/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.jsf.webapp;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.*;
import javax.faces.*;
import javax.faces.application.*;
import javax.faces.event.*;
import javax.faces.lifecycle.*;
import javax.faces.webapp.*;
import javax.servlet.*;
import com.caucho.config.*;
import com.caucho.jsf.application.*;
import com.caucho.jsf.cfg.*;
import com.caucho.jsf.dev.*;
import com.caucho.vfs.*;
import com.caucho.server.webapp.WebApp;
import com.caucho.server.dispatch.ServletMapping;
public class FacesServletImpl extends GenericServlet
{
private static final Logger log
= Logger.getLogger(FacesServletImpl.class.getName());
private static final String FACES_SCHEMA
= "com/caucho/jsf/cfg/jsf.rnc";
private ConfigException _configException;
private ArrayList<PhaseListener> _phaseListenerList
= new ArrayList<PhaseListener>();
public FacesServletImpl()
{
}
public void init(ServletConfig config)
throws ServletException
{
initFactory(FactoryFinder.APPLICATION_FACTORY,
"com.caucho.jsf.application.ApplicationFactoryImpl");
initFactory(FactoryFinder.LIFECYCLE_FACTORY,
"com.caucho.jsf.lifecycle.LifecycleFactoryImpl");
initFactory(FactoryFinder.RENDER_KIT_FACTORY,
"com.caucho.jsf.render.RenderKitFactoryImpl");
initFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
"com.caucho.jsf.context.FacesContextFactoryImpl");
ApplicationFactory appFactory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
Application app = appFactory.getApplication();
if (app == null) {
app = new ApplicationImpl();
appFactory.setApplication(app);
}
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try {
Enumeration e = loader.getResources("META-INF/faces-config.xml");
while (e != null && e.hasMoreElements()) {
URL url = (URL) e.nextElement();
initPath(app, Vfs.lookup(url.toString()));
}
} catch (IOException e) {
throw ConfigException.create(e);
}
String path = config.getServletContext().getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
String []paths = null;
if (path != null)
paths = path.split("\\s*,\\s*");
for (int i = 0; paths != null && i < paths.length; i++)
initPath(app, Vfs.lookup("./" + paths[i]));
initPath(app, Vfs.lookup("WEB-INF/faces-config.xml"));
if (app.getViewHandler() == null)
app.setViewHandler(new JspViewHandler());
JsfPropertyGroup jsfPropertyGroup = WebApp.getLocal().getJsf();
if (app.getStateManager() == null) {
SessionStateManager stateManager = new SessionStateManager();
if (jsfPropertyGroup != null)
stateManager.setStateSerializationMethod(
jsfPropertyGroup.getStateSerializationMethod());
app.setStateManager(stateManager);
}
LifecycleFactory lifecycleFactory = (LifecycleFactory)
FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
PhaseListener developerAidListener = null;
if (jsfPropertyGroup != null && jsfPropertyGroup.isEnableDeveloperAid()) {
developerAidListener = new JsfDeveloperAid();
//will use Servlet 3.0
ServletMapping servletMapping = WebApp.getCurrent()
.createServletMapping();
servletMapping.addURLPattern("/caucho.jsf.developer.aid");
servletMapping.setServletClass(JsfDeveloperAidServlet.class.getName());
WebApp.getCurrent().addServletMapping(servletMapping);
}
Iterator iter = lifecycleFactory.getLifecycleIds();
while (iter.hasNext()) {
Lifecycle lifecycle
= lifecycleFactory.getLifecycle((String) iter.next());
if (developerAidListener != null)
lifecycle.addPhaseListener(developerAidListener);
for (PhaseListener listener : _phaseListenerList) {
lifecycle.addPhaseListener(listener);
}
}
}
private static void initFactory(String factoryName, String defaultName)
{
Object factoryObj = null;
String factory;
try {
factoryObj = FactoryFinder.getFactory(factoryName);
} catch (FacesException e) {
}
if (factoryObj == null) {
FactoryFinder.setFactory(factoryName, defaultName);
factory = getServiceFactory(factoryName);
if (factory != null && ! "".equals(factory))
FactoryFinder.setFactory(factoryName, factory);
}
}
private static String getServiceFactory(String factoryName)
{
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("META-INF/services/" + factoryName);
try {
if (is != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
if (line != null) {
if (line.indexOf('#') >= 0)
line = line.substring(0, line.indexOf('#'));
return line.trim();
}
}
} catch (Exception e) {
log.log(Level.WARNING, e.toString(), e);
} finally {
is.close();
}
} catch (Exception e) {
}
return null;
}
private void initPath(Application app, Path facesPath)
throws ServletException
{
if (facesPath.canRead() && ! facesPath.isDirectory()) {
try {
FacesConfig facesConfig = new FacesConfig();
Config config = new Config();
config.setEL(false);
config.configure(facesConfig, facesPath, FACES_SCHEMA);
if (app instanceof ApplicationImpl) {
ApplicationImpl appImpl = (ApplicationImpl) app;
// jsf/4409
NavigationHandlerImpl navigationHandler
= appImpl.getDefaultNavigationHandler();
List<NavigationRule> navigationRules
= facesConfig.getNavigationRules();
for (NavigationRule navigationRule : navigationRules) {
navigationHandler.addRule(navigationRule);
}
facesConfig.configure(appImpl);
facesConfig.configurePhaseListeners(_phaseListenerList);
for (ManagedBeanConfig bean : facesConfig.getManagedBeans()) {
appImpl.addManagedBean(bean.getName(), bean);
}
ApplicationConfig appConfig = facesConfig.getApplication();
if (appConfig != null) {
appConfig.configure(appImpl);
for (ResourceBundleConfig bundle
: appConfig.getResourceBundleList()) {
appImpl.addResourceBundle(bundle.getVar(), bundle);
}
}
}
} catch (ConfigException e) {
_configException = e;
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new ServletException(e);
}
}
}
public void service(ServletRequest request,
ServletResponse response)
throws IOException, ServletException
{
throw new UnsupportedOperationException();
}
public void destroy()
{
}
}