1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tools.gsf.config;
17
18 import COM.FutureTense.Interfaces.ICS;
19
20 import javax.servlet.ServletContext;
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 import java.lang.reflect.Constructor;
26 import java.lang.reflect.InvocationTargetException;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Set;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public class DefaultFactoryProducer implements FactoryProducer {
69
70 private static final Logger LOG = LoggerFactory.getLogger(DefaultFactoryProducer.class);
71
72
73
74
75
76 protected static final String CONFIG_FILE = "META-INF/gsf-factory";
77
78 private final Map<Class, Constructor<Factory>> factoryConstructors;
79
80
81
82
83
84
85
86 public DefaultFactoryProducer() {
87
88 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
89
90
91 Map<Class, Class> conf = lookupConfiguration(classLoader);
92
93
94 if (!conf.containsKey(ICS.class)) {
95 conf.put(ICS.class, IcsBackedFactory.class);
96 }
97 if (!conf.containsKey(ServletContext.class)) {
98 conf.put(ServletContext.class, ServletContextBackedFactory.class);
99 }
100
101
102 factoryConstructors = getConstructorMap(conf);
103
104 if (LOG.isDebugEnabled()) {
105 LOG.debug("DefaultFactoryProducer constructor is done... factoryConstructors = " + factoryConstructors);
106 }
107
108 }
109
110 @Override
111 public Factory getFactory(Object scope) {
112 if (scope instanceof ICS) {
113 return getFactory((ICS) scope);
114 } else if (scope instanceof ServletContext) {
115 return getFactory((ServletContext) scope);
116 } else if (scope == null) {
117 throw new IllegalArgumentException("Null scope not allowed");
118 } else if (factoryConstructors.containsKey(scope.getClass())) {
119 return createFactory(scope);
120 } else {
121 throw new IllegalArgumentException("Unsupported scope: " + scope.getClass().getName());
122 }
123 }
124
125
126
127
128
129
130
131
132
133 protected Factory createFactory(Object customScope) {
134 Constructor<Factory> con = factoryConstructors.get(customScope.getClass());
135 try {
136 return con.newInstance(customScope, null );
137 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
138 throw new IllegalStateException("Could not instantiate factory: " + e, e);
139 }
140 }
141
142
143
144
145 protected static final String ICS_CONTEXT_BACKED_FACTORY = "gsf-ics-backed-factory";
146
147
148
149
150
151
152
153
154 protected Factory getFactory(ICS ics) {
155 Object o = ics.GetObj(ICS_CONTEXT_BACKED_FACTORY);
156 if (o == null) {
157 o = createFactory(ics);
158 ics.SetObj(ICS_CONTEXT_BACKED_FACTORY, o);
159 }
160 return (Factory) o;
161 }
162
163
164
165
166
167
168
169
170
171
172
173 protected Factory createFactory(ICS ics) {
174 ServletContext servletContext = ics.getIServlet().getServlet().getServletContext();
175 Factory delegate = getFactory(servletContext);
176
177 Constructor<Factory> con = factoryConstructors.get(ICS.class);
178 try {
179 return con.newInstance(ics, delegate);
180 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
181 throw new IllegalStateException("Could not instantiate factory: " + e, e);
182 }
183 }
184
185
186
187
188 protected static final String SERVLET_CONTEXT_BACKED_FACTORY = "gsf-servlet-context-backed-factory";
189
190
191
192
193
194
195
196
197 protected Factory getFactory(ServletContext servletContext) {
198 Object o = servletContext.getAttribute(SERVLET_CONTEXT_BACKED_FACTORY);
199 if (o == null) {
200 o = createFactory(servletContext);
201 servletContext.setAttribute(SERVLET_CONTEXT_BACKED_FACTORY, o);
202 }
203 return (Factory) o;
204 }
205
206
207
208
209
210
211
212
213
214 protected Factory createFactory(ServletContext servletContext) {
215 Constructor<Factory> con = factoryConstructors.get(ServletContext.class);
216 try {
217 return con.newInstance(servletContext, null);
218 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
219 throw new IllegalStateException("Could not instantiate factory: " + e, e);
220 }
221 }
222
223
224
225
226
227
228
229
230
231
232
233 protected static Map<Class, Class> lookupConfiguration(ClassLoader classLoader) {
234 Map<Class, Class> config = new HashMap<>();
235 Set<String> configLines = ReflectionUtils.readConfigurationResource(classLoader, CONFIG_FILE);
236 for (String line : configLines) {
237 String[] lineInfo = line.split(":");
238 if (lineInfo.length != 2) {
239 throw new IllegalStateException("Invalid configuration file format in " + CONFIG_FILE + ": " + line);
240 }
241 String scopeClassName = lineInfo[0];
242 String factoryClassName = lineInfo[1];
243 try {
244 Class scopeClass = classLoader.loadClass(scopeClassName);
245 if (config.containsKey(scopeClass)) {
246 throw new IllegalStateException("More than one matching configuration setting found for " +
247 scopeClass.getName() + " in " + CONFIG_FILE);
248 }
249 Class factoryClass = classLoader.loadClass(factoryClassName);
250 config.put(scopeClass, factoryClass);
251 } catch (ClassNotFoundException e) {
252 throw new IllegalStateException("Could not find class listed in configuration file: " +
253 CONFIG_FILE + ": " + e, e);
254 }
255 }
256 return config;
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271 protected static Map<Class, Constructor<Factory>> getConstructorMap(Map<Class, Class> config) {
272 Map<Class, Constructor<Factory>> constructorMap = new HashMap<>(config.size());
273 for (Class scopeClass : config.keySet()) {
274 Class configuredFactoryClass = config.get(scopeClass);
275 if (Factory.class.isAssignableFrom(configuredFactoryClass)) {
276 @SuppressWarnings("unchecked")
277 Class<Factory> factoryClass = (Class<Factory>) configuredFactoryClass;
278 try {
279 Constructor<Factory> constructor = factoryClass.getConstructor(scopeClass, Factory.class);
280 constructorMap.put(scopeClass, constructor);
281 } catch (NoSuchMethodException e) {
282 throw new IllegalStateException("Could not locate constructor with argument " + scopeClass.getName() + " for class " + factoryClass.getName());
283 }
284 } else {
285 throw new IllegalStateException("Invalid configuration - class " + configuredFactoryClass.getName() + " does not implement " + Factory.class);
286 }
287 }
288 return constructorMap;
289 }
290 }