2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org
.argeo
.slc
.core
.structure
.tree
;
19 import java
.io
.Serializable
;
20 import java
.util
.List
;
21 import java
.util
.StringTokenizer
;
22 import java
.util
.Vector
;
24 import org
.argeo
.slc
.SlcException
;
25 import org
.argeo
.slc
.structure
.StructurePath
;
26 import org
.argeo
.slc
.structure
.StructureRegistry
;
29 * Path for tree based <code>StructureRegistry</code> implementations.
31 public class TreeSPath
implements StructurePath
, Comparable
<StructurePath
>,
33 private static final long serialVersionUID
= -110121029180848183L;
35 /** Default character to use a separator: /. */
36 private static Character DEFAULT_SEPARATOR
= '/';
38 private Character separator
= DEFAULT_SEPARATOR
;
40 private String asUniqueString
;
49 public TreeSPath(String asUniqueString
) {
50 this.asUniqueString
= checkAndFormatPath(asUniqueString
);
53 public String
getAsUniqueString() {
54 return asUniqueString
;
58 * Sets all the required data from a string. <b>ATTENTION</b>: the path is
59 * not checked for performance reason. This method should be used only by
60 * ORM/OXM frameworks. Use constructor to create immutable tree structure
63 public void setAsUniqueString(String str
) {
64 this.asUniqueString
= str
;
67 /** The separator actually used by this path. */
68 public Character
getSeparator() {
72 /** Gets the parent path. */
73 public TreeSPath
getParent() {
74 int lastSep
= getAsUniqueString().lastIndexOf(separator
);
78 String parentUniqueString
= getAsUniqueString().substring(0, lastSep
);
79 return new TreeSPath(parentUniqueString
);
82 /** Gets the name part of the path. */
83 public String
getName() {
84 int lastSep
= getAsUniqueString().lastIndexOf(separator
);
85 return getAsUniqueString().substring(lastSep
+ 1);
88 /** Create a path without parent. */
89 public static TreeSPath
createRootPath(String name
) {
90 if (name
.indexOf(DEFAULT_SEPARATOR
) >= 0) {
91 throw new SlcException("Name cannot contain " + DEFAULT_SEPARATOR
);
93 return new TreeSPath('/' + name
);
96 /** Create a child . */
97 public TreeSPath
createChild(String name
) {
98 if (name
.indexOf(separator
) > -1) {
99 throw new SlcException("Tree path name '" + name
100 + "' contains separator character " + separator
);
102 return new TreeSPath(getAsUniqueString() + '/' + name
);
106 * Parses a string to a path.
108 * @deprecated use constructor instead
110 public static TreeSPath
parseToCreatePath(String path
) {
111 return parseToCreatePath(path
, DEFAULT_SEPARATOR
);
114 protected String
checkAndFormatPath(String str
) {
115 if (str
.length() < 2) {
116 throw new SlcException("Path " + str
+ " is not short");
118 if (str
.charAt(0) != separator
) {
119 throw new SlcException("Path " + str
+ " have to start with "
123 StringBuffer buf
= new StringBuffer(str
.length() + 5);
124 StringTokenizer st
= new StringTokenizer(str
, separator
.toString());
125 while (st
.hasMoreTokens()) {
126 buf
.append(separator
).append(st
.nextToken());
128 return buf
.toString();
132 * Parses a string to a path.
134 * @deprecated use constructor instead
136 public static TreeSPath
parseToCreatePath(String path
, Character separator
) {
137 return new TreeSPath(path
);
140 /** Lists the children from a registry. */
141 public List
<TreeSPath
> listChildren(StructureRegistry
<TreeSPath
> registry
) {
142 return listChildrenPaths(registry
, this);
145 /** Lists the children from a given path from a registry. */
146 public static List
<TreeSPath
> listChildrenPaths(
147 StructureRegistry
<TreeSPath
> registry
, TreeSPath path
) {
148 List
<TreeSPath
> paths
= new Vector
<TreeSPath
>();
149 List
<TreeSPath
> allPaths
= registry
.listPaths();
150 for (TreeSPath pathT
: allPaths
) {
151 if (pathT
.getParent() != null && pathT
.getParent().equals(path
)) {
158 /** Gets the root tree path of this path. */
159 public TreeSPath
getRoot() {
160 TreeSPath root
= this;
161 while (root
.getParent() != null) {
162 root
= root
.getParent();
167 /** Depth of this path. */
168 public Integer
getDepth() {
169 return depthImpl(this);
172 protected int depthImpl(TreeSPath path
) {
173 if (path
.getParent() == null) {
176 return depthImpl(path
.getParent()) + 1;
180 public List
<TreeSPath
> getHierarchyAsList() {
181 List
<TreeSPath
> lst
= new Vector
<TreeSPath
>();
182 addParentToList(lst
, this);
187 protected void addParentToList(List
<TreeSPath
> lst
, TreeSPath current
) {
188 TreeSPath parent
= current
.getParent();
189 if (parent
!= null) {
190 addParentToList(lst
, parent
);
196 public String
toString() {
197 return getAsUniqueString();
201 public boolean equals(Object obj
) {
202 if (obj
instanceof StructurePath
) {
203 StructurePath path
= (StructurePath
) obj
;
204 return getAsUniqueString().equals(path
.getAsUniqueString());
210 public int hashCode() {
211 return getAsUniqueString().hashCode();
214 public int compareTo(StructurePath o
) {
215 return getAsUniqueString().compareTo(o
.getAsUniqueString());
218 public Long
getTid() {
222 void setTid(Long tid
) {