Project

General

Profile

Download (5.97 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2015 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package eu.etaxonomy.cdm.api.lazyloading;
10

    
11
import java.util.ArrayList;
12
import java.util.HashMap;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Set;
17
import java.util.TreeMap;
18
import java.util.TreeSet;
19

    
20
import org.aspectj.lang.ProceedingJoinPoint;
21
import org.aspectj.lang.annotation.Around;
22
import org.aspectj.lang.annotation.Aspect;
23
import org.aspectj.lang.annotation.Pointcut;
24
import org.hibernate.collection.internal.PersistentList;
25
import org.hibernate.collection.internal.PersistentMap;
26
import org.hibernate.collection.internal.PersistentSet;
27
import org.hibernate.collection.internal.PersistentSortedMap;
28
import org.hibernate.collection.internal.PersistentSortedSet;
29
import org.hibernate.collection.spi.PersistentCollection;
30
import org.hibernate.proxy.LazyInitializer;
31
import org.springframework.beans.factory.annotation.Autowire;
32
import org.springframework.beans.factory.annotation.Autowired;
33
import org.springframework.beans.factory.annotation.Configurable;
34
import org.springframework.stereotype.Component;
35

    
36
import eu.etaxonomy.cdm.api.service.ICommonService;
37
import eu.etaxonomy.cdm.model.common.CdmBase;
38
import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
39

    
40

    
41
@Aspect
42
@Component
43
@Configurable(autowire = Autowire.BY_TYPE)
44
public class CdmLazyLoader {
45

    
46
	private final Set classes = new HashSet<>();
47

    
48
	public static boolean enableWeaving = true;
49
	private static Set<String> classesToIgnore = new HashSet<>();
50

    
51

    
52
	@Autowired
53
	private ICommonService commonService;
54

    
55
	public CdmLazyLoader() {
56
		//classesToIgnore.add("eu.etaxonomy.cdm.model.term.TermVocabulary");
57
		//classesToIgnore.add("eu.etaxonomy.cdm.model.term.OrderedTermVocabulary");
58
	}
59

    
60
	/**
61
	 *  Point cut for the 'initialize' method of the AbstractLazyInitializer.
62
	 */
63
	@Pointcut("execution(* org.hibernate.proxy.AbstractLazyInitializer.initialize())")
64
	public void possibleEntityLazyInitializationException() {
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.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
	@Pointcut("execution(protected final void org.hibernate.collection.internal.AbstractPersistentCollection.initialize(..))")
92
	public void possibleCollectionLazyInitializationException() {
93
	}
94

    
95
	/**
96
	 *  'Around' advice for the initialization of Collection objects
97
	 */
98
	@Around(value = "possibleCollectionLazyInitializationException()")
99
	public Object preloadCollectionOnDemand(ProceedingJoinPoint pjp) throws Throwable {
100
		if(enableWeaving) {
101
			PersistentCollection ps = (PersistentCollection) pjp.getTarget();
102
			if (ps.getOwner() != null && !classesToIgnore.contains(ps.getOwner().getClass().getName()) && !ps.wasInitialized() &&  !classes.contains(ps.getKey())) {
103
				System.out.print("--> AspectJCompile-Time Weaving " + ps.getRole());
104
				classes.add(ps.getKey());
105
				try {
106
					String role = ps.getRole();
107
					String fieldName = role.substring(role.lastIndexOf(".") + 1);
108
					System.out.print(", field : " + fieldName);
109
					Object owner = ps.getOwner();
110

    
111
					Object col = commonService.initializeCollection(((CdmBase)owner).getUuid(), fieldName);
112
					ps.afterInitialize();
113

    
114
//					Class<?> clazz = ps.getClass();
115
//					if (clazz != null) {
116
//						CollectionField cf = getCollectionField(col);
117
//						Field field = clazz.getDeclaredField(cf.getFieldName());
118
//						field.setAccessible(true);
119
//						field.set(ps, cf.getCollection());
120
//					}
121

    
122
				} catch (Exception ex) {
123
					ex.printStackTrace();
124
					System.out.println("Error in ReattachSessionAspect : " + ex.getMessage());
125
				} finally {
126
					classes.remove(ps.getKey());
127
					System.out.println("....Done");
128
					throw new Exception("This code is invalid");
129
				}
130
			}
131
		}
132
		return pjp.proceed();
133
	}
134

    
135
	private CollectionField getCollectionField(PersistentCollection pc) {
136
		if(pc != null) {
137
			if(pc instanceof PersistentSet) {
138
				return new CollectionField(new HashSet<>((Set)pc), "set");
139
			}
140
			if(pc instanceof PersistentSortedSet) {
141
				return new CollectionField(new TreeSet<>((Set)pc), "set");
142
			}
143
			if(pc instanceof PersistentList) {
144
				return new CollectionField(new ArrayList<>((List)pc), "list");
145
			}
146
			if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
147
				return new CollectionField(new HashMap<>((Map)pc), "map");
148
			}
149
			if(pc instanceof PersistentSortedMap) {
150
				return new CollectionField(new TreeMap<>((Map)pc), "map");
151
			}
152
		}
153
		return null;
154
	}
155

    
156
	private String getCollectionFieldName(PersistentCollection pc) {
157
		if(pc != null) {
158
			if(pc instanceof PersistentSet || pc instanceof PersistentSortedSet) {
159
				return "set";
160
			}
161
			if(pc instanceof PersistentList) {
162
				return "list";
163
			}
164
			if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
165
				return "map";
166
			}
167
		}
168
		return null;
169
	}
170

    
171
	private class CollectionField {
172
		private final Object col;
173
		private final String fieldName;
174
		public CollectionField(Object col, String fieldName) {
175
			this.col = col;
176
			this.fieldName = fieldName;
177
		}
178

    
179
		public Object getCollection() {
180
			return this.col;
181
		}
182

    
183
		public String getFieldName() {
184
			return this.fieldName;
185
		}
186
	}
187
}
    (1-1/1)