Merge branch 'develop' into LibrAlign
[taxeditor.git] / eu.etaxonomy.taxeditor.cdmlib / src / main / java / eu / etaxonomy / taxeditor / remoting / cache / ProxyUtils.java
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.taxeditor.remoting.cache;
10
11 import java.lang.reflect.Field;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.TreeMap;
19 import java.util.TreeSet;
20 import java.util.UUID;
21
22 import org.hibernate.collection.internal.PersistentBag;
23 import org.hibernate.collection.internal.PersistentList;
24 import org.hibernate.collection.internal.PersistentMap;
25 import org.hibernate.collection.internal.PersistentSet;
26 import org.hibernate.collection.internal.PersistentSortedMap;
27 import org.hibernate.collection.internal.PersistentSortedSet;
28 import org.hibernate.collection.spi.PersistentCollection;
29 import org.hibernate.proxy.HibernateProxy;
30 import org.hibernate.proxy.LazyInitializer;
31 import org.springframework.util.ReflectionUtils;
32
33 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
34 import eu.etaxonomy.cdm.model.common.CdmBase;
35 import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
36 import eu.etaxonomy.taxeditor.remoting.CdmRemotingException;
37
38 /**
39 * @author cmathew
40 * @date 17 Feb 2015
41 *
42 */
43 public class ProxyUtils {
44
45
46
47 public static enum CollectionType {
48 SET,
49 LIST,
50 MAP,
51 BAG;
52
53 @Override
54 public String toString() {
55 return this.name().toLowerCase();
56 }
57 }
58
59 public static Object getCollectionType(Object obj, Class<?> clazz) {
60 if(obj != null) {
61 if(obj instanceof List) {
62 //the field in PersistentBag is called "bag" although it is an ArrayList -> #
63 if(clazz.equals(PersistentBag.class)){
64 return CollectionType.BAG;
65 }
66 return CollectionType.LIST;
67 }
68 if(obj instanceof Set) {
69 return CollectionType.SET;
70 }
71 if(obj instanceof Map) {
72 return CollectionType.MAP;
73 }
74 throw new CdmRemotingException("Cannot get Collection Type for " + obj.getClass().getName());
75 }
76 return null;
77 }
78
79 public static Object getObject(PersistentCollection pc) {
80 if(pc != null) {
81 if(pc instanceof PersistentSet) {
82 return new HashSet<>((Set<?>)pc);
83 }
84 if(pc instanceof PersistentSortedSet) {
85 return new TreeSet<>((Set<?>)pc);
86 }
87 if(pc instanceof PersistentList || pc instanceof PersistentBag) {
88 return new ArrayList<>((List<?>)pc);
89 }
90 if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
91 return new HashMap<>((Map<?,?>)pc);
92 }
93 if(pc instanceof PersistentSortedMap) {
94 return new TreeMap<>((Map<?,?>)pc);
95 }
96 throw new CdmRemotingException("Cannot get Collection field for type " + pc.getClass().getName());
97 }
98 return null;
99 }
100
101 public static CollectionField getCollectionField(PersistentCollection pc) {
102 if(pc != null) {
103 if(pc instanceof PersistentSet) {
104 return new CollectionField(new HashSet<>((Set<?>)pc), CollectionType.SET);
105 }
106 if(pc instanceof PersistentSortedSet) {
107 return new CollectionField(new TreeSet<>((Set<?>)pc), CollectionType.SET);
108 }
109 if(pc instanceof PersistentList) {
110 return new CollectionField(new ArrayList<>((List<?>)pc), CollectionType.LIST);
111 }
112 if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
113 return new CollectionField(new HashMap<>((Map<?,?>)pc), CollectionType.MAP);
114 }
115 if(pc instanceof PersistentSortedMap) {
116 return new CollectionField(new TreeMap<>((Map<?,?>)pc), CollectionType.MAP);
117 }
118 throw new CdmRemotingException("Cannot get Collection field for type " + pc.getClass().getName());
119 }
120 return null;
121 }
122
123 public static class CollectionField {
124 private final Object col;
125 private final CollectionType type;
126 public CollectionField(Object col, CollectionType type) {
127 this.col = col;
128 this.type = type;
129 }
130
131 public Object getCollection() {
132 return this.col;
133 }
134
135 public CollectionType getType() {
136 return this.type;
137 }
138 }
139
140
141 public static Object deproxy(Object o) {
142 if(o != null && o instanceof HibernateProxy) {
143 LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
144 if(!hli.isUninitialized()) {
145 return hli.getImplementation();
146
147 }
148 }
149
150 if(o != null && o instanceof PersistentCollection) {
151 PersistentCollection pc = ((PersistentCollection)o);
152 if(pc.wasInitialized()) {
153 return ProxyUtils.getObject(pc);
154
155 }
156 }
157 return o;
158 }
159
160 public static boolean isProxy(Object o) {
161 if(o != null && o instanceof HibernateProxy) {
162 LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
163 if(hli.isUninitialized()) {
164 return true;
165 }
166 }
167
168 if(o != null && o instanceof PersistentCollection) {
169 PersistentCollection pc = ((PersistentCollection)o);
170 if(!pc.wasInitialized()) {
171 return true;
172 }
173 }
174
175 return false;
176 }
177
178 @SuppressWarnings("unchecked")
179 public static Object remoteLoadPersistentCollectionIfProxy(Object o, UUID ownerUuid, String fieldName) throws ClassNotFoundException {
180 if(o != null && o instanceof HibernateProxy) {
181 LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
182 if(hli.isUninitialized()) {
183 return CdmApplicationState.getCachedCommonService().find((Class<CdmBase>)Class.forName(hli.getEntityName()),
184 ((Integer)hli.getIdentifier()).intValue());
185 }
186 }
187
188 if(o != null && o instanceof PersistentCollection) {
189 PersistentCollection pc = ((PersistentCollection)o);
190 if(!pc.wasInitialized()) {
191 return CdmApplicationState.getCachedCommonService().initializeCollection(ownerUuid, fieldName);
192 }
193 }
194
195 return o;
196 }
197
198
199
200
201 public static void setRoleValueInOwner(Object owner, String role, Object value) {
202 if(role == null || role.isEmpty()) {
203 throw new CdmRemotingException("Role cannot be null or an empty string");
204 }
205
206 String fieldName = role.substring(role.lastIndexOf(".") + 1);
207
208 Field field = ReflectionUtils.findField(owner.getClass(), fieldName);
209
210 if(field == null) {
211 throw new CdmRemotingException("Field '" + fieldName
212 + "' not found when searching in class '" + owner.getClass() + "' and its supercalsses");
213 }
214
215 field.setAccessible(true);
216
217 try {
218 field.set(owner, value);
219 } catch (IllegalArgumentException e) {
220 throw new CdmRemotingException(e);
221 } catch (IllegalAccessException e) {
222 throw new CdmRemotingException(e);
223 }
224 }
225
226 }