KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jpublish > JPublishEngine


1 /*--
2  Copyright (C) 2001-2003 Aetrion LLC.
3  All rights reserved.
4
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions
7  are met:
8
9  1. Redistributions of source code must retain the above copyright
10     notice, this list of conditions, and the following disclaimer.
11
12  2. Redistributions in binary form must reproduce the above copyright
13     notice, this list of conditions, and the disclaimer that follows
14     these conditions in the documentation and/or other materials
15     provided with the distribution.
16  3. The name "JPublish" must not be used to endorse or promote products
17     derived from this software without prior written permission. For
18     written permission, please contact info@aetrion.com.
19
20  4. Products derived from this software may not be called "JPublish", nor
21     may "JPublish" appear in their name, without prior written permission
22     from Aetrion LLC (info@aetrion.com).
23
24  In addition, the authors of this software request (but do not require)
25  that you include in the end-user documentation provided with the
26  redistribution and/or in the software itself an acknowledgement equivalent
27  to the following:
28      "This product includes software developed by
29       Aetrion LLC (http://www.aetrion.com/)."
30  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
31  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
34  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
39  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40  POSSIBILITY OF SUCH DAMAGE.
41  For more information on JPublish, please see <http://www.jpublish.org/>.
42
43  */

44 package org.jpublish;
45
46 import java.io.OutputStream JavaDoc;
47 import java.io.OutputStreamWriter JavaDoc;
48 import java.io.Writer JavaDoc;
49 import java.net.SocketException JavaDoc;
50 import java.util.Iterator JavaDoc;
51
52 import javax.servlet.http.HttpServletRequest JavaDoc;
53 import javax.servlet.http.HttpServletResponse JavaDoc;
54
55 import org.apache.commons.logging.Log;
56 import org.apache.commons.logging.LogFactory;
57 import org.jpublish.action.ActionManager;
58 import org.jpublish.component.ComponentMap;
59 import org.jpublish.exception.ExceptionHandler;
60 import org.jpublish.exception.ExceptionWrapper;
61 import org.jpublish.module.Module;
62 import org.jpublish.page.Page;
63 import org.jpublish.page.PageInstance;
64 import org.jpublish.repository.Repository;
65 import org.jpublish.repository.RepositoryWrapper;
66 import org.jpublish.resource.ResourceManager;
67 import org.jpublish.template.Template;
68 import org.jpublish.util.DateUtilities;
69 import org.jpublish.util.MessageUtilities;
70 import org.jpublish.util.NumberUtilities;
71
72 /**
73  * This class is the entry point for requests to the JPublish framework.
74  *
75  * @author Anthony Eden
76  */

77 public class JPublishEngine {
78
79     /**
80      * Description of the Field
81      */

82     public final static String JavaDoc MESSAGE_PACKAGE = "org.jpublish";
83
84     private static final Log log = LogFactory.getLog(JPublishEngine.class);
85
86     private SiteContext siteContext = null;
87     private boolean provideStaticResources = true;
88
89     /**
90      * Construct a new JPublishEngine object with the given SiteContext.
91      *
92      * @param siteContext The SiteContext
93      */

94     public JPublishEngine(SiteContext siteContext) {
95         this.siteContext = siteContext;
96         log.info("Initializing");
97         // execute startup actions
98
try {
99             ActionManager actionManager = siteContext.getActionManager();
100             actionManager.executeStartupActions();
101         } catch (Exception JavaDoc e) {
102             log.error("Error executing startup actions: " + e.getMessage());
103             e.printStackTrace();
104         }
105
106         log.info("Engine initialized.");
107     }
108
109     /**
110      * Get the SiteContext.
111      *
112      * @return The SiteContext
113      */

114     public SiteContext getSiteContext() {
115         return siteContext;
116     }
117
118     /**
119      * Get the flag which determines whether or not JPublish should handle static resources. The default value is true.
120      *
121      * @return True to provide static resources
122      */

123     public boolean getProvideStaticResources() {
124         return provideStaticResources;
125     }
126
127     /**
128      * Set the flag which determines whether or not JPublish should handle static resources.
129      *
130      * @param provideStaticResources True to provide static resources
131      */

132     public void setProvideStaticResources(boolean provideStaticResources) {
133         this.provideStaticResources = provideStaticResources;
134     }
135
136     /**
137      * Called when the Servlet is destroyed.
138      */

139     public void destroy() {
140         // execute shutdown actions
141
try {
142             ActionManager actionManager = siteContext.getActionManager();
143             actionManager.executeShutdownActions();
144         } catch (Exception JavaDoc e) {
145             log.error("Error executing shutdown actions: " + e.getMessage());
146             //e.printStackTrace();
147
}
148
149         // destroy all modules
150
try {
151             Iterator JavaDoc modules = siteContext.getModules().iterator();
152             while (modules.hasNext()) {
153                 ((Module) modules.next()).destroy();
154             }
155         } catch (Exception JavaDoc e) {
156             log.error("Error destroying modules: " + e.getMessage());
157             //e.printStackTrace();
158
}
159     }
160
161     /**
162      * Render a page. The page path is obtained through the RequestContext which is a ThreadLocal variable accessible
163      * through the static method <code>RequestContext.getRequestContext()</code> .
164      *
165      * @param out The OutputStream
166      * @throws EntityNotFoundException If the requested path is not found
167      * @throws RenderException If the engine failed to render the page
168      */

169     public void render(OutputStream JavaDoc out) throws EntityNotFoundException,
170             RenderException {
171         RequestContext context = RequestContext.getRequestContext();
172         String JavaDoc path = context.getPath();
173         if (log.isDebugEnabled()) {
174             log.debug("Rendering: " + path);
175         }
176
177         // add the DateUtilities to the context
178
context.put("dateUtilities", DateUtilities.getInstance());
179
180         // add the NumberUtilities to the context
181
context.put("numberUtilities", NumberUtilities.getInstance());
182
183         // add the MessageUtilities to the context
184
context.put("messageUtilities", MessageUtilities.getInstance());
185         
186         // add the messages log to the context
187
context.put("syslog", SiteContext.syslog);
188
189         // expose the SiteContext
190
context.put("site", siteContext);
191
192         // expose the context itself for debugging purposes
193
if (siteContext.isDebug()) {
194             context.put("context", context);
195         }
196
197         // add the repositories to the context
198
Iterator JavaDoc repositories = siteContext.getRepositories().iterator();
199         while (repositories.hasNext()) {
200             Repository repository = (Repository) repositories.next();
201             if (log.isDebugEnabled()) {
202                 log.debug("Adding " + repository.getClass().getName() + " as " +
203                         repository.getName());
204             }
205             context.put(repository.getName(), new RepositoryWrapper(repository,
206                     context));
207         }
208
209         try {
210             // execute pre-evaluation actions
211
executePreEvaluationActions(context);
212             if (context.getStopProcessing() != null) {
213                 return;
214             }
215
216             if (provideStaticResources) {
217                 // if the page is static
218
ResourceManager staticResourceManager =
219                         siteContext.getStaticResourceManager();
220                 if (log.isDebugEnabled()) {
221                     log.debug("Checking if static resource exists: " + path);
222                 }
223
224                 if (staticResourceManager.exists(path)) {
225                     // execute the global, path and parameter actions
226
executeGlobalActions(context);
227                     executePathActions(context);
228                     executeParameterActions(context);
229
230                     // load and return the static resource
231
log.debug("Loading static resource");
232
233                     // set headers
234
HttpServletResponse JavaDoc response = context.getResponse();
235                     if (response != null) {
236                         response.setDateHeader("Last-Modified",
237                                 staticResourceManager.getLastModified(path));
238                         response.setContentLength((int) staticResourceManager.getContentLength(path));
239                     }
240
241                     try {
242                         staticResourceManager.load(path, out);
243                         out.flush();
244                     } catch (SocketException JavaDoc e) {
245                         if (log.isWarnEnabled()) {
246                             log.warn("Error writing to output stream: " +
247                                     e.getMessage());
248                         }
249                     }
250                     return;
251                 } else {
252                     if (log.isDebugEnabled()) {
253                         log.debug("Static resource '" + path + "' not found");
254                     }
255                 }
256             }
257
258             // load the page
259
log.debug("Loading the page.");
260             PageInstance pageInstance =
261                     siteContext.getPageManager().getPage(path);
262             Page page = new Page(pageInstance);
263
264             if (log.isDebugEnabled()) {
265                 log.debug("Page path: " + page.getPath());
266             }
267
268             // disable reserved names temporarily
269
context.disableCheckReservedNames();
270
271             // expose the page in the context
272
context.put("page", page);
273
274             // expose components in the context
275
context.put("components", new ComponentMap(context));
276
277             // protect reserved names before executing actions
278
if (siteContext.isProtectReservedNames()) {
279                 context.enableCheckReservedNames();
280             }
281
282             // execute global, path and parameter actions
283
executeGlobalActions(context);
284             if (context.getStopProcessing() != null) {
285                 return;
286             }
287
288             executePathActions(context);
289             if (context.getStopProcessing() != null) {
290                 return;
291             }
292
293             executeParameterActions(context);
294             if (context.getStopProcessing() != null) {
295                 return;
296             }
297
298             // execute page actions
299
page.executeActions(context);
300             if (context.getStopProcessing() != null) {
301                 return;
302             }
303
304             if (context.getRedirect() != null) {
305                 return;
306             }
307
308             // get the template
309
Template template = siteContext.getTemplateManager().getTemplate(page.getFullTemplateName());
310
311             // get the Servlet writer
312
// probably need to change this to use the encoding map
313
// also may need to review how encoding is used in Velocity loader
314
String JavaDoc outputEncoding = page.getEncoding();
315             Writer JavaDoc writer = new OutputStreamWriter JavaDoc(out, outputEncoding);
316
317             // merge the template
318
if (log.isDebugEnabled()) {
319                 log.debug("Merging with template " + template.getPath());
320             }
321             template.merge(context, page, writer);
322             writer.flush();
323         } catch (EntityNotFoundException e) {
324             throw e;
325         } catch (Throwable JavaDoc e) {
326             //e.printStackTrace();
327
ExceptionWrapper error = new ExceptionWrapper(e, context);
328             Iterator JavaDoc exceptionHandlers =
329                     siteContext.getExceptionHandlers(path).iterator();
330             while (exceptionHandlers.hasNext()) {
331                 ExceptionHandler h =
332                         (ExceptionHandler) exceptionHandlers.next();
333                 h.handleException(error);
334             }
335
336             if (!error.isConsumed()) {
337                 throw new RenderException(e.getMessage(), e);
338             }
339         } finally {
340             try {
341                 if (context.getResponse().isCommitted()) {
342                     log.warn(
343                             "The response is already committed, but we're running post evaluation actions. BE CAREFUL");
344                 }
345                 executePostEvaluationActions(context);
346             } catch (Throwable JavaDoc e) {
347                 e.printStackTrace();
348                 log.error("Error executing post evaluation actions: " +
349                         e.getMessage());
350             }
351         }
352     }
353
354     /**
355      * Execute the gloabl actions for the current request.
356      *
357      * @param context The current context
358      */

359     protected void executeGlobalActions(RequestContext context) {
360         ActionManager actionManager = siteContext.getActionManager();
361         log.debug("Executing global actions.");
362         actionManager.executeGlobalActions(context);
363     }
364
365     /**
366      * Execute the path actions for the current request.
367      *
368      * @param context The current RequestContext
369      */

370     protected void executePathActions(RequestContext context) {
371         ActionManager actionManager = siteContext.getActionManager();
372         log.debug("Executing path actions, path: " + context.getPath());
373         actionManager.executePathActions(context.getPath(), context);
374     }
375
376     /**
377      * Execute the parameter actions for the current request.
378      *
379      * @param context The current RequestContext
380      */

381     protected void executeParameterActions(RequestContext context) {
382         if (!siteContext.isParameterActionsEnabled()) {
383             return;
384         }
385
386         HttpServletRequest JavaDoc request = context.getRequest();
387         if (request == null) {
388             return;
389         }
390
391         ActionManager actionManager = siteContext.getActionManager();
392         log.debug("Executing parameter actions.");
393         String JavaDoc[] actionNames = request.getParameterValues(siteContext.getActionIdentifier());
394         if (actionNames != null) {
395             for (int i = 0; i < actionNames.length; i++) {
396                 if (log.isDebugEnabled()) {
397                     log.debug("Executing paramater action: " + actionNames[i]);
398                 }
399                 actionManager.execute(actionNames[i], context);
400             }
401         }
402     }
403
404     /**
405      * Execute pre-evaluation action.
406      *
407      * @param context The current RequestContext
408      * @return True if processing should stop
409      */

410     protected boolean executePreEvaluationActions(RequestContext context) {
411         ActionManager actionManager = siteContext.getActionManager();
412         log.debug("Executing pre-evaluation actions.");
413         return actionManager.executePreEvaluationActions(context.getPath(),
414                 context);
415     }
416
417     /**
418      * Execute post-evaluation action.
419      *
420      * @param context The current RequestContext
421      * @return True if processing should stop
422      */

423     protected boolean executePostEvaluationActions(RequestContext context) {
424         ActionManager actionManager = siteContext.getActionManager();
425         log.debug("Executing post-evaluation actions.");
426         actionManager.executePostEvaluationActions(context.getPath(), context);
427         return false;
428     }
429
430 }
431
432
Popular Tags