]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/structure/tree/TreeSPath.java
Implement kill and process progress
[gpl/argeo-slc.git] / runtime / org.argeo.slc.core / src / main / java / org / argeo / slc / core / structure / tree / TreeSPath.java
1 /*
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 package org.argeo.slc.core.structure.tree;
18
19 import java.io.Serializable;
20 import java.util.List;
21 import java.util.StringTokenizer;
22 import java.util.Vector;
23
24 import org.argeo.slc.SlcException;
25 import org.argeo.slc.structure.StructurePath;
26 import org.argeo.slc.structure.StructureRegistry;
27
28 /**
29 * Path for tree based <code>StructureRegistry</code> implementations.
30 */
31 public class TreeSPath implements StructurePath, Comparable<StructurePath>,
32 Serializable {
33 private static final long serialVersionUID = -110121029180848183L;
34
35 /** Default character to use a separator: /. */
36 private static Character DEFAULT_SEPARATOR = '/';
37
38 private Character separator = DEFAULT_SEPARATOR;
39
40 private String asUniqueString;
41
42 /** For ORM */
43 private Long tid;
44
45 public TreeSPath() {
46
47 }
48
49 public TreeSPath(String asUniqueString) {
50 this.asUniqueString = checkAndFormatPath(asUniqueString);
51 }
52
53 public String getAsUniqueString() {
54 return asUniqueString;
55 }
56
57 /**
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
61 * paths.
62 */
63 public void setAsUniqueString(String str) {
64 this.asUniqueString = str;
65 }
66
67 /** The separator actually used by this path. */
68 public Character getSeparator() {
69 return separator;
70 }
71
72 /** Gets the parent path. */
73 public TreeSPath getParent() {
74 int lastSep = getAsUniqueString().lastIndexOf(separator);
75 if (lastSep < 1) {
76 return null;
77 }
78 String parentUniqueString = getAsUniqueString().substring(0, lastSep);
79 return new TreeSPath(parentUniqueString);
80 }
81
82 /** Gets the name part of the path. */
83 public String getName() {
84 int lastSep = getAsUniqueString().lastIndexOf(separator);
85 return getAsUniqueString().substring(lastSep + 1);
86 }
87
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);
92 }
93 return new TreeSPath('/' + name);
94 }
95
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);
101 }
102 return new TreeSPath(getAsUniqueString() + '/' + name);
103 }
104
105 /**
106 * Parses a string to a path.
107 *
108 * @deprecated use constructor instead
109 */
110 public static TreeSPath parseToCreatePath(String path) {
111 return parseToCreatePath(path, DEFAULT_SEPARATOR);
112 }
113
114 protected String checkAndFormatPath(String str) {
115 if (str.length() < 2) {
116 throw new SlcException("Path " + str + " is not short");
117 }
118 if (str.charAt(0) != separator) {
119 throw new SlcException("Path " + str + " have to start with "
120 + separator);
121 }
122
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());
127 }
128 return buf.toString();
129 }
130
131 /**
132 * Parses a string to a path.
133 *
134 * @deprecated use constructor instead
135 */
136 public static TreeSPath parseToCreatePath(String path, Character separator) {
137 return new TreeSPath(path);
138 }
139
140 /** Lists the children from a registry. */
141 public List<TreeSPath> listChildren(StructureRegistry<TreeSPath> registry) {
142 return listChildrenPaths(registry, this);
143 }
144
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)) {
152 paths.add(pathT);
153 }
154 }
155 return paths;
156 }
157
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();
163 }
164 return root;
165 }
166
167 /** Depth of this path. */
168 public Integer getDepth() {
169 return depthImpl(this);
170 }
171
172 protected int depthImpl(TreeSPath path) {
173 if (path.getParent() == null) {
174 return 1;
175 } else {
176 return depthImpl(path.getParent()) + 1;
177 }
178 }
179
180 public List<TreeSPath> getHierarchyAsList() {
181 List<TreeSPath> lst = new Vector<TreeSPath>();
182 addParentToList(lst, this);
183 lst.add(this);
184 return lst;
185 }
186
187 protected void addParentToList(List<TreeSPath> lst, TreeSPath current) {
188 TreeSPath parent = current.getParent();
189 if (parent != null) {
190 addParentToList(lst, parent);
191 lst.add(parent);
192 }
193 }
194
195 @Override
196 public String toString() {
197 return getAsUniqueString();
198 }
199
200 @Override
201 public boolean equals(Object obj) {
202 if (obj instanceof StructurePath) {
203 StructurePath path = (StructurePath) obj;
204 return getAsUniqueString().equals(path.getAsUniqueString());
205 }
206 return false;
207 }
208
209 @Override
210 public int hashCode() {
211 return getAsUniqueString().hashCode();
212 }
213
214 public int compareTo(StructurePath o) {
215 return getAsUniqueString().compareTo(o.getAsUniqueString());
216 }
217
218 public Long getTid() {
219 return tid;
220 }
221
222 void setTid(Long tid) {
223 this.tid = tid;
224 }
225 }