Adding new and modifying existing classes / resources for remoting.
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / cdm / api / lazyloading / CdmLazyLoader.java
1 package eu.etaxonomy.cdm.api.lazyloading;
2
3 import java.beans.Transient;
4 import java.lang.reflect.Field;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12 import java.util.TreeMap;
13 import java.util.TreeSet;
14
15 import org.aspectj.lang.ProceedingJoinPoint;
16 import org.aspectj.lang.annotation.Around;
17 import org.aspectj.lang.annotation.Aspect;
18 import org.aspectj.lang.annotation.Pointcut;
19 import org.hibernate.collection.internal.PersistentList;
20 import org.hibernate.collection.internal.PersistentMap;
21 import org.hibernate.collection.internal.PersistentSet;
22 import org.hibernate.collection.internal.PersistentSortedMap;
23 import org.hibernate.collection.internal.PersistentSortedSet;
24 import org.hibernate.collection.spi.PersistentCollection;
25 import org.hibernate.proxy.LazyInitializer;
26 import org.springframework.beans.factory.annotation.Autowire;
27 import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.beans.factory.annotation.Configurable;
29 import org.springframework.stereotype.Component;
30
31 import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
32 import eu.etaxonomy.cdm.api.service.ICommonService;
33 import eu.etaxonomy.cdm.model.common.CdmBase;
34 import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
35
36
37 @Aspect
38 @Component
39 @Configurable(autowire = Autowire.BY_TYPE)
40 public class CdmLazyLoader {
41
42
43 private Set classes = new HashSet();
44
45 public static boolean enableWeaving = true;
46 private static Set<String> classesToIgnore = new HashSet<String>();
47
48
49 @Autowired
50 private ICommonService commonService;
51
52 public CdmLazyLoader() {
53 //classesToIgnore.add("eu.etaxonomy.cdm.model.common.TermVocabulary");
54 //classesToIgnore.add("eu.etaxonomy.cdm.model.common.OrderedTermVocabulary");
55
56 }
57
58 /**
59 * Point cut for the 'initialize' method of the AbstractLazyInitializer.
60 *
61 */
62 @Pointcut("execution(* org.hibernate.proxy.AbstractLazyInitializer.initialize())")
63 public void possibleEntityLazyInitializationException() {
64 }
65
66
67 /**
68 * 'Around' advice for the initialization of CDM Entity Objects
69 *
70 */
71 @Around(value = "possibleEntityLazyInitializationException()")
72 public Object preloadEntityOnDemand(ProceedingJoinPoint pjp) throws Throwable {
73 if(enableWeaving) {
74 LazyInitializer ll = (LazyInitializer)pjp.getTarget();
75 if(ll.isUninitialized()) {
76 int classid = ((Integer)ll.getIdentifier()).intValue();
77 System.out.print("--> AspectJ Compile-Time Weaving " + ll.getEntityName() + " with id " + classid);
78 Class clazz = (Class<? extends CdmBase>) Class.forName(ll.getEntityName());
79 CdmBase cdmBase = CdmBase.deproxy(commonService.find(clazz,classid),clazz);
80 ll.setImplementation(cdmBase);
81 System.out.println("....Done");
82 }
83 }
84 return pjp.proceed();
85 }
86
87
88 /**
89 * Point cut for the 'initialize' method of the AbstractPersistentCollection.
90 *
91 */
92 @Pointcut("execution(protected final void org.hibernate.collection.internal.AbstractPersistentCollection.initialize(..))")
93 public void possibleCollectionLazyInitializationException() {
94 }
95
96 /**
97 * 'Around' advice for the initialization of Collection objects
98 *
99 */
100 @Around(value = "possibleCollectionLazyInitializationException()")
101 @Transient
102 public Object preloadCollectionOnDemand(ProceedingJoinPoint pjp) throws Throwable {
103 if(enableWeaving) {
104 PersistentCollection ps = (PersistentCollection) pjp.getTarget();
105 if (ps.getOwner() != null && !classesToIgnore.contains(ps.getOwner().getClass().getName()) && !ps.wasInitialized() && !classes.contains(ps.getKey())) {
106 System.out.print("--> AspectJCompile-Time Weaving " + ps.getRole());
107 classes.add(ps.getKey());
108 try {
109 String role = ps.getRole();
110 String fieldName = role.substring(role.lastIndexOf(".") + 1);
111 System.out.print(", field : " + fieldName);
112 Object owner = ps.getOwner();
113
114 PersistentCollection col = commonService.initializeCollection(ps);
115 ps.afterInitialize();
116
117 Class<?> clazz = ps.getClass();
118 if (clazz != null) {
119 CollectionField cf = getCollectionField(col);
120 Field field = clazz.getDeclaredField(cf.getFieldName());
121 field.setAccessible(true);
122 field.set(ps, cf.getCollection());
123 }
124 } catch (Exception ex) {
125 ex.printStackTrace();
126 System.out.println("Error in ReattachSessionAspect : " + ex.getMessage());
127 } finally {
128 classes.remove(ps.getKey());
129 System.out.println("....Done");
130 }
131 }
132 }
133 return pjp.proceed();
134
135 }
136
137 private CollectionField getCollectionField(PersistentCollection pc) {
138 if(pc != null) {
139 if(pc instanceof PersistentSet) {
140 return new CollectionField(new HashSet((Set)pc), "set");
141 }
142 if(pc instanceof PersistentSortedSet) {
143 return new CollectionField(new TreeSet((Set)pc), "set");
144 }
145 if(pc instanceof PersistentList) {
146 return new CollectionField(new ArrayList((List)pc), "list");
147 }
148 if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
149 return new CollectionField(new HashMap((Map)pc), "map");
150 }
151 if(pc instanceof PersistentSortedMap) {
152 return new CollectionField(new TreeMap((Map)pc), "map");
153 }
154 }
155 return null;
156 }
157
158 private String getCollectionFieldName(PersistentCollection pc) {
159 if(pc != null) {
160 if(pc instanceof PersistentSet || pc instanceof PersistentSortedSet) {
161 return "set";
162 }
163
164 if(pc instanceof PersistentList) {
165 return "list";
166 }
167 if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
168 return "map";
169 }
170 }
171 return null;
172 }
173
174 private class CollectionField {
175 private Object col;
176 private String fieldName;
177 public CollectionField(Object col, String fieldName) {
178 this.col = col;
179 this.fieldName = fieldName;
180 }
181
182 public Object getCollection() {
183 return this.col;
184 }
185
186 public String getFieldName() {
187 return this.fieldName;
188 }
189 }
190
191 }