X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Facr%2FContentUtils.java;h=272a5c5a148d3f51b3315fad79918e4837aed3c9;hb=4c7e1885b8bf3c93fa0919ace122e3f289a925ea;hp=d0ce5d1535bcf954242533f0a4d2febafdf16b55;hpb=cc1dd97ebcc32e1bd754073ad23def182f460452;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java b/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java index d0ce5d153..272a5c5a1 100644 --- a/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/acr/ContentUtils.java @@ -1,22 +1,32 @@ package org.argeo.cms.acr; import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; import java.util.function.BiConsumer; import javax.xml.namespace.QName; import org.argeo.api.acr.Content; +/** Utilities and routines around {@link Content}. */ public class ContentUtils { public static void traverse(Content content, BiConsumer doIt) { - traverse(content, doIt, 0); + traverse(content, doIt, (Integer) null); } - public static void traverse(Content content, BiConsumer doIt, int currentDepth) { + public static void traverse(Content content, BiConsumer doIt, Integer maxDepth) { + doTraverse(content, doIt, 0, maxDepth); + } + + private static void doTraverse(Content content, BiConsumer doIt, int currentDepth, + Integer maxDepth) { doIt.accept(content, currentDepth); + if (maxDepth != null && currentDepth == maxDepth) + return; int nextDepth = currentDepth + 1; for (Content child : content) { - traverse(child, doIt, nextDepth); + doTraverse(child, doIt, nextDepth, maxDepth); } } @@ -37,24 +47,60 @@ public class ContentUtils { } } - - // public static boolean isString(T t) { // return t instanceof String; // } + public static final char SLASH = '/'; + public static final String ROOT_SLASH = "" + SLASH; + /** * Split a path (with '/' separator) in an array of length 2, the first part * being the parent path (which could be either absolute or relative), the - * second one being the last segment, (guaranteed to be with '/'). + * second one being the last segment, (guaranteed to be without a '/'). */ public static String[] getParentPath(String path) { - int parentIndex = path.lastIndexOf('/'); - // TODO make it more robust - return new String[] { parentIndex != 0 ? path.substring(0, parentIndex) : "/", + if (path == null) + throw new IllegalArgumentException("Path cannot be null"); + if (path.length() == 0) + throw new IllegalArgumentException("Path cannot be empty"); + checkDoubleSlash(path); + int parentIndex = path.lastIndexOf(SLASH); + if (parentIndex == path.length() - 1) {// trailing '/' + path = path.substring(0, path.length() - 1); + parentIndex = path.lastIndexOf(SLASH); + } + + if (parentIndex == -1) // no '/' + return new String[] { "", path }; + + return new String[] { parentIndex != 0 ? path.substring(0, parentIndex) : "" + SLASH, path.substring(parentIndex + 1) }; } + public static List toPathSegments(String path) { + List res = new ArrayList<>(); + if ("".equals(path) || ROOT_SLASH.equals(path)) + return res; + collectPathSegments(path, res); + return res; + } + + private static void collectPathSegments(String path, List segments) { + String[] parent = getParentPath(path); + if ("".equals(parent[1])) // root + return; + segments.add(0, parent[1]); + if ("".equals(parent[0])) // end + return; + collectPathSegments(parent[0], segments); + } + + public static void checkDoubleSlash(String path) { + if (path.contains(SLASH + "" + SLASH)) + throw new IllegalArgumentException("Path " + path + " contains //"); + } + /** Singleton. */ private ContentUtils() {