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