001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.faces.context;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038:
039: import javax.faces.FacesException;
040: import javax.faces.context.FacesContext;
041: import javax.faces.context.FacesContextFactory;
042: import javax.faces.lifecycle.Lifecycle;
043: import javax.servlet.ServletContext;
044: import javax.servlet.ServletRequest;
045: import java.lang.reflect.Method;
046:
047: /**
048: * This is the ICEfaces implementation of the FacesContextFactory. We take
049: * advantage of the delegation design provided by the JSF spec to create our
050: * factory with a delegate factory. We then check to see if requests are being
051: * handled by one of our PersistentFaces classes. This is accomplished by
052: * inserting a known attribute into the request. If the attribute is present,
053: * then we know that the request for a FacesContext originated from an ICEfaces
054: * servlet (or portlet). If not, we delegate the call to the "parent" factory.
055: * This allows us to run in "plain" Faces mode while still making use of our own
056: * ViewHandler and renders.
057: */
058: public class FacesContextFactoryImpl extends FacesContextFactory {
059:
060: protected static Log log = LogFactory
061: .getLog(FacesContextFactoryImpl.class);
062:
063: public static final String SERVLET_KEY = "servletkey";
064: public static final String PERSISTENT = "persistent";
065:
066: private FacesContextFactory delegate;
067:
068: public FacesContextFactoryImpl() {
069:
070: }
071:
072: public FacesContextFactoryImpl(FacesContextFactory delegate) {
073: this .delegate = delegate;
074: }
075:
076: public FacesContext getFacesContext(Object context, Object request,
077: Object response, Lifecycle lifecycle) throws FacesException {
078:
079: // If anything is null, we're not good to go.
080: if (context == null || request == null || response == null
081: || lifecycle == null) {
082: throw new NullPointerException();
083: }
084:
085: //If ICEfaces should not be handling this, then delegate the responsibility of
086: //providing the FacesContext to the delegated FacesContextFactory.
087: if (shouldDelegate(request)) {
088: return delegate.getFacesContext(context, request, response,
089: lifecycle);
090: }
091:
092: // Create a new external context that wraps up the context for the environment that
093: // we're currently running in as well as the request and response objects. The
094: // BridgeExternalContext is responsible for differentiating the type of environment
095: // and delegating the calls appropriately.
096: if (context instanceof ServletContext) {
097: return null;
098: } else {
099: throw new IllegalStateException("Unknown environment");
100: }
101: }
102:
103: private boolean shouldDelegate(Object request) {
104: if (delegate == null) {
105: return false;
106: }
107: //We must run without portlet.jar being present, so cannot use
108: //instanceof PortletRequest
109: //if (request instanceof PortletRequest) {
110: Method getAttributeMethod = null;
111: Class portletRequestClass = null;
112: try {
113: portletRequestClass = Class
114: .forName("javax.portlet.PortletRequest");
115: getAttributeMethod = portletRequestClass.getMethod(
116: "getAttribute", new Class[] { String.class });
117: } catch (Throwable t) {
118: if (log.isDebugEnabled()) {
119: log.debug("Portlet classes not available");
120: }
121: }
122:
123: if ((null != portletRequestClass)
124: && (portletRequestClass.isInstance(request))) {
125: //now use our reflectively obtained method to get another attribute
126: String portletType = null;
127: try {
128: portletType = (String) getAttributeMethod.invoke(
129: request, new Object[] { SERVLET_KEY });
130: } catch (Exception e) {
131: if (log.isWarnEnabled()) {
132: log.warn(
133: "Reflection failure: request.getAttribute",
134: e);
135: }
136: }
137:
138: if (portletType != null
139: && portletType.equalsIgnoreCase(PERSISTENT)) {
140: return false;
141: }
142: } else if (request instanceof ServletRequest) {
143: String servletType = (String) ((ServletRequest) request)
144: .getAttribute(SERVLET_KEY);
145: if (servletType != null
146: && servletType.equalsIgnoreCase(PERSISTENT)) {
147: return false;
148: }
149: }
150:
151: return true;
152: }
153:
154: }
|