fix mumissing multilanaguage text (and similar) bug
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / initializer / BeanInitNode.java
1 /**
2 *
3 */
4 package eu.etaxonomy.cdm.persistence.dao.initializer;
5
6 import java.io.Serializable;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import org.apache.commons.beanutils.BeanUtils;
17 import org.apache.commons.beanutils.BeanUtilsBean2;
18 import org.apache.commons.lang.StringUtils;
19 import org.hibernate.collection.internal.AbstractPersistentCollection;
20
21 import eu.etaxonomy.cdm.common.CdmUtils;
22
23 /**
24 * @author a.mueller
25 * @date 2013-10-25
26 */
27 public class BeanInitNode implements Comparable<BeanInitNode>{
28
29 // ************************ ATTRIBUTES *******************************/
30
31 private BeanInitNode parent;
32
33 private Map<String, BeanInitNode> children = new HashMap<String, BeanInitNode>();
34
35 private String path;
36
37 private boolean isToManyInitialized = false;
38
39 private boolean isToOneInitialized = false;
40
41 private BeanInitNode wildcardChildCache;
42
43
44 private Map<Class<?>, Set<Object>> beans = new HashMap<Class<?>, Set<Object>>();
45
46 private Map<Class<?>, Set<Serializable>> lazyBeans = new HashMap<Class<?>, Set<Serializable>>();
47
48 private Map<Class<?>, Map<String, Set<Serializable>>> lazyCollections = new HashMap<Class<?>, Map<String,Set<Serializable>>>();
49
50 //java.util.Set is not possible here to avoid initializing of collection during .add()
51 private List<AbstractPersistentCollection> uninitializedCollections = new ArrayList<AbstractPersistentCollection>();
52
53 // *************************** STATIC METHODS *****************************************/
54
55 public static BeanInitNode createInitTree(List<String> propertyPaths) {
56
57 //sort paths //TODO needed?
58 Collections.sort(propertyPaths);
59
60 BeanInitNode root = new BeanInitNode(null, "");
61
62 for (String fullPath : propertyPaths){
63 String[] parts = fullPath.split("\\.");
64 BeanInitNode lastNode = root;
65 for (String part : parts){
66 BeanInitNode child = lastNode.children.get(part);
67 if (child == null){
68 child = new BeanInitNode(lastNode, part);
69 }
70 lastNode = child;
71 }
72 }
73
74 return root;
75 }
76
77 private static boolean isWildcard(String pathPart) {
78 return pathPart.equals(AbstractBeanInitializer.LOAD_2ONE_WILDCARD) ||
79 pathPart.equals(AbstractBeanInitializer.LOAD_2ONE_2MANY_WILDCARD);
80 }
81
82
83 //***************************** CONSTRUCTOR RELATED ****************************************/
84
85 public BeanInitNode(BeanInitNode parent, String part) {
86 this.path = CdmUtils.Nz(part);
87 this.parent = parent;
88 this.isToManyInitialized = this.path.equals(AbstractBeanInitializer.LOAD_2ONE_2MANY_WILDCARD);
89 this.isToOneInitialized = this.path.equals(AbstractBeanInitializer.LOAD_2ONE_WILDCARD) || this.isToManyInitialized;
90 if (parent != null){
91 parent.addChild(part, this);
92 }
93 }
94
95 private void addChild(String part, BeanInitNode child) {
96 children.put(part, child);
97 if (child.isWildcard()){
98 //set wildcard child if not exists or if child is stronger then existing wildcard child
99 if (this.wildcardChildCache == null || (! this.wildcardChildCache.isToManyInitialized) && child.isToManyInitialized ){
100 this.wildcardChildCache = child;
101 }
102 }
103 }
104
105 // ************************** ***********************************************************/
106
107 public BeanInitNode getChild(String param){
108 return children.get(param);
109 }
110
111
112
113 public List<BeanInitNode> getChildrenList() {
114 List<BeanInitNode> result = new ArrayList<BeanInitNode>(children.values());
115 Collections.sort(result);
116 return result;
117 }
118
119 public BeanInitNode getSibling(String param) {
120 if (getPath().equals(param) || parent == null){
121 return null;
122 }else{
123 return parent.getChild(param);
124 }
125 }
126
127 public String getPath() {
128 return path;
129 }
130
131 public boolean isRoot() {
132 return StringUtils.isBlank(path);
133 }
134
135 public boolean hasChildren() {
136 return children.size() > 0;
137 }
138
139 public BeanInitNode getWildcardChild(){
140 return this.wildcardChildCache;
141 }
142 public boolean isWildcard() {
143 return this.isToManyInitialized || this.isToOneInitialized;
144 }
145 public boolean hasWildcardChild() {
146 return this.wildcardChildCache != null;
147 }
148 public boolean hasToManyWildcardChild() {
149 return this.wildcardChildCache != null;
150 }
151
152 public boolean hasWildcardToManySibling() {
153 BeanInitNode sibl = getWildcardSibling();
154 return (sibl != null && sibl.isToManyInitialized);
155 }
156
157 private BeanInitNode getWildcardSibling() {
158 if (!isWildcard() && parent == null){
159 return parent.getWildcardChild();
160 }else{
161 return null;
162 }
163 }
164
165
166 public boolean isToManyWildcard() {
167 return path.equals(AbstractBeanInitializer.LOAD_2ONE_2MANY_WILDCARD);
168 }
169
170
171 // ******************* LAZY COLLECTION *****************************************/
172
173 public void putLazyCollection(AbstractPersistentCollection collection) {
174 String parameter = collection.getRole();
175 parameter = parameter.substring(parameter.lastIndexOf(".")+1);
176 putLazyCollection(collection.getOwner().getClass(), parameter, collection.getKey());
177 this.uninitializedCollections.add(collection);
178 }
179
180
181 private void putLazyCollection(Class<?> ownerClazz, String parameter, Serializable id) {
182 if (ownerClazz != null && parameter != null && id != null){
183 Map<String, Set<Serializable>> lazyParams = lazyCollections.get(ownerClazz);
184 if (lazyParams == null){
185 lazyParams = new HashMap<String, Set<Serializable>>();
186 lazyCollections.put(ownerClazz, lazyParams);
187 }
188 Set<Serializable> layzIds = lazyParams.get(parameter);
189 if (layzIds == null){
190 layzIds = new HashSet<Serializable>();
191 lazyParams.put(parameter, layzIds);
192 }
193 layzIds.add(id);
194 }else{
195 throw new IllegalArgumentException("Class, parameter and id should not be null");
196 }
197 }
198 public Map<Class<?>, Map<String, Set<Serializable>>> getLazyCollections(){
199 return this.lazyCollections;
200 }
201 public List<AbstractPersistentCollection> getUninitializedCollections(){
202 return this.uninitializedCollections;
203 }
204 public void resetLazyCollections(){
205 this.lazyCollections.clear();
206 this.uninitializedCollections.clear();
207 }
208
209
210 // ******************* LAZY BEAN *****************************************/
211
212 public void putLazyBean(Class<?> clazz, Serializable id) {
213 if (clazz != null && id != null){
214 Set<Serializable> classedLazies= lazyBeans.get(clazz);
215 if (classedLazies == null){
216 classedLazies = new HashSet<Serializable>();
217 lazyBeans.put(clazz, classedLazies);
218 }
219 classedLazies.add(id);
220 }else{
221 throw new IllegalArgumentException("Class and id should not be null");
222 }
223 }
224 public Map<Class<?>, Set<Serializable>> getLazyBeans(){
225 return this.lazyBeans;
226 }
227 public void resetLazyBeans(){
228 this.lazyBeans.clear();
229 }
230
231 // ********************* BEANS ******************************/
232
233 private Map<Class<?>, Set<Object>> getClassedBeans(){
234 return this.beans;
235 }
236
237
238 public Map<Class<?>, Set<Object>> getBeans() {
239 return this.beans;
240 }
241
242 public Map<Class<?>, Set<Object>> getParentBeans() {
243 if (parent == null){
244 return new HashMap<Class<?>, Set<Object>>();
245 }else{
246 return parent.getClassedBeans();
247 }
248 }
249
250 public void addBean(Object bean) {
251 if (! isWildcard()){
252 if (bean != null){
253 Class<?> key = bean.getClass();
254 Set<Object> classedBeans = beans.get(key);
255 if (classedBeans == null){
256 classedBeans = new HashSet<Object>();
257 beans.put(key, classedBeans);
258 }
259 classedBeans.add(bean);
260 }
261 }
262 }
263 public void addBeans(Collection<?> beans) {
264 for (Object bean : beans){
265 addBean(bean);
266 }
267 }
268
269 public void resetBeans(){
270 beans.clear();
271 }
272
273
274 // ************************* OVERRIDES **********************************/
275
276 @Override
277 public int compareTo(BeanInitNode o) {
278 String toMany = AbstractBeanInitializer.LOAD_2ONE_2MANY_WILDCARD;
279 String toOne = AbstractBeanInitializer.LOAD_2ONE_WILDCARD;
280 if (this.path.equals(toMany)){
281 return -1;
282 }else if (o.path.equals(toMany)){
283 return 1;
284 }else if (this.path.equals(toOne)){
285 return -1;
286 }else if (o.path.equals(toOne)){
287 return 1;
288 }else{
289 return path.compareTo(o.path);
290 }
291 }
292
293
294 @Override
295 public String toString() {
296
297 if(parent == null){
298 return "/"; //for root node
299 }else{
300 String result = parent.toString() + ((parent.parent == null) ? "" : ".") + path;
301 return result;
302 }
303 }
304
305 public String toStringNoWildcard(){
306 return toString().replace(".$", "").replace(".*", "");
307 }
308
309 public String toStringTree() {
310
311 String result = (path.equals("") ? "/" : path) + "\n";
312
313 for (BeanInitNode child : getChildrenList()){
314 result += toString() + (result.endsWith("/\n") ? "" : ".") + child.toStringTree();
315 }
316
317 return result;
318 }
319
320 public boolean hasWildcardToOneSibling() {
321 BeanInitNode sibl = getWildcardSibling();
322 return (sibl != null && sibl.isToOneInitialized);
323 }
324
325
326 }