--- /dev/null
+package org.argeo.slc.core.structure.tree;\r
+\r
+import java.util.List;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+import org.argeo.slc.core.SlcException;\r
+import org.argeo.slc.core.structure.StructurePath;\r
+import org.argeo.slc.core.structure.StructureRegistry;\r
+\r
+/**\r
+ * Path for tree based <code>StructureRegistry</code> implementations.\r
+ */\r
+public class TreeSPath implements StructurePath, Comparable<StructurePath> {\r
+ /** Default character to use a separator: /. */\r
+ public static Character DEFAULT_SEPARATOR = '/';\r
+\r
+ private TreeSPath parent;\r
+ private String name;\r
+ private Character separator = DEFAULT_SEPARATOR;\r
+\r
+ /** For ORM */\r
+ private Long tid;\r
+\r
+ public String getAsUniqueString() {\r
+ String parentStr = parent != null ? parent.getAsUniqueString() : "";\r
+ return parentStr + separator + name;\r
+ }\r
+\r
+ /** Sets all the required data from a string. */\r
+ public void setAsUniqueString(String str) {\r
+ TreeSPath twin = parseToCreatePath(str, getSeparator());\r
+ name = twin.name;\r
+ parent = twin.parent;\r
+ }\r
+\r
+ /** The separator actually used by this path. */\r
+ public Character getSeparator() {\r
+ return separator;\r
+ }\r
+\r
+ /** Gets the parent path. */\r
+ public TreeSPath getParent() {\r
+ return parent;\r
+ }\r
+\r
+ /** Gets the name part of the path. */\r
+ public String getName() {\r
+ return name;\r
+ }\r
+\r
+ /** Create a path without parent. */\r
+ public static TreeSPath createRootPath(String name) {\r
+ TreeSPath path = new TreeSPath();\r
+ path.parent = null;\r
+ path.name = name;\r
+ return path;\r
+ }\r
+\r
+ /** Create a child . */\r
+ public TreeSPath createChild(String name) {\r
+ if (name.indexOf(separator) > -1) {\r
+ throw new SlcException("Tree path name '" + name\r
+ + "' contains separator character " + separator);\r
+ }\r
+ TreeSPath path = new TreeSPath();\r
+ path.parent = this;\r
+ path.name = name;\r
+ return path;\r
+ }\r
+\r
+ /** Parses a string to a path. */\r
+ public static TreeSPath parseToCreatePath(String path) {\r
+ return parseToCreatePath(path, DEFAULT_SEPARATOR);\r
+ }\r
+\r
+ /** Parses a string to a path. */\r
+ public static TreeSPath parseToCreatePath(String path, Character separator) {\r
+ StringTokenizer st = new StringTokenizer(path, Character\r
+ .toString(separator));\r
+\r
+ TreeSPath currPath = null;\r
+ while (st.hasMoreTokens()) {\r
+ if (currPath == null) {// begin\r
+ currPath = createRootPath(st.nextToken());\r
+ } else {\r
+ currPath = currPath.createChild(st.nextToken());\r
+ }\r
+ }\r
+ return currPath;\r
+ }\r
+\r
+ /** Lists the children from a registry. */\r
+ public List<TreeSPath> listChildren(StructureRegistry registry) {\r
+ return listChildrenPaths(registry, this);\r
+ }\r
+\r
+ /** Lists the children from a given path from a registry. */\r
+ public static List<TreeSPath> listChildrenPaths(StructureRegistry registry,\r
+ TreeSPath path) {\r
+ List<TreeSPath> paths = new Vector<TreeSPath>();\r
+ List<StructurePath> allPaths = registry.listPaths();\r
+ for (StructurePath sPath : allPaths) {\r
+ TreeSPath pathT = (TreeSPath) sPath;\r
+ if (pathT.parent != null && pathT.parent.equals(path)) {\r
+ paths.add(pathT);\r
+ }\r
+ }\r
+ return paths;\r
+ }\r
+\r
+ /** Gets the root tree path of this path. */\r
+ public TreeSPath getRoot() {\r
+ TreeSPath root = this;\r
+ while (root.getParent() != null) {\r
+ root = root.getParent();\r
+ }\r
+ return root;\r
+ }\r
+\r
+ /** Depth of this path. */\r
+ public Integer depth() {\r
+ return depthImpl(this);\r
+ }\r
+\r
+ private static int depthImpl(TreeSPath path) {\r
+ if (path.getParent() == null) {\r
+ return 1;\r
+ } else {\r
+ return depthImpl(path.getParent()) + 1;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return getAsUniqueString();\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (obj instanceof StructurePath) {\r
+ StructurePath path = (StructurePath) obj;\r
+ return getAsUniqueString().equals(path.getAsUniqueString());\r
+ }\r
+ return false;\r
+ }\r
+\r
+ public int compareTo(StructurePath o) {\r
+ return getAsUniqueString().compareTo(o.getAsUniqueString());\r
+ }\r
+\r
+ Long getTid() {\r
+ return tid;\r
+ }\r
+\r
+ void setTid(Long tid) {\r
+ this.tid = tid;\r
+ }\r
+\r
+ /** Sets the separator character to use. */\r
+ public void setSeparator(Character separator) {\r
+ this.separator = separator;\r
+ }\r
+\r
+ /** Sets the parent (for ORM). */\r
+ protected void setParent(TreeSPath parent) {\r
+ this.parent = parent;\r
+ }\r
+\r
+ /** Sets the name (for ORM). */\r
+ protected void setName(String name) {\r
+ this.name = name;\r
+ }\r
+\r
+}\r