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 }