1 16 package org.apache.myfaces.config; 17 18 import java.io.BufferedReader ; 19 import java.io.File ; 20 import java.io.FileOutputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.InputStreamReader ; 24 import java.lang.reflect.Constructor ; 25 import java.lang.reflect.InvocationTargetException ; 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Set ; 33 import java.util.StringTokenizer ; 34 import java.util.jar.JarEntry ; 35 import java.util.jar.JarFile ; 36 import java.util.jar.JarInputStream ; 37 38 import javax.faces.FacesException; 39 import javax.faces.FactoryFinder; 40 import javax.faces.application.Application; 41 import javax.faces.application.ApplicationFactory; 42 import javax.faces.application.NavigationHandler; 43 import javax.faces.application.StateManager; 44 import javax.faces.application.ViewHandler; 45 import javax.faces.context.ExternalContext; 46 import javax.faces.el.PropertyResolver; 47 import javax.faces.el.VariableResolver; 48 import javax.faces.event.ActionListener; 49 import javax.faces.event.PhaseListener; 50 import javax.faces.lifecycle.Lifecycle; 51 import javax.faces.lifecycle.LifecycleFactory; 52 import javax.faces.render.RenderKit; 53 import javax.faces.render.RenderKitFactory; 54 import javax.faces.webapp.FacesServlet; 55 56 import org.apache.commons.logging.Log; 57 import org.apache.commons.logging.LogFactory; 58 import org.apache.myfaces.application.ApplicationFactoryImpl; 59 import org.apache.myfaces.application.ApplicationImpl; 60 import org.apache.myfaces.config.element.ManagedBean; 61 import org.apache.myfaces.config.element.NavigationRule; 62 import org.apache.myfaces.config.element.Renderer; 63 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl; 64 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl; 65 import org.apache.myfaces.context.FacesContextFactoryImpl; 66 import org.apache.myfaces.lifecycle.LifecycleFactoryImpl; 67 import org.apache.myfaces.renderkit.RenderKitFactoryImpl; 68 import org.apache.myfaces.renderkit.html.HtmlRenderKitImpl; 69 import org.apache.myfaces.util.ClassUtils; 70 import org.apache.myfaces.util.LocaleUtils; 71 import org.xml.sax.SAXException ; 72 73 74 151 public class FacesConfigurator 152 { 153 154 private static final Log log = LogFactory.getLog(FacesConfigurator.class); 155 156 private static final String STANDARD_FACES_CONFIG_RESOURCE 157 = "org.apache.myfaces.resource".replace('.', '/') + "/standard-faces-config.xml"; 158 159 public static final String APPLICATION_MAP_LIFECYCLE_KEY = Lifecycle.class.getName(); 160 161 public static final String META_INF_SERVICES_LOCATION = "/META-INF/services/"; 162 163 private static final String DEFAULT_RENDER_KIT_CLASS = HtmlRenderKitImpl.class.getName(); 164 private static final String DEFAULT_APPLICATION_FACTORY = ApplicationFactoryImpl.class.getName(); 165 private static final String DEFAULT_FACES_CONTEXT_FACTORY = FacesContextFactoryImpl.class.getName(); 166 private static final String DEFAULT_LIFECYCLE_FACTORY = LifecycleFactoryImpl.class.getName(); 167 private static final String DEFAULT_RENDER_KIT_FACTORY = RenderKitFactoryImpl.class.getName(); 168 169 private static final Set FACTORY_NAMES = new HashSet (); 170 { 171 FACTORY_NAMES.add(FactoryFinder.APPLICATION_FACTORY); 172 FACTORY_NAMES.add(FactoryFinder.FACES_CONTEXT_FACTORY); 173 FACTORY_NAMES.add(FactoryFinder.LIFECYCLE_FACTORY); 174 FACTORY_NAMES.add(FactoryFinder.RENDER_KIT_FACTORY); 175 } 176 177 178 private ExternalContext _externalContext; 179 private FacesConfigUnmarshaller _unmarshaller; 180 private FacesConfigDispenser _dispenser; 181 182 183 public FacesConfigurator(ExternalContext externalContext) 184 { 185 _externalContext = externalContext; 186 187 } 188 189 190 public void configure() 191 throws FacesException 192 { 193 _unmarshaller = new DigesterFacesConfigUnmarshallerImpl(_externalContext); 197 _dispenser = new DigesterFacesConfigDispenserImpl(); 198 199 try 200 { 201 feedStandardConfig(); 202 feedMetaInfServicesFactories(); 203 feedJarFileConfigurations(); 204 feedContextSpecifiedConfig(); 205 feedWebAppConfig(); 206 } catch (IOException e) 207 { 208 throw new FacesException(e); 209 } catch (SAXException e) 210 { 211 throw new FacesException(e); 212 } 213 214 configureFactories(); 215 configureApplication(); 216 configureRenderKits(); 217 configureRuntimeConfig(); 218 configureLifecycle(); 219 } 220 221 222 private void feedStandardConfig() throws IOException , SAXException 223 { 224 InputStream stream = ClassUtils.getResourceAsStream(STANDARD_FACES_CONFIG_RESOURCE); 225 if (stream == null) throw new FacesException("Standard faces config " + STANDARD_FACES_CONFIG_RESOURCE + " not found"); 226 if (log.isInfoEnabled()) log.info("Reading standard config " + STANDARD_FACES_CONFIG_RESOURCE); 227 _dispenser.feed(_unmarshaller.getFacesConfig(stream, STANDARD_FACES_CONFIG_RESOURCE)); 228 } 229 230 231 237 protected void feedMetaInfServicesFactories() 238 { 239 Map resourceNames = expandFactoryNames(FACTORY_NAMES); 241 Set services = _externalContext.getResourcePaths(META_INF_SERVICES_LOCATION); 243 if (null != services) 247 { 248 services.retainAll(resourceNames.keySet()); 249 Iterator itr = services.iterator(); 250 while (itr.hasNext()) 251 { 252 String resourceName = (String ) itr.next(); 253 InputStream is = _externalContext.getResourceAsStream(resourceName); 254 InputStreamReader isr = new InputStreamReader (is); 255 BufferedReader br = new BufferedReader (isr); 256 String className = null; 257 try 258 { 259 className = br.readLine(); 260 } catch (IOException e) 261 { 262 throw new FacesException("Unable to read class name from file " 263 + resourceName, e); 264 } 265 266 String factoryName = (String ) resourceNames.get(resourceName); 267 if (factoryName.equals(FactoryFinder.APPLICATION_FACTORY)) 268 { 269 _dispenser.feedApplicationFactory(className); 270 } else if (factoryName.equals(FactoryFinder.FACES_CONTEXT_FACTORY)) 271 { 272 _dispenser.feedFacesContextFactory(className); 273 } else if (factoryName.equals(FactoryFinder.LIFECYCLE_FACTORY)) 274 { 275 _dispenser.feedLifecycleFactory(className); 276 } else if (factoryName.equals(FactoryFinder.RENDER_KIT_FACTORY)) 277 { 278 _dispenser.feedRenderKitFactory(className); 279 } else 280 { 281 throw new IllegalStateException ("Unexpected factory name " + factoryName); 282 } 283 } 284 } 285 } 286 287 288 private Map expandFactoryNames(Set factoryNames) 289 { 290 Map names = new HashMap (); 291 Iterator itr = factoryNames.iterator(); 292 while (itr.hasNext()) 293 { 294 String name = (String ) itr.next(); 295 names.put(META_INF_SERVICES_LOCATION + name, name); 296 } 297 return names; 298 } 299 300 301 private void feedJarFileConfigurations() 302 { 303 Set jars = _externalContext.getResourcePaths("/WEB-INF/lib/"); 304 if (jars != null) 305 { 306 for (Iterator it = jars.iterator(); it.hasNext();) 307 { 308 String path = (String ) it.next(); 309 if (path.toLowerCase().endsWith(".jar")) 310 { 311 feedJarConfig(path); 312 } 313 } 314 } 315 } 316 317 private void feedJarConfig(String jarPath) 318 throws FacesException 319 { 320 try 321 { 322 InputStream in = _externalContext.getResourceAsStream(jarPath); 325 if (in == null) 326 { 327 if (jarPath.startsWith("/")) 328 { 329 in = _externalContext.getResourceAsStream(jarPath.substring(1)); 330 } else 331 { 332 in = _externalContext.getResourceAsStream("/" + jarPath); 333 } 334 } 335 if (in == null) 336 { 337 log.error("Resource " + jarPath + " not found"); 338 return; 339 } 340 341 JarInputStream jar = new JarInputStream (in); 343 JarEntry entry = jar.getNextJarEntry(); 344 boolean found = false; 345 346 while (entry != null) 347 { 348 if (entry.getName().equals("META-INF/faces-config.xml")) 349 { 350 if (log.isDebugEnabled()) log.debug("faces-config.xml found in " + jarPath); 351 found = true; 352 break; 353 } 354 entry = jar.getNextJarEntry(); 355 } 356 jar.close(); 357 358 File tmp = null; 359 360 if (found) 363 { 364 tmp = File.createTempFile("myfaces", ".jar"); 365 in = _externalContext.getResourceAsStream(jarPath); 366 FileOutputStream out = new FileOutputStream (tmp); 367 byte[] buffer = new byte[4096]; 368 int r; 369 370 while ((r = in.read(buffer)) != -1) 371 { 372 out.write(buffer, 0, r); 373 } 374 out.close(); 375 376 JarFile jarFile = new JarFile (tmp); 377 try 378 { 379 JarEntry configFile = jarFile.getJarEntry("META-INF/faces-config.xml"); 380 if (configFile != null) 381 { 382 if (log.isDebugEnabled()) log.debug("faces-config.xml found in jar " + jarPath); 383 InputStream stream = jarFile.getInputStream(configFile); 384 String systemId = "jar:" + tmp.toURL() + "!/" + configFile.getName(); 385 if (log.isInfoEnabled()) log.info("Reading config " + systemId); 386 _dispenser.feed(_unmarshaller.getFacesConfig(stream, systemId)); 387 } 388 } finally 389 { 390 jarFile.close(); 391 tmp.delete(); 392 } 393 } else 394 { 395 if (log.isDebugEnabled()) log.debug("Jar " + jarPath + " contains no faces-config.xml"); 396 } 397 } catch (Exception e) 398 { 399 throw new FacesException(e); 400 } 401 } 402 403 404 private void feedContextSpecifiedConfig() throws IOException , SAXException 405 { 406 String configFiles = _externalContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR); 407 if (configFiles != null) 408 { 409 StringTokenizer st = new StringTokenizer (configFiles, ",", false); 410 while (st.hasMoreTokens()) 411 { 412 String systemId = st.nextToken().trim(); 413 InputStream stream = _externalContext.getResourceAsStream(systemId); 414 if (stream == null) 415 { 416 log.error("Faces config resource " + systemId + " not found"); 417 continue; 418 } 419 420 if (log.isInfoEnabled()) log.info("Reading config " + systemId); 421 422 _dispenser.feed(_unmarshaller.getFacesConfig(stream, systemId)); 423 } 424 } 425 } 426 427 428 private void feedWebAppConfig() throws IOException , SAXException 429 { 430 String systemId = "/WEB-INF/faces-config.xml"; 432 InputStream stream = _externalContext.getResourceAsStream(systemId); 433 if (stream != null) 434 { 435 if (log.isInfoEnabled()) log.info("Reading config /WEB-INF/faces-config.xml"); 436 437 _dispenser.feed(_unmarshaller.getFacesConfig(stream, systemId)); 438 } 439 } 440 441 442 private void configureFactories() 443 { 444 setFactories(FactoryFinder.APPLICATION_FACTORY, _dispenser.getApplicationFactoryIterator(), DEFAULT_APPLICATION_FACTORY); 445 setFactories(FactoryFinder.FACES_CONTEXT_FACTORY, _dispenser.getFacesContextFactoryIterator(), DEFAULT_FACES_CONTEXT_FACTORY); 446 setFactories(FactoryFinder.LIFECYCLE_FACTORY, _dispenser.getLifecycleFactoryIterator(), DEFAULT_LIFECYCLE_FACTORY); 447 setFactories(FactoryFinder.RENDER_KIT_FACTORY, _dispenser.getRenderKitFactoryIterator(), DEFAULT_RENDER_KIT_FACTORY); 448 } 449 450 451 private void setFactories(String factoryName, Iterator factories, String defaultFactory) 452 { 453 FactoryFinder.setFactory(factoryName, defaultFactory); 454 while (factories.hasNext()) 455 { 456 FactoryFinder.setFactory(factoryName, (String ) factories.next()); 457 } 458 } 459 460 461 private void configureApplication() 462 { 463 Application application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication(); 464 application.setActionListener((ActionListener) getApplicationObject(ActionListener.class, _dispenser.getActionListenerIterator(), null)); 465 466 if (_dispenser.getDefaultLocale() != null) 467 { 468 application.setDefaultLocale( 469 LocaleUtils.toLocale(_dispenser.getDefaultLocale())); 470 } 471 472 if (_dispenser.getDefaultRenderKitId() != null) 473 { 474 application.setDefaultRenderKitId(_dispenser.getDefaultRenderKitId()); 475 } 476 477 if (_dispenser.getMessageBundle() != null) 478 { 479 application.setMessageBundle(_dispenser.getMessageBundle()); 480 } 481 482 application.setNavigationHandler((NavigationHandler) getApplicationObject(NavigationHandler.class, 483 _dispenser.getNavigationHandlerIterator(), application.getNavigationHandler())); 484 application.setPropertyResolver((PropertyResolver) getApplicationObject(PropertyResolver.class, 485 _dispenser.getPropertyResolverIterator(), application.getPropertyResolver())); 486 application.setStateManager((StateManager) getApplicationObject(StateManager.class, 487 _dispenser.getStateManagerIterator(), application.getStateManager())); 488 List locales = new ArrayList (); 489 for (Iterator it = _dispenser.getSupportedLocalesIterator(); it.hasNext();) 490 { 491 locales.add(LocaleUtils.toLocale((String ) it.next())); 492 } 493 application.setSupportedLocales(locales); 494 495 application.setVariableResolver((VariableResolver) getApplicationObject(VariableResolver.class, 496 _dispenser.getVariableResolverIterator(), application.getVariableResolver())); 497 application.setViewHandler((ViewHandler) getApplicationObject(ViewHandler.class, 498 _dispenser.getViewHandlerIterator(), application.getViewHandler())); 499 500 for (Iterator it = _dispenser.getComponentTypes(); it.hasNext();) 501 { 502 String componentType = (String ) it.next(); 503 application.addComponent(componentType, 504 _dispenser.getComponentClass(componentType)); 505 } 506 507 for (Iterator it = _dispenser.getConverterIds(); it.hasNext();) 508 { 509 String converterId = (String ) it.next(); 510 application.addConverter(converterId, 511 _dispenser.getConverterClassById(converterId)); 512 } 513 514 for (Iterator it = _dispenser.getConverterClasses(); it.hasNext();) 515 { 516 String converterClass = (String ) it.next(); 517 try 518 { 519 application.addConverter(ClassUtils.simpleClassForName(converterClass), 520 _dispenser.getConverterClassByClass(converterClass)); 521 } 522 catch(Exception ex) 523 { 524 log.error("Converter could not be added. Reason:",ex); 525 } 526 } 527 528 if(application instanceof ApplicationImpl) 529 { 530 for (Iterator it = _dispenser.getConverterConfigurationByClassName(); it.hasNext();) 531 { 532 String converterClassName = (String ) it.next(); 533 534 ((ApplicationImpl) application).addConverterConfiguration(converterClassName, 535 _dispenser.getConverterConfiguration(converterClassName)); 536 } 537 } 538 539 for (Iterator it = _dispenser.getValidatorIds(); it.hasNext();) 540 { 541 String validatorId = (String ) it.next(); 542 application.addValidator(validatorId, 543 _dispenser.getValidatorClass(validatorId)); 544 } 545 } 546 547 548 private Object getApplicationObject(Class interfaceClass, Iterator classNamesIterator, Object defaultObject) 549 { 550 Object current = defaultObject; 551 552 while (classNamesIterator.hasNext()) 553 { 554 String implClassName = (String ) classNamesIterator.next(); 555 Class implClass = ClassUtils.simpleClassForName(implClassName); 556 557 if (!interfaceClass.isAssignableFrom(implClass)) 559 { 560 throw new IllegalArgumentException ("Class " + implClassName + " is no " + interfaceClass.getName()); 561 } 562 563 if (current == null) 564 { 565 current = ClassUtils.newInstance(implClass); 567 } else 568 { 569 try 571 { 572 Constructor delegationConstructor = implClass.getConstructor(new Class []{interfaceClass}); 573 try 575 { 576 current = delegationConstructor.newInstance(new Object []{current}); 578 } catch (InstantiationException e) 579 { 580 log.error(e.getMessage(), e); 581 throw new FacesException(e); 582 } catch (IllegalAccessException e) 583 { 584 log.error(e.getMessage(), e); 585 throw new FacesException(e); 586 } catch (InvocationTargetException e) 587 { 588 log.error(e.getMessage(), e); 589 throw new FacesException(e); 590 } 591 } catch (NoSuchMethodException e) 592 { 593 current = ClassUtils.newInstance(implClass); 595 } 596 } 597 } 598 599 return current; 600 } 601 602 603 private void configureRuntimeConfig() 604 { 605 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(_externalContext); 606 607 for (Iterator iterator = _dispenser.getManagedBeans(); iterator.hasNext();) 608 { 609 ManagedBean bean = (ManagedBean) iterator.next(); 610 runtimeConfig.addManagedBean(bean.getManagedBeanName(), bean); 611 612 } 613 614 for (Iterator iterator = _dispenser.getNavigationRules(); iterator.hasNext();) 615 { 616 NavigationRule rule = (NavigationRule) iterator.next(); 617 runtimeConfig.addNavigationRule(rule); 618 619 } 620 } 621 622 623 private void configureRenderKits() 624 { 625 RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); 626 627 for (Iterator iterator = _dispenser.getRenderKitIds(); iterator.hasNext();) 628 { 629 String renderKitId = (String ) iterator.next(); 630 String renderKitClass = _dispenser.getRenderKitClass(renderKitId); 631 632 if (renderKitClass == null) 633 { 634 renderKitClass = DEFAULT_RENDER_KIT_CLASS; 635 } 636 637 RenderKit renderKit = (RenderKit) ClassUtils.newInstance(renderKitClass); 638 639 for (Iterator renderers = _dispenser.getRenderers(renderKitId); renderers.hasNext();) 640 { 641 Renderer element = (Renderer) renderers.next(); 642 javax.faces.render.Renderer renderer = null; 643 try { 644 renderer = (javax.faces.render.Renderer) ClassUtils.newInstance(element.getRendererClass()); 645 } catch(FacesException e) { 646 log.error("failed to configure class " + element.getRendererClass(), e); 648 continue; 649 } 650 651 renderKit.addRenderer(element.getComponentFamily(), element.getRendererType(), renderer); 652 } 653 654 renderKitFactory.addRenderKit(renderKitId, renderKit); 655 } 656 } 657 658 659 private void configureLifecycle() 660 { 661 LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 663 Lifecycle lifecycle = lifecycleFactory.getLifecycle(getLifecycleId()); 664 665 for (Iterator iterator = _dispenser.getLifecyclePhaseListeners(); iterator.hasNext();) 667 { 668 String listenerClassName = (String ) iterator.next(); 669 try 670 { 671 lifecycle.addPhaseListener((PhaseListener) ClassUtils.newInstance(listenerClassName)); 672 } catch (ClassCastException e) 673 { 674 log.error("Class " + listenerClassName + " does not implement PhaseListener"); 675 } 676 } 677 } 678 679 680 private String getLifecycleId() 681 { 682 String id = _externalContext.getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR); 683 684 if (id != null) 685 { 686 return id; 687 } 688 689 return LifecycleFactory.DEFAULT_LIFECYCLE; 690 } 691 } 692 | Popular Tags |