1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.simject;
17
18 import java.io.FileNotFoundException;
19 import java.io.InputStream;
20 import java.lang.annotation.Annotation;
21 import java.lang.reflect.Field;
22 import java.net.MalformedURLException;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 import javax.persistence.EntityManager;
29 import javax.persistence.EntityManagerFactory;
30 import javax.persistence.Persistence;
31 import javax.xml.bind.JAXBContext;
32 import javax.xml.bind.Unmarshaller;
33
34 import org.simject.exception.SimConfigException;
35 import org.simject.exception.SimResourceNotFoundException;
36 import org.simject.jaxb.Property;
37 import org.simject.jaxb.Resource;
38 import org.simject.jaxb.Resources;
39 import org.simject.remoting.client.HttpClientProxy;
40 import org.simject.util.SimConstants;
41
42
43
44
45
46
47
48
49 public class SimFactory {
50
51 private static final Logger logger = Logger.getLogger(SimFactory.class
52 .getName());
53
54
55
56
57 final private Map<Class<?>, Object> resourceMap = new HashMap<Class<?>, Object>();
58
59
60
61
62
63
64 public SimFactory(final String... fileNames) {
65
66 for (String fileName : fileNames) {
67 this.loadXmlConfig(fileName);
68 }
69 this.injectDependencies();
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83 @SuppressWarnings("unchecked")
84 public <T> T getResource(final Class<T> clazz) {
85 final Object obj = this.resourceMap.get(clazz);
86 if (obj == null) {
87 final String message = "Resource of type " + clazz.getName()
88 + " not found";
89 logger.severe(message);
90 throw new SimResourceNotFoundException(message);
91 }
92 return (T) obj;
93 }
94
95
96
97
98
99
100 private void loadXmlConfig(final String fileName) {
101 try {
102 logger.info("Loading configuration from <"
103 + SimConstants.DEFAULT_DIRECTORY + fileName + ">");
104
105 final JAXBContext jcontext = JAXBContext
106 .newInstance("org.simject.jaxb");
107 final Unmarshaller unmarshaller = jcontext.createUnmarshaller();
108
109 final InputStream istream = Thread.currentThread()
110 .getContextClassLoader().getResourceAsStream(
111 SimConstants.DEFAULT_DIRECTORY + fileName);
112
113 if (istream == null) {
114 throw new FileNotFoundException(SimConstants.DEFAULT_DIRECTORY
115 + fileName + " not found");
116 } else {
117 final Resources resources = (Resources) unmarshaller
118 .unmarshal(istream);
119 for (Resource resource : resources.getResource()) {
120 this.createResource(resource);
121 }
122 }
123 } catch (Exception e) {
124 logger.log(Level.SEVERE, e.getMessage(), e);
125 throw new SimConfigException(e.getMessage(), e);
126 }
127 }
128
129
130
131
132
133
134
135
136
137
138
139 private void createResource(final Resource resource)
140 throws ClassNotFoundException, InstantiationException,
141 IllegalAccessException, MalformedURLException {
142
143 final String className = resource.getType();
144 final Class<?> clazz = Class.forName(className);
145
146 Object obj = null;
147 if (resource.getType().equals(EntityManager.class.getName())) {
148
149 obj = this.createEntityManager(resource);
150 } else if (resource.getTarget() != null
151 && resource.getTarget().contains("http://")) {
152
153 obj = this.createHttpClientProxy(clazz, resource.getTarget());
154 } else {
155
156 obj = this.createPojo(resource, clazz);
157 }
158 this.resourceMap.put(clazz, obj);
159 }
160
161
162
163
164
165
166
167
168
169 private Object createHttpClientProxy(final Class<?> clazz,
170 final String target) throws MalformedURLException {
171 logger.info("Creating <" + clazz.getName() + "> for URL <" + target
172 + ">");
173
174 return HttpClientProxy.newInstance(Thread.currentThread()
175 .getContextClassLoader(), new Class[] { clazz }, target);
176 }
177
178
179
180
181
182
183
184
185
186
187
188 private Object createPojo(final Resource resource, final Class<?> clazz)
189 throws InstantiationException, IllegalAccessException,
190 ClassNotFoundException {
191
192 Object obj = null;
193 if (resource.getTarget() == null || resource.getTarget().equals("")) {
194 logger.info("Creating <" + resource.getType() + ">");
195 obj = createInstance(clazz);
196 } else {
197 logger.info("Creating <" + resource.getType() + "> as <"
198 + resource.getTarget() + ">");
199 final String realizedby = resource.getTarget();
200 final Class<?> realizedbyClazz = Class.forName(realizedby);
201 obj = createInstance(realizedbyClazz);
202 }
203 return obj;
204 }
205
206
207
208
209
210
211
212 private Object createEntityManager(final Resource resource) {
213
214 logger.info("Creating <" + resource.getType() + ">");
215
216 final Map<String, String> props = new HashMap<String, String>();
217 for (Property property : resource.getProperty()) {
218 props.put(property.getName(), property.getValue());
219 }
220 final EntityManagerFactory emf = Persistence
221 .createEntityManagerFactory(resource.getName(), props);
222 return emf.createEntityManager();
223 }
224
225
226
227
228
229
230
231
232
233
234 private Object createInstance(final Class<?> clazz)
235 throws InstantiationException, IllegalAccessException {
236
237 if (clazz.isInterface()) {
238 throw new InstantiationException(
239 "Can not instantiate a interface. Please check configuration");
240 }
241 return clazz.newInstance();
242 }
243
244
245
246
247 private void injectDependencies() {
248 try {
249 for (Object obj : this.resourceMap.values()) {
250 final Field[] fields = obj.getClass().getDeclaredFields();
251 for (Field field : fields) {
252 final Annotation[] annotations = field
253 .getDeclaredAnnotations();
254 for (Annotation annotation : annotations) {
255 if (annotation.annotationType().equals(
256 javax.annotation.Resource.class)) {
257 final Class<?> clazz = field.getType();
258 final Object value = this.resourceMap.get(clazz);
259 field.setAccessible(true);
260 field.set(obj, value);
261 logger.info("Injecting instance of <"
262 + value.getClass().getName()
263 + "> into field <" + field.getName()
264 + "> in class <" + obj.getClass().getName()
265 + ">");
266 }
267 }
268 }
269 }
270 } catch (Exception e) {
271 logger.log(Level.SEVERE, e.getMessage(), e);
272 throw new SimConfigException(
273 "Unable to inject dependencies. Please check the configuration",
274 e);
275 }
276 }
277 }