1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
package org.apache.myfaces.config; |
20 | |
|
21 | |
import java.io.BufferedReader; |
22 | |
import java.io.File; |
23 | |
import java.io.IOException; |
24 | |
import java.io.InputStream; |
25 | |
import java.io.InputStreamReader; |
26 | |
import java.lang.reflect.Constructor; |
27 | |
import java.lang.reflect.InvocationTargetException; |
28 | |
import java.lang.reflect.Method; |
29 | |
import java.net.JarURLConnection; |
30 | |
import java.net.URL; |
31 | |
import java.net.URLConnection; |
32 | |
import java.util.ArrayList; |
33 | |
import java.util.Collections; |
34 | |
import java.util.HashMap; |
35 | |
import java.util.HashSet; |
36 | |
import java.util.Iterator; |
37 | |
import java.util.List; |
38 | |
import java.util.Locale; |
39 | |
import java.util.Map; |
40 | |
import java.util.Set; |
41 | |
import java.util.StringTokenizer; |
42 | |
import java.util.TreeMap; |
43 | |
import java.util.regex.Matcher; |
44 | |
import java.util.regex.Pattern; |
45 | |
|
46 | |
import javax.el.ELResolver; |
47 | |
import javax.faces.FacesException; |
48 | |
import javax.faces.FactoryFinder; |
49 | |
import javax.faces.application.Application; |
50 | |
import javax.faces.application.ApplicationFactory; |
51 | |
import javax.faces.application.NavigationHandler; |
52 | |
import javax.faces.application.StateManager; |
53 | |
import javax.faces.application.ViewHandler; |
54 | |
import javax.faces.context.ExternalContext; |
55 | |
import javax.faces.el.PropertyResolver; |
56 | |
import javax.faces.el.VariableResolver; |
57 | |
import javax.faces.event.ActionListener; |
58 | |
import javax.faces.event.PhaseListener; |
59 | |
import javax.faces.lifecycle.Lifecycle; |
60 | |
import javax.faces.lifecycle.LifecycleFactory; |
61 | |
import javax.faces.render.RenderKit; |
62 | |
import javax.faces.render.RenderKitFactory; |
63 | |
import javax.faces.webapp.FacesServlet; |
64 | |
|
65 | |
import org.apache.commons.logging.Log; |
66 | |
import org.apache.commons.logging.LogFactory; |
67 | |
import org.apache.myfaces.application.ApplicationFactoryImpl; |
68 | |
import org.apache.myfaces.application.ApplicationImpl; |
69 | |
import org.apache.myfaces.config.element.ManagedBean; |
70 | |
import org.apache.myfaces.config.element.NavigationRule; |
71 | |
import org.apache.myfaces.config.element.Renderer; |
72 | |
import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl; |
73 | |
import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl; |
74 | |
import org.apache.myfaces.config.impl.digester.elements.ResourceBundle; |
75 | |
import org.apache.myfaces.context.FacesContextFactoryImpl; |
76 | |
import org.apache.myfaces.el.DefaultPropertyResolver; |
77 | |
import org.apache.myfaces.el.VariableResolverImpl; |
78 | |
import org.apache.myfaces.lifecycle.LifecycleFactoryImpl; |
79 | |
import org.apache.myfaces.renderkit.RenderKitFactoryImpl; |
80 | |
import org.apache.myfaces.renderkit.html.HtmlRenderKitImpl; |
81 | |
import org.apache.myfaces.shared_impl.config.MyfacesConfig; |
82 | |
import org.apache.myfaces.shared_impl.util.ClassUtils; |
83 | |
import org.apache.myfaces.shared_impl.util.LocaleUtils; |
84 | |
import org.apache.myfaces.shared_impl.util.StateUtils; |
85 | |
import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory; |
86 | |
import org.apache.myfaces.shared_impl.util.serial.SerialFactory; |
87 | |
import org.xml.sax.SAXException; |
88 | |
|
89 | |
|
90 | |
|
91 | |
|
92 | |
|
93 | |
|
94 | |
|
95 | |
|
96 | |
@SuppressWarnings("deprecation") |
97 | |
public class FacesConfigurator |
98 | |
{ |
99 | 0 | private static final Log log = LogFactory.getLog(FacesConfigurator.class); |
100 | |
|
101 | |
private static final String STANDARD_FACES_CONFIG_RESOURCE = "META-INF/standard-faces-config.xml"; |
102 | |
private static final String FACES_CONFIG_RESOURCE = "META-INF/faces-config.xml"; |
103 | |
|
104 | |
private static final String META_INF_SERVICES_RESOURCE_PREFIX = "META-INF/services/"; |
105 | |
|
106 | 0 | private static final String DEFAULT_RENDER_KIT_CLASS = HtmlRenderKitImpl.class.getName(); |
107 | 0 | private static final String DEFAULT_APPLICATION_FACTORY = ApplicationFactoryImpl.class.getName(); |
108 | 0 | private static final String DEFAULT_FACES_CONTEXT_FACTORY = FacesContextFactoryImpl.class.getName(); |
109 | 0 | private static final String DEFAULT_LIFECYCLE_FACTORY = LifecycleFactoryImpl.class.getName(); |
110 | 0 | private static final String DEFAULT_RENDER_KIT_FACTORY = RenderKitFactoryImpl.class.getName(); |
111 | |
private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml"; |
112 | |
|
113 | 0 | private static final Set<String> FACTORY_NAMES = new HashSet<String>(); |
114 | |
{ |
115 | 0 | FACTORY_NAMES.add(FactoryFinder.APPLICATION_FACTORY); |
116 | 0 | FACTORY_NAMES.add(FactoryFinder.FACES_CONTEXT_FACTORY); |
117 | 0 | FACTORY_NAMES.add(FactoryFinder.LIFECYCLE_FACTORY); |
118 | 0 | FACTORY_NAMES.add(FactoryFinder.RENDER_KIT_FACTORY); |
119 | |
} |
120 | |
|
121 | |
private final ExternalContext _externalContext; |
122 | |
private FacesConfigUnmarshaller _unmarshaller; |
123 | |
private FacesConfigDispenser _dispenser; |
124 | |
|
125 | |
private RuntimeConfig _runtimeConfig; |
126 | |
private static final String JAR_EXTENSION = ".jar"; |
127 | |
private static final String META_INF_MANIFEST_SUFFIX = "!/META-INF/MANIFEST.MF"; |
128 | |
private static final String JAR_PREFIX = "jar:"; |
129 | |
|
130 | |
private static long lastUpdate; |
131 | |
|
132 | |
public static final String MYFACES_API_PACKAGE_NAME = "myfaces-api"; |
133 | |
public static final String MYFACES_IMPL_PACKAGE_NAME = "myfaces-impl"; |
134 | |
public static final String MYFACES_TOMAHAWK_PACKAGE_NAME = "tomahawk"; |
135 | |
public static final String MYFACES_TOMAHAWK12_PACKAGE_NAME = "tomahawk12"; |
136 | |
public static final String MYFACES_ORCHESTRA_PACKAGE_NAME = "myfaces-orchestra-core"; |
137 | |
public static final String MYFACES_ORCHESTRA12_PACKAGE_NAME = "myfaces-orchestra-core12"; |
138 | |
public static final String MYFACES_TRINIDAD_API_PACKAGE_NAME = "trinidad-api"; |
139 | |
public static final String MYFACES_TRINIDAD_IMPL_PACKAGE_NAME = "trinidad-impl"; |
140 | |
public static final String MYFACES_TOBAGO_PACKAGE_NAME = "tobago"; |
141 | |
public static final String MYFACES_TOMAHAWK_SANDBOX_PACKAGE_NAME = "tomahawk-sandbox"; |
142 | |
public static final String MYFACES_TOMAHAWK_SANDBOX12_PACKAGE_NAME = "tomahawk-sandbox12"; |
143 | |
public static final String MYFACES_TOMAHAWK_SANDBOX15_PACKAGE_NAME = "tomahawk-sandbox15"; |
144 | |
public static final String COMMONS_EL_PACKAGE_NAME = "commons-el"; |
145 | |
public static final String JSP_API_PACKAGE_NAME = "jsp-api"; |
146 | |
|
147 | 0 | private static final String[] ARTIFACTS_IDS = |
148 | |
{ |
149 | |
MYFACES_API_PACKAGE_NAME, MYFACES_IMPL_PACKAGE_NAME, |
150 | |
MYFACES_TOMAHAWK_PACKAGE_NAME, MYFACES_TOMAHAWK12_PACKAGE_NAME, |
151 | |
MYFACES_TOMAHAWK_SANDBOX_PACKAGE_NAME, MYFACES_TOMAHAWK_SANDBOX12_PACKAGE_NAME, |
152 | |
MYFACES_TOMAHAWK_SANDBOX15_PACKAGE_NAME, |
153 | |
MYFACES_ORCHESTRA_PACKAGE_NAME, MYFACES_ORCHESTRA12_PACKAGE_NAME, |
154 | |
MYFACES_TRINIDAD_API_PACKAGE_NAME, MYFACES_TRINIDAD_IMPL_PACKAGE_NAME, |
155 | |
MYFACES_TOBAGO_PACKAGE_NAME, |
156 | |
COMMONS_EL_PACKAGE_NAME, JSP_API_PACKAGE_NAME |
157 | |
}; |
158 | |
|
159 | |
|
160 | |
|
161 | |
|
162 | |
|
163 | |
|
164 | |
|
165 | |
|
166 | |
|
167 | |
|
168 | |
|
169 | |
|
170 | |
|
171 | |
|
172 | |
|
173 | |
public static final String REGEX_LIBRARY = "((jar)?(besjar)?(wsjar)?(zip)?)?:(file:.*/(.+)-" + |
174 | |
"(\\d+)(\\.(\\d+)(\\.(\\d+)(\\.(\\d+))?)?)?(-SNAPSHOT)?" + |
175 | |
"\\.jar)!/META-INF/MANIFEST.MF"; |
176 | 0 | private static final Pattern REGEX_LIBRARY_PATTERN = Pattern.compile(REGEX_LIBRARY); |
177 | |
private static final int REGEX_LIBRARY_FILE_PATH = 6; |
178 | |
private static final int REGEX_LIBRARY_ARTIFACT_ID = 7; |
179 | |
private static final int REGEX_LIBRARY_MAJOR_VERSION = 8; |
180 | |
private static final int REGEX_LIBRARY_MINOR_VERSION = 10; |
181 | |
private static final int REGEX_LIBRARY_MAINTENANCE_VERSION = 12; |
182 | |
private static final int REGEX_LIBRARY_EXTRA_VERSION = 14; |
183 | |
private static final int REGEX_LIBRARY_SNAPSHOT_MARKER = 15; |
184 | |
|
185 | |
public FacesConfigurator(ExternalContext externalContext) |
186 | 0 | { |
187 | 0 | if (externalContext == null) |
188 | |
{ |
189 | 0 | throw new IllegalArgumentException("external context must not be null"); |
190 | |
} |
191 | 0 | _externalContext = externalContext; |
192 | |
|
193 | 0 | } |
194 | |
|
195 | |
|
196 | |
|
197 | |
|
198 | |
|
199 | |
public void setUnmarshaller(FacesConfigUnmarshaller unmarshaller) |
200 | |
{ |
201 | 0 | _unmarshaller = unmarshaller; |
202 | 0 | } |
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | |
protected FacesConfigUnmarshaller getUnmarshaller() |
208 | |
{ |
209 | 0 | if (_unmarshaller == null) |
210 | |
{ |
211 | 0 | _unmarshaller = new DigesterFacesConfigUnmarshallerImpl(_externalContext); |
212 | |
} |
213 | 0 | return _unmarshaller; |
214 | |
} |
215 | |
|
216 | |
|
217 | |
|
218 | |
|
219 | |
|
220 | |
public void setDispenser(FacesConfigDispenser dispenser) |
221 | |
{ |
222 | 0 | _dispenser = dispenser; |
223 | 0 | } |
224 | |
|
225 | |
|
226 | |
|
227 | |
|
228 | |
protected FacesConfigDispenser getDispenser() |
229 | |
{ |
230 | 0 | if (_dispenser == null) |
231 | |
{ |
232 | 0 | _dispenser = new DigesterFacesConfigDispenserImpl(); |
233 | |
} |
234 | 0 | return _dispenser; |
235 | |
} |
236 | |
|
237 | |
private long getResourceLastModified(String resource) |
238 | |
{ |
239 | |
try |
240 | |
{ |
241 | 0 | URL url = _externalContext.getResource(resource); |
242 | 0 | if (url != null) |
243 | |
{ |
244 | 0 | return getResourceLastModified(url); |
245 | |
} |
246 | |
} |
247 | 0 | catch (IOException e) |
248 | |
{ |
249 | 0 | log.error("Could not read resource " + resource, e); |
250 | 0 | } |
251 | 0 | return 0; |
252 | |
} |
253 | |
|
254 | |
|
255 | |
private long getResourceLastModified(URL url) throws IOException |
256 | |
{ |
257 | 0 | if ("file".equals(url.getProtocol())) |
258 | |
{ |
259 | 0 | String externalForm = url.toExternalForm(); |
260 | |
|
261 | 0 | File file = new File(externalForm.substring(5)); |
262 | |
|
263 | 0 | return file.lastModified(); |
264 | |
} |
265 | |
else |
266 | |
{ |
267 | 0 | return getResourceLastModified(url.openConnection()); |
268 | |
} |
269 | |
} |
270 | |
|
271 | |
|
272 | |
private long getResourceLastModified(URLConnection connection) throws IOException |
273 | |
{ |
274 | |
long modified; |
275 | 0 | if (connection instanceof JarURLConnection) |
276 | |
{ |
277 | |
|
278 | |
|
279 | |
|
280 | |
|
281 | |
|
282 | |
|
283 | |
|
284 | |
|
285 | |
|
286 | |
|
287 | 0 | URL jarFileUrl = ((JarURLConnection) connection).getJarFileURL(); |
288 | 0 | URLConnection jarFileConnection = jarFileUrl.openConnection(); |
289 | |
|
290 | |
try |
291 | |
{ |
292 | 0 | modified = jarFileConnection.getLastModified(); |
293 | |
} |
294 | |
finally |
295 | |
{ |
296 | 0 | try |
297 | |
{ |
298 | 0 | jarFileConnection.getInputStream().close(); |
299 | |
} |
300 | 0 | catch (Exception exception) |
301 | |
{ |
302 | |
|
303 | 0 | } |
304 | 0 | } |
305 | 0 | } |
306 | |
else |
307 | |
{ |
308 | 0 | modified = connection.getLastModified(); |
309 | |
} |
310 | |
|
311 | 0 | return modified; |
312 | |
} |
313 | |
|
314 | |
private long getLastModifiedTime() |
315 | |
{ |
316 | 0 | long lastModified = 0; |
317 | |
long resModified; |
318 | |
|
319 | 0 | resModified = getResourceLastModified(DEFAULT_FACES_CONFIG); |
320 | 0 | if (resModified > lastModified) |
321 | 0 | lastModified = resModified; |
322 | |
|
323 | |
|
324 | 0 | List<String> configFilesList = getConfigFilesList(); |
325 | |
|
326 | 0 | for (String systemId : configFilesList) |
327 | |
{ |
328 | 0 | resModified = getResourceLastModified(systemId); |
329 | 0 | if (resModified > lastModified) |
330 | |
{ |
331 | 0 | lastModified = resModified; |
332 | |
} |
333 | |
|
334 | |
} |
335 | |
|
336 | 0 | return lastModified; |
337 | |
} |
338 | |
|
339 | |
public void update() { |
340 | 0 | long refreshPeriod = (MyfacesConfig.getCurrentInstance(_externalContext).getConfigRefreshPeriod()) * 1000; |
341 | |
|
342 | 0 | if (refreshPeriod > 0) { |
343 | 0 | long ttl = lastUpdate + refreshPeriod; |
344 | 0 | if ((System.currentTimeMillis() > ttl) && (getLastModifiedTime() > ttl)) { |
345 | |
try { |
346 | 0 | purgeConfiguration(); |
347 | |
} |
348 | 0 | catch (NoSuchMethodException e) { |
349 | 0 | log.error("Configuration objects do not support clean-up. Update aborted"); |
350 | |
|
351 | |
|
352 | |
|
353 | |
|
354 | 0 | lastUpdate = System.currentTimeMillis(); |
355 | |
|
356 | 0 | return; |
357 | |
} |
358 | 0 | catch (IllegalAccessException e) { |
359 | 0 | log.fatal("Error during configuration clean-up" + e.getMessage()); |
360 | |
} |
361 | 0 | catch (InvocationTargetException e) { |
362 | 0 | log.fatal("Error during configuration clean-up" + e.getMessage()); |
363 | 0 | } |
364 | 0 | configure(); |
365 | |
} |
366 | |
} |
367 | 0 | } |
368 | |
|
369 | |
private void purgeConfiguration() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException |
370 | |
{ |
371 | 0 | final Class<?>[] NO_PARAMETER_TYPES = new Class[]{}; |
372 | 0 | final Object[] NO_PARAMETERS = new Object[]{}; |
373 | |
|
374 | |
Method appFactoryPurgeMethod; |
375 | |
Method renderKitPurgeMethod; |
376 | |
Method lifecyclePurgeMethod; |
377 | |
|
378 | |
|
379 | |
|
380 | 0 | ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); |
381 | 0 | appFactoryPurgeMethod = applicationFactory.getClass().getMethod("purgeApplication", NO_PARAMETER_TYPES); |
382 | |
|
383 | 0 | RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); |
384 | 0 | renderKitPurgeMethod = renderKitFactory.getClass().getMethod("purgeRenderKit", NO_PARAMETER_TYPES); |
385 | |
|
386 | 0 | LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); |
387 | 0 | lifecyclePurgeMethod = lifecycleFactory.getClass().getMethod("purgeLifecycle", NO_PARAMETER_TYPES); |
388 | |
|
389 | |
|
390 | |
|
391 | 0 | appFactoryPurgeMethod.invoke(applicationFactory, NO_PARAMETERS); |
392 | 0 | renderKitPurgeMethod.invoke(renderKitFactory, NO_PARAMETERS); |
393 | 0 | RuntimeConfig.getCurrentInstance(_externalContext).purge(); |
394 | 0 | lifecyclePurgeMethod.invoke(lifecycleFactory, NO_PARAMETERS); |
395 | |
|
396 | |
|
397 | 0 | } |
398 | |
|
399 | |
|
400 | |
public void configure() throws FacesException |
401 | |
{ |
402 | |
try |
403 | |
{ |
404 | 0 | feedStandardConfig(); |
405 | 0 | feedMetaInfServicesFactories(); |
406 | 0 | feedClassloaderConfigurations(); |
407 | 0 | feedContextSpecifiedConfig(); |
408 | 0 | feedWebAppConfig(); |
409 | |
|
410 | 0 | if (log.isInfoEnabled()) |
411 | |
{ |
412 | 0 | logMetaInf(); |
413 | |
} |
414 | |
} |
415 | 0 | catch (IOException e) |
416 | |
{ |
417 | 0 | throw new FacesException(e); |
418 | |
} |
419 | 0 | catch (SAXException e) |
420 | |
{ |
421 | 0 | throw new FacesException(e); |
422 | 0 | } |
423 | |
|
424 | 0 | configureFactories(); |
425 | 0 | configureApplication(); |
426 | 0 | configureRenderKits(); |
427 | 0 | configureRuntimeConfig(); |
428 | 0 | configureLifecycle(); |
429 | 0 | handleSerialFactory(); |
430 | |
|
431 | |
|
432 | 0 | lastUpdate = System.currentTimeMillis(); |
433 | 0 | } |
434 | |
|
435 | |
private void feedStandardConfig() throws IOException, SAXException |
436 | |
{ |
437 | 0 | InputStream stream = ClassUtils.getResourceAsStream(STANDARD_FACES_CONFIG_RESOURCE); |
438 | 0 | if (stream == null) |
439 | 0 | throw new FacesException("Standard faces config " + STANDARD_FACES_CONFIG_RESOURCE + " not found"); |
440 | 0 | if (log.isInfoEnabled()) |
441 | 0 | log.info("Reading standard config " + STANDARD_FACES_CONFIG_RESOURCE); |
442 | 0 | getDispenser().feed(getUnmarshaller().getFacesConfig(stream, STANDARD_FACES_CONFIG_RESOURCE)); |
443 | 0 | stream.close(); |
444 | 0 | } |
445 | |
|
446 | |
|
447 | |
|
448 | |
|
449 | |
@SuppressWarnings("unchecked") |
450 | |
protected void logMetaInf() |
451 | |
{ |
452 | |
try |
453 | |
{ |
454 | 0 | Map<String, List<JarInfo>> libs = new HashMap<String, List<JarInfo>>(30); |
455 | |
|
456 | 0 | Iterator<URL> it = ClassUtils.getResources("META-INF/MANIFEST.MF", this); |
457 | 0 | while (it.hasNext()) |
458 | |
{ |
459 | 0 | URL url = it.next(); |
460 | 0 | Matcher matcher = REGEX_LIBRARY_PATTERN.matcher(url.toString()); |
461 | 0 | if (matcher.matches()) |
462 | |
{ |
463 | |
|
464 | 0 | String artifactId = matcher.group(REGEX_LIBRARY_ARTIFACT_ID); |
465 | 0 | List<JarInfo> versions = libs.get(artifactId); |
466 | 0 | if (versions == null) |
467 | |
{ |
468 | 0 | versions = new ArrayList<JarInfo>(2); |
469 | 0 | libs.put(artifactId, versions); |
470 | |
} |
471 | |
|
472 | 0 | String path = matcher.group(REGEX_LIBRARY_FILE_PATH); |
473 | |
|
474 | 0 | Version version = new Version(matcher.group(REGEX_LIBRARY_MAJOR_VERSION), |
475 | |
matcher.group(REGEX_LIBRARY_MINOR_VERSION), |
476 | |
matcher.group(REGEX_LIBRARY_MAINTENANCE_VERSION), |
477 | |
matcher.group(REGEX_LIBRARY_EXTRA_VERSION), |
478 | |
matcher.group(REGEX_LIBRARY_SNAPSHOT_MARKER)); |
479 | |
|
480 | 0 | JarInfo newInfo = new JarInfo(path, version); |
481 | 0 | if (!versions.contains(newInfo)) |
482 | |
{ |
483 | 0 | versions.add(newInfo); |
484 | |
} |
485 | |
} |
486 | 0 | } |
487 | |
|
488 | 0 | if (log.isInfoEnabled()) |
489 | |
{ |
490 | 0 | if (log.isWarnEnabled()) |
491 | |
{ |
492 | 0 | for (String artifactId : ARTIFACTS_IDS) |
493 | |
{ |
494 | 0 | List<JarInfo> versions = libs.get(artifactId); |
495 | 0 | if (versions != null && versions.size() > 1) |
496 | |
{ |
497 | 0 | StringBuilder builder = new StringBuilder(1024); |
498 | 0 | builder.append("You are using the library: "); |
499 | 0 | builder.append(artifactId); |
500 | 0 | builder.append(" in different versions; first (and probably used) version is: "); |
501 | 0 | builder.append(versions.get(0).getVersion()); |
502 | 0 | builder.append(" loaded from: "); |
503 | 0 | builder.append(versions.get(0).getUrl()); |
504 | 0 | builder.append(", but also found the following versions: "); |
505 | |
|
506 | 0 | boolean needComma = false; |
507 | 0 | for (int i = 1; i < versions.size(); i++) |
508 | |
{ |
509 | 0 | JarInfo info = versions.get(i); |
510 | 0 | if (needComma) |
511 | |
{ |
512 | 0 | builder.append(", "); |
513 | |
} |
514 | |
|
515 | 0 | builder.append(info.getVersion()); |
516 | 0 | builder.append(" loaded from: "); |
517 | 0 | builder.append(info.getUrl()); |
518 | |
|
519 | 0 | needComma = true; |
520 | |
} |
521 | |
|
522 | 0 | log.warn(builder.toString()); |
523 | |
} |
524 | |
} |
525 | |
} |
526 | |
|
527 | 0 | for (String artifactId : ARTIFACTS_IDS) |
528 | |
{ |
529 | 0 | startLib(artifactId, libs); |
530 | |
} |
531 | |
} |
532 | |
} |
533 | 0 | catch (Throwable e) |
534 | |
{ |
535 | 0 | throw new FacesException(e); |
536 | 0 | } |
537 | 0 | } |
538 | |
|
539 | |
|
540 | |
|
541 | |
|
542 | |
protected void feedMetaInfServicesFactories() |
543 | |
{ |
544 | |
try |
545 | |
{ |
546 | 0 | for (String factoryName : FACTORY_NAMES) |
547 | |
{ |
548 | 0 | Iterator it = ClassUtils.getResources(META_INF_SERVICES_RESOURCE_PREFIX + factoryName, this); |
549 | 0 | while (it.hasNext()) |
550 | |
{ |
551 | 0 | URL url = (URL) it.next(); |
552 | 0 | InputStream stream = openStreamWithoutCache(url); |
553 | 0 | InputStreamReader isr = new InputStreamReader(stream); |
554 | 0 | BufferedReader br = new BufferedReader(isr); |
555 | |
String className; |
556 | |
try |
557 | |
{ |
558 | 0 | className = br.readLine(); |
559 | |
} |
560 | 0 | catch (IOException e) |
561 | |
{ |
562 | 0 | throw new FacesException("Unable to read class name from file " + url.toExternalForm(), e); |
563 | |
} finally { |
564 | 0 | if (br != null) |
565 | |
{ |
566 | 0 | br.close(); |
567 | |
} |
568 | 0 | if (isr != null) { |
569 | 0 | isr.close(); |
570 | |
} |
571 | 0 | if (stream != null) { |
572 | 0 | stream.close(); |
573 | |
} |
574 | |
} |
575 | |
|
576 | |
|
577 | 0 | if (log.isInfoEnabled()) |
578 | |
{ |
579 | 0 | log.info("Found " + factoryName + " factory implementation: " + className); |
580 | |
} |
581 | |
|
582 | 0 | if (factoryName.equals(FactoryFinder.APPLICATION_FACTORY)) |
583 | |
{ |
584 | 0 | getDispenser().feedApplicationFactory(className); |
585 | |
} |
586 | 0 | else if (factoryName.equals(FactoryFinder.FACES_CONTEXT_FACTORY)) |
587 | |
{ |
588 | 0 | getDispenser().feedFacesContextFactory(className); |
589 | |
} |
590 | 0 | else if (factoryName.equals(FactoryFinder.LIFECYCLE_FACTORY)) |
591 | |
{ |
592 | 0 | getDispenser().feedLifecycleFactory(className); |
593 | |
} |
594 | 0 | else if (factoryName.equals(FactoryFinder.RENDER_KIT_FACTORY)) |
595 | |
{ |
596 | 0 | getDispenser().feedRenderKitFactory(className); |
597 | |
} |
598 | |
else |
599 | |
{ |
600 | 0 | throw new IllegalStateException("Unexpected factory name " + factoryName); |
601 | |
} |
602 | 0 | } |
603 | 0 | } |
604 | |
} |
605 | 0 | catch (Throwable e) |
606 | |
{ |
607 | 0 | throw new FacesException(e); |
608 | 0 | } |
609 | 0 | } |
610 | |
|
611 | |
private InputStream openStreamWithoutCache(URL url) throws IOException |
612 | |
{ |
613 | 0 | URLConnection connection = url.openConnection(); |
614 | 0 | connection.setUseCaches(false); |
615 | 0 | return connection.getInputStream(); |
616 | |
} |
617 | |
|
618 | |
|
619 | |
|
620 | |
|
621 | |
private void feedClassloaderConfigurations() |
622 | |
{ |
623 | |
try |
624 | |
{ |
625 | 0 | Map<String,URL> facesConfigs = new TreeMap<String,URL>(); |
626 | 0 | Iterator it = ClassUtils.getResources(FACES_CONFIG_RESOURCE, this); |
627 | 0 | while (it.hasNext()) |
628 | |
{ |
629 | 0 | URL url = (URL) it.next(); |
630 | 0 | String systemId = url.toExternalForm(); |
631 | 0 | facesConfigs.put(systemId,url); |
632 | 0 | } |
633 | |
|
634 | 0 | for (Map.Entry<String, URL> entry : facesConfigs.entrySet()) |
635 | |
{ |
636 | 0 | InputStream stream = null; |
637 | |
try |
638 | |
{ |
639 | 0 | stream = openStreamWithoutCache(entry.getValue()); |
640 | 0 | if (log.isInfoEnabled()) |
641 | |
{ |
642 | 0 | log.info("Reading config : " + entry.getKey()); |
643 | |
} |
644 | 0 | getDispenser().feed(getUnmarshaller().getFacesConfig(stream, entry.getKey())); |
645 | |
} |
646 | |
finally |
647 | |
{ |
648 | 0 | if (stream != null) |
649 | |
{ |
650 | 0 | stream.close(); |
651 | |
} |
652 | |
} |
653 | 0 | } |
654 | |
} |
655 | 0 | catch (Throwable e) |
656 | |
{ |
657 | 0 | throw new FacesException(e); |
658 | 0 | } |
659 | 0 | } |
660 | |
|
661 | |
|
662 | |
private void feedContextSpecifiedConfig() throws IOException, SAXException |
663 | |
{ |
664 | 0 | List<String> configFilesList = getConfigFilesList(); |
665 | 0 | for (String systemId : configFilesList) |
666 | |
{ |
667 | 0 | InputStream stream = _externalContext.getResourceAsStream(systemId); |
668 | 0 | if (stream == null) |
669 | |
{ |
670 | 0 | log.error("Faces config resource " + systemId + " not found"); |
671 | 0 | continue; |
672 | |
} |
673 | |
|
674 | 0 | if (log.isInfoEnabled()) |
675 | |
{ |
676 | 0 | log.info("Reading config " + systemId); |
677 | |
} |
678 | 0 | getDispenser().feed(getUnmarshaller().getFacesConfig(stream, systemId)); |
679 | 0 | stream.close(); |
680 | 0 | } |
681 | 0 | } |
682 | |
|
683 | |
private List<String> getConfigFilesList() { |
684 | 0 | String configFiles = _externalContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR); |
685 | 0 | List<String> configFilesList = new ArrayList<String>(); |
686 | 0 | if (configFiles != null) |
687 | |
{ |
688 | 0 | StringTokenizer st = new StringTokenizer(configFiles, ",", false); |
689 | 0 | while (st.hasMoreTokens()) |
690 | |
{ |
691 | 0 | String systemId = st.nextToken().trim(); |
692 | |
|
693 | 0 | if (DEFAULT_FACES_CONFIG.equals(systemId)) |
694 | |
{ |
695 | 0 | if(log.isWarnEnabled()) |
696 | 0 | log.warn(DEFAULT_FACES_CONFIG + " has been specified in the " + |
697 | |
FacesServlet.CONFIG_FILES_ATTR + " context parameter of " + |
698 | |
"the deployment descriptor. This will automatically be removed, " + |
699 | |
"if we wouldn't do this, it would be loaded twice. See JSF spec 1.1, 10.3.2"); |
700 | |
} |
701 | |
else |
702 | 0 | configFilesList.add(systemId); |
703 | 0 | } |
704 | |
} |
705 | 0 | return configFilesList; |
706 | |
} |
707 | |
|
708 | |
private void feedWebAppConfig() throws IOException, SAXException |
709 | |
{ |
710 | |
|
711 | 0 | InputStream stream = _externalContext.getResourceAsStream(DEFAULT_FACES_CONFIG); |
712 | 0 | if (stream != null) |
713 | |
{ |
714 | 0 | if (log.isInfoEnabled()) |
715 | 0 | log.info("Reading config /WEB-INF/faces-config.xml"); |
716 | 0 | getDispenser().feed(getUnmarshaller().getFacesConfig(stream, DEFAULT_FACES_CONFIG)); |
717 | 0 | stream.close(); |
718 | |
} |
719 | 0 | } |
720 | |
|
721 | |
private void configureFactories() |
722 | |
{ |
723 | 0 | FacesConfigDispenser dispenser = getDispenser(); |
724 | 0 | setFactories(FactoryFinder.APPLICATION_FACTORY, dispenser.getApplicationFactoryIterator(), |
725 | |
DEFAULT_APPLICATION_FACTORY); |
726 | 0 | setFactories(FactoryFinder.FACES_CONTEXT_FACTORY, dispenser.getFacesContextFactoryIterator(), |
727 | |
DEFAULT_FACES_CONTEXT_FACTORY); |
728 | 0 | setFactories(FactoryFinder.LIFECYCLE_FACTORY, dispenser.getLifecycleFactoryIterator(), |
729 | |
DEFAULT_LIFECYCLE_FACTORY); |
730 | 0 | setFactories(FactoryFinder.RENDER_KIT_FACTORY, dispenser.getRenderKitFactoryIterator(), |
731 | |
DEFAULT_RENDER_KIT_FACTORY); |
732 | 0 | } |
733 | |
|
734 | |
private void setFactories(String factoryName, Iterator factories, String defaultFactory) |
735 | |
{ |
736 | 0 | FactoryFinder.setFactory(factoryName, defaultFactory); |
737 | 0 | while (factories.hasNext()) |
738 | |
{ |
739 | 0 | String factory = (String) factories.next(); |
740 | 0 | if (!factory.equals(defaultFactory)) |
741 | 0 | FactoryFinder.setFactory(factoryName, factory); |
742 | 0 | } |
743 | 0 | } |
744 | |
|
745 | |
private void startLib(String artifactId, Map<String, List<JarInfo>> libs) |
746 | |
{ |
747 | 0 | List<JarInfo> versions = libs.get(artifactId); |
748 | 0 | if (versions == null) |
749 | |
{ |
750 | 0 | log.info("MyFaces-package : " + artifactId + " not found."); |
751 | |
} |
752 | |
else |
753 | |
{ |
754 | 0 | JarInfo info = versions.get(0); |
755 | 0 | log.info("Starting up MyFaces-package : " + artifactId + " in version : " |
756 | |
+ info.getVersion() + " from path : " + info.getUrl()); |
757 | |
} |
758 | 0 | } |
759 | |
|
760 | |
private void configureApplication() |
761 | |
{ |
762 | 0 | Application application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)) |
763 | |
.getApplication(); |
764 | 0 | FacesConfigDispenser dispenser = getDispenser(); |
765 | 0 | application.setActionListener((ActionListener) getApplicationObject(ActionListener.class, dispenser |
766 | |
.getActionListenerIterator(), null)); |
767 | |
|
768 | 0 | if (dispenser.getDefaultLocale() != null) |
769 | |
{ |
770 | 0 | application.setDefaultLocale(LocaleUtils.toLocale(dispenser.getDefaultLocale())); |
771 | |
} |
772 | |
|
773 | 0 | if (dispenser.getDefaultRenderKitId() != null) |
774 | |
{ |
775 | 0 | application.setDefaultRenderKitId(dispenser.getDefaultRenderKitId()); |
776 | |
} |
777 | |
|
778 | 0 | if (dispenser.getMessageBundle() != null) |
779 | |
{ |
780 | 0 | application.setMessageBundle(dispenser.getMessageBundle()); |
781 | |
} |
782 | |
|
783 | 0 | application.setNavigationHandler((NavigationHandler) getApplicationObject(NavigationHandler.class, dispenser |
784 | |
.getNavigationHandlerIterator(), application.getNavigationHandler())); |
785 | |
|
786 | 0 | application.setStateManager((StateManager) getApplicationObject(StateManager.class, dispenser |
787 | |
.getStateManagerIterator(), application.getStateManager())); |
788 | 0 | List<Locale> locales = new ArrayList<Locale>(); |
789 | 0 | for (Iterator it = dispenser.getSupportedLocalesIterator(); it.hasNext();) |
790 | |
{ |
791 | 0 | locales.add(LocaleUtils.toLocale((String) it.next())); |
792 | |
} |
793 | 0 | application.setSupportedLocales(locales); |
794 | |
|
795 | 0 | application.setViewHandler((ViewHandler) getApplicationObject(ViewHandler.class, dispenser |
796 | |
.getViewHandlerIterator(), application.getViewHandler())); |
797 | |
|
798 | 0 | for (Iterator it = dispenser.getComponentTypes(); it.hasNext();) |
799 | |
{ |
800 | 0 | String componentType = (String) it.next(); |
801 | 0 | application.addComponent(componentType, dispenser.getComponentClass(componentType)); |
802 | 0 | } |
803 | |
|
804 | 0 | for (Iterator it = dispenser.getConverterIds(); it.hasNext();) |
805 | |
{ |
806 | 0 | String converterId = (String) it.next(); |
807 | 0 | application.addConverter(converterId, dispenser.getConverterClassById(converterId)); |
808 | 0 | } |
809 | |
|
810 | 0 | for (Iterator it = dispenser.getConverterClasses(); it.hasNext();) |
811 | |
{ |
812 | 0 | String converterClass = (String) it.next(); |
813 | |
try |
814 | |
{ |
815 | 0 | application.addConverter(ClassUtils.simpleClassForName(converterClass), dispenser |
816 | |
.getConverterClassByClass(converterClass)); |
817 | |
} |
818 | 0 | catch (Exception ex) |
819 | |
{ |
820 | 0 | log.error("Converter could not be added. Reason:", ex); |
821 | 0 | } |
822 | 0 | } |
823 | |
|
824 | 0 | if (application instanceof ApplicationImpl) |
825 | |
{ |
826 | 0 | for (Iterator it = dispenser.getConverterConfigurationByClassName(); it.hasNext();) |
827 | |
{ |
828 | 0 | String converterClassName = (String) it.next(); |
829 | |
|
830 | 0 | ((ApplicationImpl) application).addConverterConfiguration(converterClassName, dispenser |
831 | |
.getConverterConfiguration(converterClassName)); |
832 | 0 | } |
833 | |
} |
834 | |
|
835 | 0 | for (Iterator it = dispenser.getValidatorIds(); it.hasNext();) |
836 | |
{ |
837 | 0 | String validatorId = (String) it.next(); |
838 | 0 | application.addValidator(validatorId, dispenser.getValidatorClass(validatorId)); |
839 | 0 | } |
840 | |
|
841 | 0 | RuntimeConfig runtimeConfig = getRuntimeConfig(); |
842 | |
|
843 | 0 | runtimeConfig.setPropertyResolverChainHead((PropertyResolver) getApplicationObject(PropertyResolver.class, dispenser |
844 | |
.getPropertyResolverIterator(), new DefaultPropertyResolver())); |
845 | |
|
846 | 0 | runtimeConfig.setVariableResolverChainHead((VariableResolver) getApplicationObject(VariableResolver.class, dispenser |
847 | |
.getVariableResolverIterator(), new VariableResolverImpl())); |
848 | 0 | } |
849 | |
|
850 | |
protected RuntimeConfig getRuntimeConfig() |
851 | |
{ |
852 | 0 | if(_runtimeConfig == null) |
853 | |
{ |
854 | 0 | _runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext); |
855 | |
} |
856 | 0 | return _runtimeConfig; |
857 | |
} |
858 | |
|
859 | |
public void setRuntimeConfig(RuntimeConfig runtimeConfig) |
860 | |
{ |
861 | 0 | _runtimeConfig = runtimeConfig; |
862 | 0 | } |
863 | |
|
864 | |
private Object getApplicationObject(Class interfaceClass, Iterator classNamesIterator, Object defaultObject) |
865 | |
{ |
866 | 0 | Object current = defaultObject; |
867 | |
|
868 | 0 | while (classNamesIterator.hasNext()) |
869 | |
{ |
870 | 0 | String implClassName = (String) classNamesIterator.next(); |
871 | 0 | Class implClass = ClassUtils.simpleClassForName(implClassName); |
872 | |
|
873 | |
|
874 | 0 | if (!interfaceClass.isAssignableFrom(implClass)) |
875 | |
{ |
876 | 0 | throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName()); |
877 | |
} |
878 | |
|
879 | 0 | if (current == null) |
880 | |
{ |
881 | |
|
882 | 0 | current = ClassUtils.newInstance(implClass); |
883 | |
} |
884 | |
else |
885 | |
{ |
886 | |
|
887 | |
try |
888 | |
{ |
889 | 0 | Constructor delegationConstructor = implClass.getConstructor(new Class[] { interfaceClass }); |
890 | |
|
891 | |
try |
892 | |
{ |
893 | |
|
894 | 0 | current = delegationConstructor.newInstance(new Object[] { current }); |
895 | |
} |
896 | 0 | catch (InstantiationException e) |
897 | |
{ |
898 | 0 | log.error(e.getMessage(), e); |
899 | 0 | throw new FacesException(e); |
900 | |
} |
901 | 0 | catch (IllegalAccessException e) |
902 | |
{ |
903 | 0 | log.error(e.getMessage(), e); |
904 | 0 | throw new FacesException(e); |
905 | |
} |
906 | 0 | catch (InvocationTargetException e) |
907 | |
{ |
908 | 0 | log.error(e.getMessage(), e); |
909 | 0 | throw new FacesException(e); |
910 | 0 | } |
911 | |
} |
912 | 0 | catch (NoSuchMethodException e) |
913 | |
{ |
914 | |
|
915 | 0 | current = ClassUtils.newInstance(implClass); |
916 | 0 | } |
917 | |
} |
918 | 0 | } |
919 | |
|
920 | 0 | return current; |
921 | |
} |
922 | |
|
923 | |
private void configureRuntimeConfig() |
924 | |
{ |
925 | 0 | RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext); |
926 | |
|
927 | 0 | FacesConfigDispenser dispenser = getDispenser(); |
928 | 0 | for (Iterator iterator = dispenser.getManagedBeans(); iterator.hasNext();) |
929 | |
{ |
930 | 0 | ManagedBean bean = (ManagedBean) iterator.next(); |
931 | |
|
932 | 0 | if (log.isWarnEnabled() && runtimeConfig.getManagedBean(bean.getManagedBeanName()) != null) |
933 | 0 | log.warn("More than one managed bean w/ the name of '" + bean.getManagedBeanName() |
934 | |
+ "' - only keeping the last "); |
935 | |
|
936 | 0 | runtimeConfig.addManagedBean(bean.getManagedBeanName(), bean); |
937 | |
|
938 | 0 | } |
939 | |
|
940 | 0 | removePurgedBeansFromSessionAndApplication(runtimeConfig); |
941 | |
|
942 | 0 | for (Iterator iterator = dispenser.getNavigationRules(); iterator.hasNext();) |
943 | |
{ |
944 | 0 | NavigationRule rule = (NavigationRule) iterator.next(); |
945 | 0 | runtimeConfig.addNavigationRule(rule); |
946 | |
|
947 | 0 | } |
948 | |
|
949 | 0 | for (Iterator<ResourceBundle> iter = dispenser.getResourceBundles(); iter.hasNext();) |
950 | |
{ |
951 | 0 | runtimeConfig.addResourceBundle(iter.next()); |
952 | |
} |
953 | |
|
954 | 0 | for (Iterator<String> iter = dispenser.getElResolvers(); iter.hasNext();) |
955 | |
{ |
956 | 0 | runtimeConfig.addFacesConfigElResolver((ELResolver) ClassUtils.newInstance(iter.next(), ELResolver.class)); |
957 | |
} |
958 | |
|
959 | 0 | } |
960 | |
|
961 | |
private void removePurgedBeansFromSessionAndApplication(RuntimeConfig runtimeConfig) |
962 | |
{ |
963 | 0 | Map oldManagedBeans = runtimeConfig.getManagedBeansNotReaddedAfterPurge(); |
964 | 0 | if(oldManagedBeans!=null) { |
965 | 0 | Iterator it=oldManagedBeans.entrySet().iterator(); |
966 | 0 | while(it.hasNext()) { |
967 | 0 | Map.Entry entry = (Map.Entry) it.next(); |
968 | 0 | ManagedBean bean = (ManagedBean) entry.getValue(); |
969 | |
|
970 | 0 | String scope = bean.getManagedBeanScope(); |
971 | |
|
972 | 0 | if(scope!=null && scope.equalsIgnoreCase("session")) { |
973 | 0 | _externalContext.getSessionMap().remove(entry.getKey()); |
974 | |
} |
975 | 0 | else if(scope!=null && scope.equalsIgnoreCase("application")) { |
976 | 0 | _externalContext.getApplicationMap().remove(entry.getKey()); |
977 | |
} |
978 | 0 | } |
979 | |
} |
980 | 0 | runtimeConfig.resetManagedBeansNotReaddedAfterPurge(); |
981 | 0 | } |
982 | |
|
983 | |
private void configureRenderKits() |
984 | |
{ |
985 | 0 | RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder |
986 | |
.getFactory(FactoryFinder.RENDER_KIT_FACTORY); |
987 | |
|
988 | 0 | FacesConfigDispenser dispenser = getDispenser(); |
989 | 0 | for (Iterator iterator = dispenser.getRenderKitIds(); iterator.hasNext();) |
990 | |
{ |
991 | 0 | String renderKitId = (String) iterator.next(); |
992 | 0 | String renderKitClass = dispenser.getRenderKitClass(renderKitId); |
993 | |
|
994 | 0 | if (renderKitClass == null) |
995 | |
{ |
996 | 0 | renderKitClass = DEFAULT_RENDER_KIT_CLASS; |
997 | |
} |
998 | |
|
999 | 0 | RenderKit renderKit = (RenderKit) ClassUtils.newInstance(renderKitClass); |
1000 | |
|
1001 | 0 | for (Iterator renderers = dispenser.getRenderers(renderKitId); renderers.hasNext();) |
1002 | |
{ |
1003 | 0 | Renderer element = (Renderer) renderers.next(); |
1004 | |
javax.faces.render.Renderer renderer; |
1005 | |
try |
1006 | |
{ |
1007 | 0 | renderer = (javax.faces.render.Renderer) ClassUtils.newInstance(element.getRendererClass()); |
1008 | |
} |
1009 | 0 | catch (Throwable e) |
1010 | |
{ |
1011 | |
|
1012 | 0 | log.error("failed to configure class " + element.getRendererClass(), e); |
1013 | 0 | continue; |
1014 | 0 | } |
1015 | |
|
1016 | 0 | renderKit.addRenderer(element.getComponentFamily(), element.getRendererType(), renderer); |
1017 | 0 | } |
1018 | |
|
1019 | 0 | renderKitFactory.addRenderKit(renderKitId, renderKit); |
1020 | 0 | } |
1021 | 0 | } |
1022 | |
|
1023 | |
private void configureLifecycle() |
1024 | |
{ |
1025 | |
|
1026 | 0 | LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder |
1027 | |
.getFactory(FactoryFinder.LIFECYCLE_FACTORY); |
1028 | 0 | Lifecycle lifecycle = lifecycleFactory.getLifecycle(getLifecycleId()); |
1029 | |
|
1030 | |
|
1031 | 0 | for (Iterator iterator = getDispenser().getLifecyclePhaseListeners(); iterator.hasNext();) |
1032 | |
{ |
1033 | 0 | String listenerClassName = (String) iterator.next(); |
1034 | |
try |
1035 | |
{ |
1036 | 0 | lifecycle.addPhaseListener((PhaseListener) ClassUtils.newInstance(listenerClassName)); |
1037 | |
} |
1038 | 0 | catch (ClassCastException e) |
1039 | |
{ |
1040 | 0 | log.error("Class " + listenerClassName + " does not implement PhaseListener"); |
1041 | 0 | } |
1042 | 0 | } |
1043 | 0 | } |
1044 | |
|
1045 | |
private String getLifecycleId() |
1046 | |
{ |
1047 | 0 | String id = _externalContext.getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR); |
1048 | |
|
1049 | 0 | if (id != null) |
1050 | |
{ |
1051 | 0 | return id; |
1052 | |
} |
1053 | |
|
1054 | 0 | return LifecycleFactory.DEFAULT_LIFECYCLE; |
1055 | |
} |
1056 | |
|
1057 | |
|
1058 | |
|
1059 | |
|
1060 | |
|
1061 | |
|
1062 | |
|
1063 | |
|
1064 | |
|
1065 | |
|
1066 | |
|
1067 | |
|
1068 | |
|
1069 | |
|
1070 | |
|
1071 | |
|
1072 | |
|
1073 | |
|
1074 | |
|
1075 | |
|
1076 | |
|
1077 | |
|
1078 | |
|
1079 | |
|
1080 | |
|
1081 | |
|
1082 | |
|
1083 | |
|
1084 | |
|
1085 | |
|
1086 | |
|
1087 | |
|
1088 | |
|
1089 | |
|
1090 | |
|
1091 | |
|
1092 | |
|
1093 | |
|
1094 | |
|
1095 | |
|
1096 | |
|
1097 | |
|
1098 | |
|
1099 | |
|
1100 | |
|
1101 | |
|
1102 | |
|
1103 | |
|
1104 | |
|
1105 | |
|
1106 | |
|
1107 | |
|
1108 | |
|
1109 | |
|
1110 | |
|
1111 | |
|
1112 | |
|
1113 | |
|
1114 | |
|
1115 | |
|
1116 | |
|
1117 | |
|
1118 | |
|
1119 | |
|
1120 | |
|
1121 | |
|
1122 | |
|
1123 | |
|
1124 | |
|
1125 | |
|
1126 | |
|
1127 | |
|
1128 | |
|
1129 | |
|
1130 | |
|
1131 | |
|
1132 | |
|
1133 | 0 | private static class JarInfo implements Comparable<JarInfo> |
1134 | |
{ |
1135 | |
private String url; |
1136 | |
private Version version; |
1137 | |
|
1138 | |
public JarInfo(String url, Version version) |
1139 | 0 | { |
1140 | 0 | this.url = url; |
1141 | 0 | this.version = version; |
1142 | 0 | } |
1143 | |
|
1144 | |
public Version getVersion() |
1145 | |
{ |
1146 | 0 | return version; |
1147 | |
} |
1148 | |
|
1149 | |
public String getUrl() |
1150 | |
{ |
1151 | 0 | return url; |
1152 | |
} |
1153 | |
|
1154 | |
public int compareTo(JarInfo info) |
1155 | |
{ |
1156 | 0 | return version.compareTo(info.version); |
1157 | |
} |
1158 | |
|
1159 | |
@Override |
1160 | |
public boolean equals(Object o) |
1161 | |
{ |
1162 | 0 | if (o == this) |
1163 | |
{ |
1164 | 0 | return true; |
1165 | |
} |
1166 | 0 | else if (o instanceof JarInfo) |
1167 | |
{ |
1168 | 0 | JarInfo other = (JarInfo)o; |
1169 | 0 | return version.equals(other.version); |
1170 | |
} |
1171 | |
else |
1172 | |
{ |
1173 | 0 | return false; |
1174 | |
} |
1175 | |
} |
1176 | |
|
1177 | |
@Override |
1178 | |
public int hashCode() |
1179 | |
{ |
1180 | 0 | return version.hashCode(); |
1181 | |
} |
1182 | |
} |
1183 | |
|
1184 | 0 | static class Version implements Comparable<Version> |
1185 | |
{ |
1186 | |
|
1187 | |
|
1188 | |
|
1189 | |
private Long[] parts; |
1190 | |
|
1191 | |
private boolean snapshot; |
1192 | |
|
1193 | |
public Version(String major, String minor, String maintenance, |
1194 | |
String extra, String snapshot) |
1195 | 0 | { |
1196 | 0 | parts = new Long[4]; |
1197 | 0 | parts[0] = Long.valueOf(major); |
1198 | |
|
1199 | 0 | if (minor != null) |
1200 | |
{ |
1201 | 0 | parts[1] = Long.valueOf(minor); |
1202 | |
|
1203 | 0 | if (maintenance != null) |
1204 | |
{ |
1205 | 0 | parts[2] = Long.valueOf(maintenance); |
1206 | |
|
1207 | 0 | if (extra != null) |
1208 | |
{ |
1209 | 0 | parts[3] = Long.valueOf(extra); |
1210 | |
} |
1211 | |
} |
1212 | |
} |
1213 | |
|
1214 | 0 | this.snapshot = snapshot != null; |
1215 | 0 | } |
1216 | |
|
1217 | |
public int compareTo(Version v) |
1218 | |
{ |
1219 | 0 | for (int i = 0; i < parts.length; i++) |
1220 | |
{ |
1221 | 0 | Long left = parts[i]; |
1222 | 0 | Long right = v.parts[i]; |
1223 | 0 | if (left == null) |
1224 | |
{ |
1225 | 0 | if (right == null) |
1226 | |
{ |
1227 | 0 | break; |
1228 | |
} |
1229 | |
else |
1230 | |
{ |
1231 | 0 | return -1; |
1232 | |
} |
1233 | |
} |
1234 | |
else |
1235 | |
{ |
1236 | 0 | if (right == null) |
1237 | |
{ |
1238 | 0 | return 1; |
1239 | |
} |
1240 | 0 | else if (left < right) |
1241 | |
{ |
1242 | 0 | return -1; |
1243 | |
} |
1244 | 0 | else if (left > right) |
1245 | |
{ |
1246 | 0 | return 1; |
1247 | |
} |
1248 | |
} |
1249 | |
} |
1250 | |
|
1251 | 0 | if (snapshot) |
1252 | |
{ |
1253 | 0 | return v.snapshot ? 0 : -1; |
1254 | |
} |
1255 | |
else |
1256 | |
{ |
1257 | 0 | return v.snapshot ? 1 : 0; |
1258 | |
} |
1259 | |
} |
1260 | |
|
1261 | |
@Override |
1262 | |
public boolean equals(Object o) |
1263 | |
{ |
1264 | 0 | if (o == this) |
1265 | |
{ |
1266 | 0 | return true; |
1267 | |
} |
1268 | 0 | else if (o instanceof Version) |
1269 | |
{ |
1270 | 0 | Version other = (Version)o; |
1271 | 0 | if (snapshot != other.snapshot) |
1272 | |
{ |
1273 | 0 | return false; |
1274 | |
} |
1275 | |
|
1276 | 0 | for (int i = 0; i < parts.length; i++) |
1277 | |
{ |
1278 | 0 | Long thisPart = parts[i]; |
1279 | 0 | Long otherPart = other.parts[i]; |
1280 | 0 | if (thisPart == null ? otherPart != null : !thisPart.equals(otherPart)) |
1281 | |
{ |
1282 | 0 | return false; |
1283 | |
} |
1284 | |
} |
1285 | |
|
1286 | 0 | return true; |
1287 | |
} |
1288 | |
else |
1289 | |
{ |
1290 | 0 | return false; |
1291 | |
} |
1292 | |
} |
1293 | |
|
1294 | |
@Override |
1295 | |
public int hashCode() |
1296 | |
{ |
1297 | 0 | int hash = 0; |
1298 | 0 | for (int i = 0; i < parts.length; i++) |
1299 | |
{ |
1300 | 0 | if (parts[i] != null) |
1301 | |
{ |
1302 | 0 | hash ^= parts[i].hashCode(); |
1303 | |
} |
1304 | |
} |
1305 | |
|
1306 | 0 | hash ^= Boolean.valueOf(snapshot).hashCode(); |
1307 | |
|
1308 | 0 | return hash; |
1309 | |
} |
1310 | |
|
1311 | |
@Override |
1312 | |
public String toString() |
1313 | |
{ |
1314 | 0 | StringBuilder builder = new StringBuilder(); |
1315 | 0 | builder.append(parts[0]); |
1316 | 0 | for (int i = 1; i < parts.length; i++) |
1317 | |
{ |
1318 | 0 | Long val = parts[i]; |
1319 | 0 | if (val != null) |
1320 | |
{ |
1321 | 0 | builder.append('.').append(val); |
1322 | |
} |
1323 | |
} |
1324 | |
|
1325 | 0 | if (snapshot) |
1326 | |
{ |
1327 | 0 | builder.append("-SNAPSHOT"); |
1328 | |
} |
1329 | |
|
1330 | 0 | return builder.toString(); |
1331 | |
} |
1332 | |
} |
1333 | |
|
1334 | |
private void handleSerialFactory() |
1335 | |
{ |
1336 | |
|
1337 | 0 | String serialProvider = _externalContext.getInitParameter(StateUtils.SERIAL_FACTORY); |
1338 | 0 | SerialFactory serialFactory = null; |
1339 | |
|
1340 | 0 | if (serialProvider == null) |
1341 | |
{ |
1342 | 0 | serialFactory = new DefaultSerialFactory(); |
1343 | |
} |
1344 | |
else |
1345 | |
{ |
1346 | |
try |
1347 | |
{ |
1348 | 0 | serialFactory = (SerialFactory) ClassUtils.newInstance(serialProvider); |
1349 | |
|
1350 | |
} |
1351 | 0 | catch (ClassCastException e) |
1352 | |
{ |
1353 | 0 | log.error("Make sure '" + serialProvider + "' implements the correct interface", e); |
1354 | |
} |
1355 | 0 | catch (Exception e) |
1356 | |
{ |
1357 | 0 | log.error(e); |
1358 | |
} |
1359 | |
finally |
1360 | |
{ |
1361 | 0 | if (serialFactory == null) |
1362 | |
{ |
1363 | 0 | serialFactory = new DefaultSerialFactory(); |
1364 | 0 | log.error("Using default serialization provider"); |
1365 | |
} |
1366 | |
} |
1367 | |
|
1368 | |
} |
1369 | |
|
1370 | 0 | log.info("Serialization provider : " + serialFactory.getClass()); |
1371 | 0 | _externalContext.getApplicationMap().put(StateUtils.SERIAL_FACTORY, serialFactory); |
1372 | |
|
1373 | 0 | } |
1374 | |
|
1375 | |
} |