View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.trinidad.config;
20  
21  import javax.faces.context.ExternalContext;
22  import javax.servlet.ServletRequest;
23  
24  import org.apache.myfaces.trinidad.util.RequestStateMap;
25  
26  /**
27   * This defines an abstract class for the Configurator. Classes implementing
28   * this abstraction should be listed in the jar's /META-INF/services folder
29   * inside of a text file named "org.apache.myfaces.trinidad.config.Configurator".
30   * These services will then be run by Trinidad's global configurator.
31   * <p/>
32   * This abstract class allows Trinidad and various renderkits to move some of
33   * their initialization and request/response wrapping code into a configurator
34   * so that they may be handled in a container agnostic fashion supporting
35   * both Portlets and Servlets. This allows Trinidad and its various
36   * renderkits to offload some of their filter logic such as multi-part
37   * request handling (file uploads), skin initialization, and other tasks.
38   * <p/>
39   * Depending on the container,these methods may be called at different times
40   * during the actual request.  The only thing guaranteed to Configurator
41   * developers are the constraints listed below in the following methods.
42   * <p/>
43   * Use of this abstract class is encouraged, where possible, instead of using
44   * Trinidad filter services.  While configurators and filter services should
45   * be able to coexist, any services provided by the filter service will not
46   * run in a portal and should therefore be considered optional to the run of
47   * the renderkit or application if Portal compatibility is important.
48   *
49   *
50   * @version $Revision$ $Date$
51   */
52  public abstract class Configurator
53  {
54    /**
55     * Initializes the Configurator.  This method is guaranteed to run before
56     * any other method within this Configurator and will be called only once
57     * per webapp context.  This init is guaranteed to be executed before
58     * completion of the first call to the
59     * {@link javax.faces.context.FacesContextFactory#getFacesContext}
60     * is completed.
61     *
62     * <strong>Note:</strong>the ExternalContext provided to this method may not
63     * contain any of the Request/Response functionality within the external
64     * context and will NOT contain any ExternalContext wrapping provided by
65     * the {@link #getExternalContext(ExternalContext)} method.  This object
66     * is intended only to be used as a container abstraction to the native
67     * Context object.
68     *
69     * @param externalContext a mocked up external context providing access
70     *                        to the native context object.
71     */
72    public void init(ExternalContext externalContext) {}
73  
74    /**
75     * Cleans up the Configurator.  This method is guaranteed to run at some
76     * point after the Servlet or Portlet context falls out of scope and will
77     * typically be determined by the context listener.
78     */
79    public void destroy() {}
80  
81    /**
82     * This is called at the beginning of each "physical" request, sometime
83     * before {@link #getExternalContext(ExternalContext)} or
84     * {@link #endRequest(ExternalContext)}.  When using the
85     * TrinidadFilter, this will be called during filter execution, but
86     * is not guaranteed to happen until just before the creation of the
87     * Trinidad FacesContext wrapper.
88     *
89     * All Configurator services will have thier beginRequest() methods
90     * called before any calls to getExternalContext().  So any context
91     * wrapping done by this method will not happen until after the
92     * beginRequest() is called.</p>
93     *
94     * It is also important to note that the ExternalContext provided
95     * may or may not be the same as the ExternalContext provided to
96     * getExternalContext().  But it will have a valid request and response
97     * object.
98     *
99     * By contract, the {@link org.apache.myfaces.trinidad.context.RequestContext}
100    * object will be initialized and available when this method is run.
101    *
102    * @param externalContext a mocked up or life externalContext providing
103    *                        access to the native request, response, and context
104    *                        objects.
105    */
106   public void beginRequest(ExternalContext externalContext) {}
107 
108   /**
109    * Returns an ExternalContext wrapper based on the provided ExternalContext.
110    * This method is executed durring the creation of the FacesContext when using
111    * Trinidad's FacesContextFactory.  The ExternalContext returned from this
112    * method will be a part of the FacesContext that is returned from this factory
113    * but may also be wrapped be externalContext's from other services.  Especially
114    * in Portlet environments, this method may be executed multiple times after a
115    * call to {@link #beginRequest(ExternalContext)}.
116    *
117    * Please note that it is important that this method returns a wrapper of
118    * the original context, or the behavior provided by other services and by
119    * Trinidad may not function
120    *
121    * By contract, the {@link org.apache.myfaces.trinidad.context.RequestContext}
122    * object will be initialized and available when this method is run.
123    *
124    * @param externalContext the ExternalContext to wrap
125    * @return a wrapper of the ExternalContext
126    */
127   public ExternalContext getExternalContext(ExternalContext externalContext)
128   {
129     return externalContext;
130   }
131 
132   /**
133    * Executed at the end of each "physical" request.  There will be a call to
134    * endRequest after each call to {@link #beginRequest(ExternalContext)}.
135    *
136    * It is also important to note that the ExternalContext provided
137    * may or may not be the same as the ExternalContext provided to
138    * getExternalContext().  But it will have a valid request and response
139    * object.
140    *
141    * By contract, the {@link org.apache.myfaces.trinidad.context.RequestContext}
142    * object will be initialized and available when this method is run.
143    *
144    * @param externalContext the external context
145    */
146   public void endRequest(ExternalContext externalContext){}
147 
148   /**
149    * Disables Configurator services for the current request.  When this method
150    * has been called on a request, then the {{@link #beginRequest(ExternalContext)},
151    * {@link #endRequest(ExternalContext)}, and
152    * {@link #getExternalContext(ExternalContext)} methods will not be called durring
153    * a request.
154    *
155    * <strong>Note:</strong> is this method is called after the beginRequest() method,
156    * an error will be logged in the trinidad logger and the services will continue to
157    * execute.
158    *
159    * @param srq the servlet request
160    */
161   public static final void disableConfiguratorServices(ServletRequest srq)
162   {
163     RequestStateMap.getInstance(srq).put(_DISABLE_SERVICES, Boolean.TRUE);
164   }
165 
166   /**
167    * Returns <code>true</code> if the {@link #disableConfiguratorServices(ServletRequest)}
168    * has been executed on the current request and <code>false</code> if it has not.
169    *
170    * <strong>Note:</strong>it is important to understand that this method will not
171    * properly reflect if the services have actually been disabled or not.  It simply
172    * returns whether they "should" have been disabled.  If the disableConfiguratorServices
173    * was executed after the beginRequest methods have been executed, then the services
174    * will continue to function so that {{@link #getExternalContext(ExternalContext)}
175    * and {@link #endRequest(ExternalContext)} will still be called.
176    *
177    * @param ec the ExternalContext object
178    *
179    * @return a <code>boolean</code> containing <code>true</code> if the
180    *         <code>disableConfiguratorServices()</code> method has been
181    *         called and <code>false</code> if it has not.
182    */
183   protected static final boolean isConfiguratorServiceDisabled(ExternalContext ec)
184   {
185     return Boolean.TRUE.equals(RequestStateMap.getInstance(ec).get(_DISABLE_SERVICES));
186   }
187 
188   static private final String _DISABLE_SERVICES =  Configurator.class.getName()+".DISABLE_SERVICES";
189 }