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  
23  import javax.servlet.ServletRequest;
24  
25  import org.apache.myfaces.trinidad.skin.SkinFactory;
26  import org.apache.myfaces.trinidad.util.RequestStateMap;
27  
28  /**
29   * This defines an abstract class for the Configurator. Classes implementing
30   * this abstraction should be listed in the jar's /META-INF/services folder
31   * inside of a text file named "org.apache.myfaces.trinidad.config.Configurator".
32   * These services will then be run by Trinidad's global configurator.
33   * <p/>
34   * This abstract class allows Trinidad and various renderkits to move some of
35   * their initialization and request/response wrapping code into a configurator
36   * so that they may be handled in a container agnostic fashion supporting
37   * both Portlets and Servlets. This allows Trinidad and its various
38   * renderkits to offload some of their filter logic such as multi-part
39   * request handling (file uploads), skin initialization, and other tasks.
40   * <p/>
41   * Depending on the container,these methods may be called at different times
42   * during the actual request.  The only thing guaranteed to Configurator
43   * developers are the constraints listed below in the following methods.
44   * <p/>
45   * Use of this abstract class is encouraged, where possible, instead of using
46   * Trinidad filter services.  While configurators and filter services should
47   * be able to coexist, any services provided by the filter service will not
48   * run in a portal and should therefore be considered optional to the run of
49   * the renderkit or application if Portal compatibility is important.
50   *
51   *
52   * @version $Revision$ $Date$
53   */
54  public abstract class Configurator
55  {
56    /**
57     * Initializes the Configurator.  This method is guaranteed to run before
58     * any other method within this Configurator and will be called only once
59     * per webapp context.  This init is guaranteed to be executed before
60     * completion of the first call to the
61     * {@link javax.faces.context.FacesContextFactory#getFacesContext}
62     * is completed.
63     *
64     * <strong>Note:</strong>the ExternalContext provided to this method may not
65     * contain any of the Request/Response functionality within the external
66     * context and will NOT contain any ExternalContext wrapping provided by
67     * the {@link #getExternalContext(ExternalContext)} method.  This object
68     * is intended only to be used as a container abstraction to the native
69     * Context object.
70     *
71     * @param externalContext a mocked up external context providing access
72     *                        to the native context object.
73     */
74    public void init(ExternalContext externalContext) {}
75  
76    /**
77     * Cleans up the Configurator.  This method is guaranteed to run at some
78     * point after the Servlet or Portlet context falls out of scope and will
79     * typically be determined by the context listener.
80     */
81    public void destroy() {}
82  
83    /**
84     * This is called at the beginning of each "physical" request, sometime
85     * before {@link #getExternalContext(ExternalContext)} or
86     * {@link #endRequest(ExternalContext)}.  When using the
87     * TrinidadFilter, this will be called during filter execution, but
88     * is not guaranteed to happen until just before the creation of the
89     * Trinidad FacesContext wrapper.
90     *
91     * All Configurator services will have thier beginRequest() methods
92     * called before any calls to getExternalContext().  So any context
93     * wrapping done by this method will not happen until after the
94     * beginRequest() is called.</p>
95     *
96     * It is also important to note that the ExternalContext provided
97     * may or may not be the same as the ExternalContext provided to
98     * getExternalContext().  But it will have a valid request and response
99     * object.
100    *
101    * By contract, the {@link org.apache.myfaces.trinidad.context.RequestContext}
102    * object will be initialized and available when this method is run.
103    *
104    * @param externalContext a mocked up or life externalContext providing
105    *                        access to the native request, response, and context
106    *                        objects.
107    */
108   public void beginRequest(ExternalContext externalContext) {}
109 
110   /**
111    * Returns an ExternalContext wrapper based on the provided ExternalContext.
112    * This method is executed durring the creation of the FacesContext when using
113    * Trinidad's FacesContextFactory.  The ExternalContext returned from this
114    * method will be a part of the FacesContext that is returned from this factory
115    * but may also be wrapped be externalContext's from other services.  Especially
116    * in Portlet environments, this method may be executed multiple times after a
117    * call to {@link #beginRequest(ExternalContext)}.
118    *
119    * Please note that it is important that this method returns a wrapper of
120    * the original context, or the behavior provided by other services and by
121    * Trinidad may not function
122    *
123    * By contract, the {@link org.apache.myfaces.trinidad.context.RequestContext}
124    * object will be initialized and available when this method is run.
125    *
126    * @param externalContext the ExternalContext to wrap
127    * @return a wrapper of the ExternalContext
128    */
129   public ExternalContext getExternalContext(ExternalContext externalContext)
130   {
131     return externalContext;
132   }
133 
134   /**
135    * Executed at the end of each "physical" request.  There will be a call to
136    * endRequest after each call to {@link #beginRequest(ExternalContext)}.
137    *
138    * It is also important to note that the ExternalContext provided
139    * may or may not be the same as the ExternalContext provided to
140    * getExternalContext().  But it will have a valid request and response
141    * object.
142    *
143    * By contract, the {@link org.apache.myfaces.trinidad.context.RequestContext}
144    * object will be initialized and available when this method is run.
145    *
146    * @param externalContext the external context
147    */
148   public void endRequest(ExternalContext externalContext){}
149 
150   /**
151    * Third parties can call SkinFactory#reload. This in turn calls this method. In response the Configurators
152    * can add their skins to the specified SkinFactory. Note that this is now deprecated in favor of SkinProvider SPI.
153    * SkinProvider introduces the flexibility to create and manage external skin repositories. Each SkinProvider
154    * implementation can support its own set of Skins. Thus creating, managing and disposing Skins is the responsibility
155    * of SkinProvider. This includes reloading of skins as well.
156    * @param externalContext the external context
157    * @param factory the SkinFactory instance to which the skins can be reloaded
158    * @deprecated use SkinProvider SPI. The reloading of 'dirty' skins has to be taken care inside SkinProvider
159    * implementations.
160    * @see org.apache.myfaces.trinidad.skin.SkinProvider
161    */
162   @Deprecated
163   public void reloadSkins(ExternalContext externalContext, SkinFactory factory){}
164 
165   /**
166    * Disables Configurator services for the current request.  When this method
167    * has been called on a request, then the {{@link #beginRequest(ExternalContext)},
168    * {@link #endRequest(ExternalContext)}, and
169    * {@link #getExternalContext(ExternalContext)} methods will not be called durring
170    * a request.
171    *
172    * <strong>Note:</strong> is this method is called after the beginRequest() method,
173    * an error will be logged in the trinidad logger and the services will continue to
174    * execute.
175    *
176    * @param srq the servlet request
177    */
178   public static final void disableConfiguratorServices(ServletRequest srq)
179   {
180     RequestStateMap.getInstance(srq).put(_DISABLE_SERVICES, Boolean.TRUE);
181   }
182 
183   /**
184    * Returns <code>true</code> if the {@link #disableConfiguratorServices(ServletRequest)}
185    * has been executed on the current request and <code>false</code> if it has not.
186    *
187    * <strong>Note:</strong>it is important to understand that this method will not
188    * properly reflect if the services have actually been disabled or not.  It simply
189    * returns whether they "should" have been disabled.  If the disableConfiguratorServices
190    * was executed after the beginRequest methods have been executed, then the services
191    * will continue to function so that {{@link #getExternalContext(ExternalContext)}
192    * and {@link #endRequest(ExternalContext)} will still be called.
193    *
194    * @param ec the ExternalContext object
195    *
196    * @return a <code>boolean</code> containing <code>true</code> if the
197    *         <code>disableConfiguratorServices()</code> method has been
198    *         called and <code>false</code> if it has not.
199    */
200   protected static final boolean isConfiguratorServiceDisabled(ExternalContext ec)
201   {
202     return Boolean.TRUE.equals(RequestStateMap.getInstance(ec).get(_DISABLE_SERVICES));
203   }
204 
205   static private final String _DISABLE_SERVICES =  Configurator.class.getName()+".DISABLE_SERVICES";
206 }