]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/dao/AbstractMemoryDaoSupport.java
Update versions used
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.core / src / main / java / org / argeo / server / dao / AbstractMemoryDaoSupport.java
1 package org.argeo.server.dao;
2
3 import java.beans.PropertyEditor;
4 import java.io.InputStream;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.TreeMap;
11
12 import org.apache.commons.io.IOUtils;
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.argeo.ArgeoException;
16 import org.springframework.beans.BeanWrapper;
17 import org.springframework.beans.BeanWrapperImpl;
18 import org.springframework.beans.BeansException;
19 import org.springframework.beans.factory.InitializingBean;
20 import org.springframework.beans.factory.generic.GenericBeanFactoryAccessor;
21 import org.springframework.context.ApplicationContext;
22 import org.springframework.context.ApplicationContextAware;
23 import org.springframework.core.io.Resource;
24
25 public abstract class AbstractMemoryDaoSupport implements LightDaoSupport,
26 ApplicationContextAware, InitializingBean {
27 private final static Log log = LogFactory
28 .getLog(AbstractMemoryDaoSupport.class);
29
30 private ClassLoader classLoader = getClass().getClassLoader();
31 private ApplicationContext applicationContext;
32 private List<Class<?>> additionalClasses = new ArrayList<Class<?>>();
33
34 private Map<Class<?>, Map<Object, Object>> model = new HashMap<Class<?>, Map<Object, Object>>();
35
36 private Map<String, Object> externalRefs = new HashMap<String, Object>();
37
38 private List<String> scannedPackages = new ArrayList<String>();
39
40 private List<Resource> resources = new ArrayList<Resource>();
41
42 private Map<Class<?>, PropertyEditor> customEditors = new HashMap<Class<?>, PropertyEditor>();;
43
44 protected abstract void load(InputStream in, List<Reference> references);
45
46 protected abstract Object findInternalRef(Reference reference);
47
48 public void afterPropertiesSet() throws Exception {
49 init();
50 }
51
52 public void init() {
53 for (PropertyEditor propertyEditor : customEditors.values())
54 if (propertyEditor instanceof LightDaoAware) {
55 ((LightDaoAware) propertyEditor).setLightDaoSupport(this);
56 }
57
58 // Load data
59 List<Reference> references = new ArrayList<Reference>();
60
61 for (Resource res : resources) {
62 InputStream in = null;
63 try {
64 in = res.getInputStream();
65 load(in, references);
66 } catch (Exception e) {
67 throw new ArgeoException("Cannot load stream", e);
68 } finally {
69 IOUtils.closeQuietly(in);
70 }
71 }
72
73 // Inject references
74 for (Reference ref : references) {
75 injectReference(ref);
76 }
77 if (log.isDebugEnabled())
78 log.debug(references.size() + " references linked");
79 }
80
81 public List<Class<?>> getSupportedClasses() {
82 List<Class<?>> res = new ArrayList<Class<?>>();
83 res.addAll(additionalClasses);
84 res.addAll(model.keySet());
85 return res;
86 }
87
88 protected void injectReference(Reference reference) {
89 BeanWrapper bw = new BeanWrapperImpl(reference.object);
90 Object targetObject;
91 if (reference.getExternalRef() != null) {
92 String ref = reference.getExternalRef();
93 if (externalRefs.containsKey(ref))
94 targetObject = externalRefs.get(ref);
95 else if (applicationContext != null)
96 targetObject = applicationContext.getBean(ref);
97 else {
98 targetObject = null;
99 log.warn("Ref " + ref + " not found");
100 }
101 } else {
102 targetObject = findInternalRef(reference);
103 }
104 bw.setPropertyValue(reference.property, targetObject);
105
106 }
107
108 protected BeanWrapper newBeanWrapper(Class<?> targetClass) {
109 BeanWrapperImpl bw = new BeanWrapperImpl(targetClass);
110 for (Class<?> clss : customEditors.keySet())
111 bw.registerCustomEditor(clss, customEditors.get(clss));
112 return bw;
113 }
114
115 @SuppressWarnings("unchecked")
116 public <T> T getByKey(Class<T> clss, Object key) {
117 if (key == null)
118 throw new ArgeoException("Key is null for " + clss);
119 return (T) model.get(findClass(clss)).get(key);
120 }
121
122 /**
123 * Slow.
124 *
125 * @return the first found
126 */
127 public <T> T getByField(Class<T> clss, String field, Object value) {
128 List<T> all = list(clss, null);
129 T res = null;
130 for (T obj : all) {
131 if (new BeanWrapperImpl(obj).getPropertyValue(field).equals(value)) {
132 res = obj;
133 break;
134 }
135 }
136 return res;
137 }
138
139 @SuppressWarnings("unchecked")
140 public <T> List<T> list(Class<T> clss, Object filter) {
141 List<T> res = new ArrayList<T>();
142
143 Class classToUse = findClass(clss);
144 if (classToUse != null)
145 res.addAll((Collection<T>) model.get(classToUse).values());
146
147 if (applicationContext != null)
148 res.addAll(new GenericBeanFactoryAccessor(applicationContext)
149 .getBeansOfType(clss).values());
150
151 return res;
152 }
153
154 @SuppressWarnings("unchecked")
155 protected Class findClass(Class parent) {
156 if (model.containsKey(parent))
157 return parent;
158
159 for (Class clss : model.keySet()) {
160 if (parent.isAssignableFrom(clss))
161 return clss;// return the first found
162 }
163 if (log.isDebugEnabled())
164 log.warn("No class found for " + parent.getName());
165 return null;
166 }
167
168 public void setApplicationContext(ApplicationContext applicationContext)
169 throws BeansException {
170 this.applicationContext = applicationContext;
171 }
172
173 /**
174 * When it should be stored under a different class (e.g. super class or
175 * interface)
176 */
177 public void saveOrUpdate(Object key, Object value, Class<?> clss) {
178 if (!model.containsKey(clss))
179 model.put(clss, new TreeMap<Object, Object>());
180 model.get(clss).put(key, value);
181 }
182
183 protected ClassLoader getClassLoader() {
184 return classLoader;
185 }
186
187 public void setExternalRefs(Map<String, Object> externalRefs) {
188 this.externalRefs = externalRefs;
189 }
190
191 public Map<String, Object> getExternalRefs() {
192 return externalRefs;
193 }
194
195 public void setScannedPackages(List<String> scannedPackages) {
196 this.scannedPackages = scannedPackages;
197 }
198
199 public List<String> getScannedPackages() {
200 return scannedPackages;
201 }
202
203 public void setResources(List<Resource> workbooks) {
204 this.resources = workbooks;
205 }
206
207 public List<Resource> getResources() {
208 return resources;
209 }
210
211 public void setClassLoader(ClassLoader classLoader) {
212 this.classLoader = classLoader;
213 }
214
215 public List<Class<?>> getAdditionalClasses() {
216 return additionalClasses;
217 }
218
219 public void setAdditionalClasses(List<Class<?>> additionalClasses) {
220 this.additionalClasses = additionalClasses;
221 }
222
223 public void setCustomEditors(Map<Class<?>, PropertyEditor> propertyEditors) {
224 this.customEditors = propertyEditors;
225 }
226
227 protected static class Reference {
228 private Object object;
229 private String property;
230 private String externalRef;
231
232 public Reference(Object object, String property, String externalRef) {
233 this.object = object;
234 this.property = property;
235 this.externalRef = externalRef;
236 }
237
238 public Object getObject() {
239 return object;
240 }
241
242 public String getProperty() {
243 return property;
244 }
245
246 public String getExternalRef() {
247 return externalRef;
248 }
249
250 }
251 }