1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.xmlfield.core.internal;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.net.URL;
21 import java.util.Enumeration;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Properties;
25
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 import org.xmlfield.core.api.XmlFieldNodeModifierFactory;
29 import org.xmlfield.core.api.XmlFieldNodeParserFactory;
30 import org.xmlfield.core.api.XmlFieldSelectorFactory;
31 import org.xmlfield.core.impl.dom.DomNodeModifierFactory;
32 import org.xmlfield.core.impl.dom.DomNodeParserFactory;
33 import org.xmlfield.core.impl.dom.DomSelectorFactory;
34
35
36
37
38
39
40
41
42 public class XmlFieldFactoryFinder {
43
44
45
46
47 private static Properties cachedProperties = new Properties();
48
49
50
51
52 private static final String CONFIG_LOCATION = "xmlfield-factory.properties";
53
54
55
56
57 private static Map<String, Class<?>> defaultFactoriesClass;
58
59 private static boolean firstTime = true;
60
61 private static Logger logger = LoggerFactory.getLogger(XmlFieldFactoryFinder.class);
62
63 static {
64 defaultFactoriesClass = new HashMap<String, Class<?>>();
65 defaultFactoriesClass.put(XmlFieldSelectorFactory.class.getName(), DomSelectorFactory.class);
66 defaultFactoriesClass.put(XmlFieldNodeParserFactory.class.getName(), DomNodeParserFactory.class);
67 defaultFactoriesClass
68 .put(XmlFieldNodeModifierFactory.class.getName(), DomNodeModifierFactory.class);
69 }
70
71 private final ClassLoader classloader;
72
73
74
75
76
77
78
79 public XmlFieldFactoryFinder(final ClassLoader classLoader) {
80 this.classloader = classLoader;
81 }
82
83
84
85
86
87
88
89
90
91
92
93 @SuppressWarnings("unchecked")
94 public <T> T newFactory(Class<T> factoryClass) {
95 final String requestedFactoryClass = factoryClass.getName();
96 if (!defaultFactoriesClass.containsKey(requestedFactoryClass)) {
97 logger.error("This requseted factory class is not managed by this finder, factory class : {}",
98 requestedFactoryClass);
99 return null;
100 }
101 if (firstTime) {
102 init();
103 }
104 String implementationFactoryClass = cachedProperties.getProperty(requestedFactoryClass);
105 if (implementationFactoryClass == null) {
106 logger.debug("The requested factory is not overriden ({}), we return the factory class : {}",
107 requestedFactoryClass, defaultFactoriesClass.get(requestedFactoryClass));
108 return (T) createDefaultInstance(requestedFactoryClass);
109 }
110 logger.debug("The requested factory is overriden by : {}", implementationFactoryClass);
111 return (T) createInstance(implementationFactoryClass);
112 }
113
114
115
116
117
118
119
120
121
122
123 private Class<?> createClass(String className) {
124 Class<?> clazz;
125
126
127 try {
128 if (this.classloader != null) {
129 clazz = this.classloader.loadClass(className);
130 } else {
131 clazz = Class.forName(className);
132 }
133 } catch (Throwable t) {
134 logger.error("Error when creating the class named {}", className);
135 return null;
136 }
137
138 return clazz;
139 }
140
141
142
143
144
145
146
147
148
149
150 private Object createDefaultInstance(String factoryClass) {
151 Class<?> implementationFactoryClass = defaultFactoriesClass.get(factoryClass);
152 if (implementationFactoryClass == null) {
153 return null;
154 }
155 return createInstance(implementationFactoryClass);
156 }
157
158 private Object createInstance(Class<?> clazz) {
159 Object factory;
160 try {
161 factory = clazz.newInstance();
162 } catch (ClassCastException classCastException) {
163 logger.error("could not instantiate {}", clazz.getName());
164 return null;
165 } catch (IllegalAccessException illegalAccessException) {
166 logger.error("could not instantiate {}", clazz.getName());
167 return null;
168 } catch (InstantiationException instantiationException) {
169 logger.error("could not instantiate {}", clazz.getName());
170 return null;
171 }
172 return factory;
173 }
174
175 private Object createInstance(String className) {
176 Class<?> implementationFactoryClass = createClass(className);
177 if (implementationFactoryClass == null) {
178 return null;
179 }
180 return createInstance(implementationFactoryClass);
181 }
182
183
184
185
186 private void init() {
187 synchronized (cachedProperties) {
188 if (firstTime) {
189 try {
190 Enumeration<URL> configFiles;
191 configFiles = classloader.getResources(CONFIG_LOCATION);
192
193 if (configFiles == null) {
194 logger.info("No configuration file ({}) found in the classpath.", CONFIG_LOCATION);
195 return;
196 }
197 firstTime = false;
198 boolean alreadyLoaded = false;
199 while (configFiles.hasMoreElements()) {
200 final URL url = configFiles.nextElement();
201 if (!alreadyLoaded) {
202 final InputStream is = url.openStream();
203 cachedProperties.load(is);
204 is.close();
205 logger.info("XmlFieldFactory configuration loaded from the file {}", url);
206 } else {
207 logger.info(
208 "An other XmlFieldFactory configuration file is found in the classpath. This file won't be loaded {}",
209 url);
210 }
211 }
212 } catch (IOException e) {
213 logger.error("An error occur during the XmlFieldFActory initialization", e);
214 }
215 }
216 }
217 }
218 }