Project

General

Profile

Download (9.09 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.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

    
21
import org.hibernate.collection.internal.PersistentBag;
22
import org.hibernate.collection.internal.PersistentList;
23
import org.hibernate.collection.internal.PersistentMap;
24
import org.hibernate.collection.internal.PersistentSet;
25
import org.hibernate.collection.internal.PersistentSortedMap;
26
import org.hibernate.collection.internal.PersistentSortedSet;
27
import org.hibernate.collection.spi.PersistentCollection;
28
import org.hibernate.proxy.HibernateProxy;
29
import org.hibernate.proxy.LazyInitializer;
30
import org.springframework.util.ReflectionUtils;
31

    
32
import eu.etaxonomy.cdm.model.common.CdmBase;
33
import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
34

    
35
/**
36
 * @author cmathew
37
 * @since 17 Feb 2015
38
 */
39
public class ProxyUtils {
40

    
41
    public static enum CollectionType {
42
        SET("set"),
43
        LIST("list"),
44
        MAP("map"),
45
        BAG("bag");
46

    
47
        public String encodingSaveName;
48

    
49
        private CollectionType(String name){
50
            this.encodingSaveName = name;
51
        }
52

    
53
        @Override
54
        public String toString() {
55
            return this.encodingSaveName;
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 ProxyUtilsException("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 ProxyUtilsException("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 ProxyUtilsException("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
     * De-proxies the passed object <code>o</code> if it is an initialized proxy object,
142
     * otherwise <code>o</code> is returned.
143
     */
144
    public static <T extends Object> T deproxyIfInitialized(T o) {
145
        if(o != null && o instanceof HibernateProxy) {
146
            LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
147
            if(!hli.isUninitialized()) {
148
                @SuppressWarnings("unchecked")
149
                T result = (T)hli.getImplementation();
150
                return result;
151
            }
152
        }
153

    
154
        if(o != null && o instanceof PersistentCollection) {
155
            PersistentCollection pc = ((PersistentCollection)o);
156
            if(pc.wasInitialized()) {
157
                @SuppressWarnings("unchecked")
158
                T result = (T)ProxyUtils.getObject(pc);
159
                return result;
160
            }
161
        }
162
        return o;
163
    }
164

    
165

    
166
    /**
167
     * De-proxies the passed object <code>o</code> if it is an initialized proxy object,
168
     * otherwise <code>null</code> is returned.
169
     */
170
    public static <T extends CdmBase> T deproxyOrNull(T o) {
171
        if(o != null && o instanceof HibernateProxy) {
172
            LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
173
            if(!hli.isUninitialized()) {
174
                return (T)hli.getImplementation();
175
            } else {
176
                return null;
177
            }
178
        }
179
        return o;
180
    }
181

    
182
//    /**
183
//     * Currently not yet used.
184
//     * de-proxies the passed object <code>o</code> if it is an initialized proxy object,
185
//     * otherwise <code>null</code> is returned.
186
//     */
187
//    public static Object deproxyOrNull(Object o) {
188
//        if(o != null && o instanceof PersistentCollection) {
189
//            PersistentCollection pc = ((PersistentCollection)o);
190
//            if(pc.wasInitialized()) {
191
//                return ProxyUtils.getObject(pc);
192
//            } else {
193
//                return null;
194
//            }
195
//        }
196
//        return o;
197
//    }
198

    
199
    public static boolean isUninitializedProxy(Object o) {
200
        if(o != null && o instanceof HibernateProxy) {
201
            LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
202
            if(hli.isUninitialized()) {
203
                return true;
204
            }
205
        }
206

    
207
        if(o != null && o instanceof PersistentCollection) {
208
            PersistentCollection pc = ((PersistentCollection)o);
209
            if(!pc.wasInitialized()) {
210
                return true;
211
            }
212
        }
213

    
214
        return false;
215
    }
216

    
217
    /*
218
     * ########################################### makes no sense without remoting ###########################################
219
    @SuppressWarnings("unchecked")
220
	public static Object remoteLoadPersistentCollectionIfProxy(Object o, UUID ownerUuid, String fieldName) throws ClassNotFoundException {
221
        if(o != null && o instanceof HibernateProxy) {
222
            LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
223
            if(hli.isUninitialized()) {
224
                return CdmApplicationState.getCachedCommonService().find((Class<CdmBase>)Class.forName(hli.getEntityName()),
225
                        ((Integer)hli.getIdentifier()).intValue());
226
            }
227
        }
228

    
229
        if(o != null && o instanceof PersistentCollection) {
230
            PersistentCollection pc = ((PersistentCollection)o);
231
            if(!pc.wasInitialized()) {
232
                return CdmApplicationState.getCachedCommonService().initializeCollection(ownerUuid, fieldName);
233
            }
234
        }
235

    
236
        return o;
237
    }
238
    ########################################### ########################################### */
239

    
240
    public static void setRoleValueInOwner(Object owner, String role, Object value) {
241
        if(role == null || role.isEmpty()) {
242
            throw new ProxyUtilsException("Role cannot be null or an empty string");
243
        }
244

    
245
        String fieldName = role.substring(role.lastIndexOf(".") + 1);
246

    
247
        Field field = ReflectionUtils.findField(owner.getClass(), fieldName);
248

    
249
        if(field == null) {
250
            throw new ProxyUtilsException("Field '" + fieldName
251
                    + "' not found when searching in class '" + owner.getClass() + "' and its supercalsses");
252
        }
253

    
254
        field.setAccessible(true);
255

    
256
        try {
257
            field.set(owner, value);
258
        } catch (IllegalArgumentException e) {
259
            throw new ProxyUtilsException(e);
260
        } catch (IllegalAccessException e) {
261
            throw new ProxyUtilsException(e);
262
        }
263
    }
264

    
265
}
(11-11/12)