KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > tiles > TilesRequestProcessor


1 /*
2  * $Id: TilesRequestProcessor.java 164703 2005-04-26 01:28:13Z niallp $
3  *
4  * Copyright 1999-2005 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * 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, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 package org.apache.struts.tiles;
20
21 import java.io.IOException JavaDoc;
22
23 import javax.servlet.ServletException JavaDoc;
24 import javax.servlet.http.HttpServletRequest JavaDoc;
25 import javax.servlet.http.HttpServletResponse JavaDoc;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.struts.action.ActionServlet;
30 import org.apache.struts.action.RequestProcessor;
31 import org.apache.struts.config.ForwardConfig;
32 import org.apache.struts.config.ModuleConfig;
33
34 /**
35  * <p><strong>RequestProcessor</strong> contains the processing logic that
36  * the Struts controller servlet performs as it receives each servlet request
37  * from the container.</p>
38  * <p>This processor subclasses the Struts RequestProcessor in order to intercept calls to forward
39  * or include. When such calls are done, the Tiles processor checks if the specified URI
40  * is a definition name. If true, the definition is retrieved and included. If
41  * false, the original URI is included or a forward is performed.
42  * <p>
43  * Actually, catching is done by overloading the following methods:
44  * <ul>
45  * <li>{@link #processForwardConfig(HttpServletRequest,HttpServletResponse,ForwardConfig)}</li>
46  * <li>{@link #internalModuleRelativeForward(String, HttpServletRequest , HttpServletResponse)}</li>
47  * <li>{@link #internalModuleRelativeInclude(String, HttpServletRequest , HttpServletResponse)}</li>
48  * </ul>
49  * </p>
50  * @since Struts 1.1
51  */

52 public class TilesRequestProcessor extends RequestProcessor {
53
54     /**
55      * Definitions factory.
56      */

57     protected DefinitionsFactory definitionsFactory = null;
58
59     /**
60      * Commons Logging instance.
61      */

62     protected static Log log = LogFactory.getLog(TilesRequestProcessor.class);
63
64     /**
65      * Initialize this request processor instance.
66      *
67      * @param servlet The ActionServlet we are associated with.
68      * @param moduleConfig The ModuleConfig we are associated with.
69      * @throws ServletException If an error occurs during initialization.
70      */

71     public void init(ActionServlet servlet, ModuleConfig moduleConfig)
72         throws ServletException JavaDoc {
73
74         super.init(servlet, moduleConfig);
75         this.initDefinitionsMapping();
76     }
77
78     /**
79      * Read component instance mapping configuration file.
80      * This is where we read files properties.
81      */

82     protected void initDefinitionsMapping() throws ServletException JavaDoc {
83         // Retrieve and set factory for this modules
84
definitionsFactory =
85             (
86                 (TilesUtilStrutsImpl) TilesUtil
87                     .getTilesUtil())
88                     .getDefinitionsFactory(
89                 getServletContext(),
90                 moduleConfig);
91
92         if (definitionsFactory == null) { // problem !
93

94             log.info(
95                 "Definition Factory not found for module '"
96                     + moduleConfig.getPrefix()
97                     + "'. "
98                     + "Have you declared the appropriate plugin in struts-config.xml ?");
99
100             return;
101         }
102
103         log.info(
104             "Tiles definition factory found for request processor '"
105                 + moduleConfig.getPrefix()
106                 + "'.");
107
108     }
109
110     /**
111      * Process a Tile definition name.
112      * This method tries to process the parameter <code>definitionName</code> as a definition name.
113      * It returns <code>true</code> if a definition has been processed, or <code>false</code> otherwise.
114      * Parameter <code>contextRelative</code> is not used in this implementation.
115      *
116      * @param definitionName Definition name to insert.
117      * @param contextRelative Is the definition marked contextRelative ?
118      * @param request Current page request.
119      * @param response Current page response.
120      * @return <code>true</code> if the method has processed uri as a definition name, <code>false</code> otherwise.
121      */

122     protected boolean processTilesDefinition(
123         String JavaDoc definitionName,
124         boolean contextRelative,
125         HttpServletRequest JavaDoc request,
126         HttpServletResponse JavaDoc response)
127         throws IOException JavaDoc, ServletException JavaDoc {
128
129         // Do we do a forward (original behavior) or an include ?
130
boolean doInclude = false;
131
132         // Controller associated to a definition, if any
133
Controller controller = null;
134
135         // Computed uri to include
136
String JavaDoc uri = null;
137
138         ComponentContext tileContext = null;
139
140         try {
141             // Get current tile context if any.
142
// If context exist, we will do an include
143
tileContext = ComponentContext.getContext(request);
144             doInclude = (tileContext != null);
145             ComponentDefinition definition = null;
146
147             // Process tiles definition names only if a definition factory exist,
148
// and definition is found.
149
if (definitionsFactory != null) {
150                 // Get definition of tiles/component corresponding to uri.
151
try {
152                     definition =
153                         definitionsFactory.getDefinition(
154                             definitionName,
155                             request,
156                             getServletContext());
157                 } catch (NoSuchDefinitionException ex) {
158                     // Ignore not found
159
log.debug("NoSuchDefinitionException " + ex.getMessage());
160                 }
161                 if (definition != null) { // We have a definition.
162
// We use it to complete missing attribute in context.
163
// We also get uri, controller.
164
uri = definition.getPath();
165                     controller = definition.getOrCreateController();
166
167                     if (tileContext == null) {
168                         tileContext =
169                             new ComponentContext(definition.getAttributes());
170                         ComponentContext.setContext(tileContext, request);
171
172                     } else {
173                         tileContext.addMissing(definition.getAttributes());
174                     }
175                 }
176             }
177
178             // Process definition set in Action, if any.
179
definition = DefinitionsUtil.getActionDefinition(request);
180             if (definition != null) { // We have a definition.
181
// We use it to complete missing attribute in context.
182
// We also overload uri and controller if set in definition.
183
if (definition.getPath() != null) {
184                     uri = definition.getPath();
185                 }
186
187                 if (definition.getOrCreateController() != null) {
188                     controller = definition.getOrCreateController();
189                 }
190
191                 if (tileContext == null) {
192                     tileContext =
193                         new ComponentContext(definition.getAttributes());
194                     ComponentContext.setContext(tileContext, request);
195                 } else {
196                     tileContext.addMissing(definition.getAttributes());
197                 }
198             }
199
200         } catch (java.lang.InstantiationException JavaDoc ex) {
201
202             log.error("Can't create associated controller", ex);
203
204             throw new ServletException JavaDoc(
205                 "Can't create associated controller",
206                 ex);
207         } catch (DefinitionsFactoryException ex) {
208             throw new ServletException JavaDoc(ex);
209         }
210
211         // Have we found a definition ?
212
if (uri == null) {
213             return false;
214         }
215
216         // Execute controller associated to definition, if any.
217
if (controller != null) {
218             try {
219                 controller.execute(
220                     tileContext,
221                     request,
222                     response,
223                     getServletContext());
224                     
225             } catch (Exception JavaDoc e) {
226                 throw new ServletException JavaDoc(e);
227             }
228         }
229
230         // If request comes from a previous Tile, do an include.
231
// This allows to insert an action in a Tile.
232
if (log.isDebugEnabled()) {
233             log.debug("uri=" + uri + " doInclude=" + doInclude);
234         }
235         
236         if (doInclude) {
237             doInclude(uri, request, response);
238         } else {
239             doForward(uri, request, response); // original behavior
240
}
241
242         return true;
243     }
244
245     /**
246      * Do a forward using request dispatcher.
247      * Uri is a valid uri. If response has already been commited, do an include
248      * instead.
249      * @param uri Uri or Definition name to forward.
250      * @param request Current page request.
251      * @param response Current page response.
252      */

253     protected void doForward(
254         String JavaDoc uri,
255         HttpServletRequest JavaDoc request,
256         HttpServletResponse JavaDoc response)
257         throws IOException JavaDoc, ServletException JavaDoc {
258             
259         if (response.isCommitted()) {
260             this.doInclude(uri, request, response);
261             
262         } else {
263             super.doForward(uri, request, response);
264         }
265     }
266
267     /**
268      * Overloaded method from Struts' RequestProcessor.
269      * Forward or redirect to the specified destination by the specified
270      * mechanism.
271      * This method catches the Struts' actionForward call. It checks if the
272      * actionForward is done on a Tiles definition name. If true, process the
273      * definition and insert it. If false, call the original parent's method.
274      * @param request The servlet request we are processing.
275      * @param response The servlet response we are creating.
276      * @param forward The ActionForward controlling where we go next.
277      *
278      * @exception IOException if an input/output error occurs.
279      * @exception ServletException if a servlet exception occurs.
280      */

281     protected void processForwardConfig(
282         HttpServletRequest JavaDoc request,
283         HttpServletResponse JavaDoc response,
284         ForwardConfig forward)
285         throws IOException JavaDoc, ServletException JavaDoc {
286             
287         // Required by struts contract
288
if (forward == null) {
289             return;
290         }
291
292         if (log.isDebugEnabled()) {
293             log.debug(
294                 "processForwardConfig("
295                     + forward.getPath()
296                     + ", "
297                     + forward.getContextRelative()
298                     + ")");
299         }
300         
301         // Try to process the definition.
302
if (processTilesDefinition(forward.getPath(),
303             forward.getContextRelative(),
304             request,
305             response)) {
306             if (log.isDebugEnabled()) {
307                 log.debug(
308                     " '" + forward.getPath() + "' - processed as definition");
309             }
310             return;
311         }
312         
313         if (log.isDebugEnabled()) {
314             log.debug(" '" + forward.getPath() + "' - processed as uri");
315         }
316         
317         // forward doesn't contain a definition, let parent do processing
318
super.processForwardConfig(request, response, forward);
319     }
320
321     /**
322      * Catch the call to a module relative forward.
323      * If the specified uri is a tiles definition name, insert it.
324      * Otherwise, parent processing is called.
325      * Do a module relative forward to specified uri using request dispatcher.
326      * Uri is relative to the current module. The real uri is computed by
327      * prefixing the module name.
328      * <strong>This method is used internally and is not part of the public
329      * API. It is advised to not use it in subclasses.</strong>
330      * @param uri Module-relative URI to forward to.
331      * @param request Current page request.
332      * @param response Current page response.
333      * @since Struts 1.1
334      */

335     protected void internalModuleRelativeForward(
336         String JavaDoc uri,
337         HttpServletRequest JavaDoc request,
338         HttpServletResponse JavaDoc response)
339         throws IOException JavaDoc, ServletException JavaDoc {
340             
341         if (processTilesDefinition(uri, false, request, response)) {
342             return;
343         }
344
345         super.internalModuleRelativeForward(uri, request, response);
346     }
347
348     /**
349      * Do a module relative include to specified uri using request dispatcher.
350      * Uri is relative to the current module. The real uri is computed by
351      * prefixing the module name.
352      * <strong>This method is used internally and is not part of the public
353      * API. It is advised to not use it in subclasses.</strong>
354      * @param uri Module-relative URI to forward to.
355      * @param request Current page request.
356      * @param response Current page response.
357      * @since Struts 1.1
358      */

359     protected void internalModuleRelativeInclude(
360         String JavaDoc uri,
361         HttpServletRequest JavaDoc request,
362         HttpServletResponse JavaDoc response)
363         throws IOException JavaDoc, ServletException JavaDoc {
364             
365         if (processTilesDefinition(uri, false, request, response)) {
366             return;
367         }
368
369         super.internalModuleRelativeInclude(uri, request, response);
370     }
371
372     /**
373      * Get associated definition factory.
374      */

375     public DefinitionsFactory getDefinitionsFactory() {
376         return definitionsFactory;
377     }
378
379 }
380
Popular Tags