KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > blojsom > dispatcher > velocity > VelocityDispatcher


1 /**
2  * Copyright (c) 2003-2006, David A. Czarnecki
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 are met:
7  *
8  * Redistributions of source code must retain the above copyright notice, this list of conditions and the
9  * following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
11  * following disclaimer in the documentation and/or other materials provided with the distribution.
12  * Neither the name of "David A. Czarnecki" and "blojsom" nor the names of its contributors may be used to
13  * endorse or promote products derived from this software without specific prior written permission.
14  * Products derived from this software may not be called "blojsom", nor may "blojsom" appear in their name,
15  * without prior written permission of David A. Czarnecki.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
18  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21  * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */

31 package org.blojsom.dispatcher.velocity;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.velocity.VelocityContext;
36 import org.apache.velocity.app.Velocity;
37 import org.apache.velocity.app.VelocityEngine;
38 import org.apache.velocity.exception.MethodInvocationException;
39 import org.apache.velocity.exception.ParseErrorException;
40 import org.apache.velocity.exception.ResourceNotFoundException;
41 import org.apache.velocity.util.EnumerationIterator;
42 import org.blojsom.dispatcher.Dispatcher;
43 import org.blojsom.blog.Blog;
44 import org.blojsom.util.BlojsomConstants;
45 import org.blojsom.util.BlojsomUtils;
46
47 import javax.servlet.ServletConfig JavaDoc;
48 import javax.servlet.ServletContext JavaDoc;
49 import javax.servlet.ServletException JavaDoc;
50 import javax.servlet.http.HttpServletRequest JavaDoc;
51 import javax.servlet.http.HttpServletResponse JavaDoc;
52 import javax.servlet.http.HttpSession JavaDoc;
53 import java.io.IOException JavaDoc;
54 import java.io.StringWriter JavaDoc;
55 import java.io.Writer JavaDoc;
56 import java.util.Map JavaDoc;
57 import java.util.Properties JavaDoc;
58
59 /**
60  * Velocity dispatcher
61  *
62  * @author David Czarnecki
63  * @since blojsom 3.0
64  * @version $Id: VelocityDispatcher.java,v 1.5 2006/07/22 03:59:27 czarneckid Exp $
65  */

66 public class VelocityDispatcher implements Dispatcher {
67
68     private Log _logger = LogFactory.getLog(VelocityDispatcher.class);
69
70     private static final String JavaDoc BLOJSOM_RENDER_TOOL = "BLOJSOM_RENDER_TOOL";
71
72     private Properties JavaDoc _velocityProperties;
73     private ServletConfig JavaDoc _servletConfig;
74     private Properties JavaDoc _blojsomProperties;
75
76     private String JavaDoc _templatesDirectory;
77     private String JavaDoc _blogsDirectory;
78
79     /**
80      * Create a new instance of the Velocity dispatcher
81      */

82     public VelocityDispatcher() {
83     }
84
85     /**
86      * Initialization method for blojsom dispatchers
87      *
88      * @throws org.blojsom.BlojsomException If there is an error initializing the dispatcher
89      */

90     public void init() throws org.blojsom.BlojsomException {
91         _templatesDirectory = _blojsomProperties.getProperty(BlojsomConstants.TEMPLATES_DIRECTORY_IP, BlojsomConstants.DEFAULT_TEMPLATES_DIRECTORY);
92         _blogsDirectory = _blojsomProperties.getProperty(BlojsomConstants.BLOGS_DIRECTORY_IP, BlojsomConstants.DEFAULT_BLOGS_DIRECTORY);
93     }
94
95     /**
96      * Set the Velocity properties for use by the dispatcher
97      *
98      * @param velocityProperties Properties for Velocity configuration
99      */

100     public void setVelocityProperties(Properties JavaDoc velocityProperties) {
101         _velocityProperties = velocityProperties;
102     }
103
104     /**
105      * Set the properties in use by blojsom
106      *
107      * @param blojsomProperties Properties in use by blojsom
108      */

109     public void setBlojsomProperties(Properties JavaDoc blojsomProperties) {
110         _blojsomProperties = blojsomProperties;
111     }
112
113     /**
114      * Set the {@link ServletConfig}
115      *
116      * @param servletConfig {@link ServletConfig}
117      */

118     public void setServletConfig(ServletConfig JavaDoc servletConfig) {
119         _servletConfig = servletConfig;
120     }
121
122     /**
123      * Populate the Velocity context with the request and session attributes
124      *
125      * @param httpServletRequest Request
126      * @param context Context
127      */

128     protected void populateVelocityContext(HttpServletRequest JavaDoc httpServletRequest, Map JavaDoc context) {
129         EnumerationIterator iterator = new EnumerationIterator(httpServletRequest.getAttributeNames());
130         while (iterator.hasNext()) {
131             Object JavaDoc key = iterator.next();
132             Object JavaDoc value = httpServletRequest.getAttribute(key.toString());
133             context.put(key, value);
134         }
135
136         HttpSession JavaDoc httpSession = httpServletRequest.getSession(false);
137         if (httpSession != null) {
138             iterator = new EnumerationIterator(httpSession.getAttributeNames());
139             while (iterator.hasNext()) {
140                 Object JavaDoc key = iterator.next();
141                 Object JavaDoc value = httpSession.getAttribute(key.toString());
142                 context.put(key, value);
143             }
144         }
145     }
146
147     /**
148      * Remove references from the Velocity context
149      *
150      * @param velocityContext {@link VelocityContext}
151      */

152     protected void destroyVelocityContext(VelocityContext velocityContext) {
153         // Make sure no objects are referenced in the context after they're finished
154
Object JavaDoc[] contextKeys = velocityContext.getKeys();
155         for (int i = 0; i < contextKeys.length; i++) {
156             Object JavaDoc contextKey = contextKeys[i];
157             velocityContext.remove(contextKey);
158         }
159     }
160
161     /**
162      * Dispatch a request and response. A context map is provided for the BlojsomServlet to pass
163      * any required information for use by the dispatcher. The dispatcher is also
164      * provided with the template for the requested flavor along with the content type for the
165      * specific flavor.
166      *
167      * @param httpServletRequest Request
168      * @param httpServletResponse Response
169      * @param blog {@link Blog}
170      * @param context Context map
171      * @param flavorTemplate Template to dispatch to for the requested flavor
172      * @param flavorContentType Content type for the requested flavor
173      * @throws java.io.IOException If there is an exception during IO
174      * @throws javax.servlet.ServletException If there is an exception in dispatching the request
175      */

176     public void dispatch(HttpServletRequest JavaDoc httpServletRequest, HttpServletResponse JavaDoc httpServletResponse, Blog blog, Map JavaDoc context, String JavaDoc flavorTemplate, String JavaDoc flavorContentType) throws IOException JavaDoc, ServletException JavaDoc {
177         httpServletResponse.setContentType(flavorContentType);
178         ServletContext JavaDoc servletContext = _servletConfig.getServletContext();
179
180         // Create the Velocity Engine
181
VelocityEngine velocityEngine = new VelocityEngine();
182         try {
183             Properties JavaDoc updatedProperties = (Properties JavaDoc) _velocityProperties.clone();
184             updatedProperties.put(VelocityEngine.FILE_RESOURCE_LOADER_PATH, servletContext.getRealPath(BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY + _blogsDirectory + blog.getBlogId() + _templatesDirectory) + ", " + servletContext.getRealPath(BlojsomConstants.DEFAULT_CONFIGURATION_BASE_DIRECTORY + _templatesDirectory));
185             velocityEngine.init(updatedProperties);
186         } catch (Exception JavaDoc e) {
187             if (_logger.isErrorEnabled()) {
188                 _logger.error(e);
189             }
190
191             return;
192         }
193
194         Writer JavaDoc responseWriter = httpServletResponse.getWriter();
195         String JavaDoc flavorTemplateForPage = null;
196         String JavaDoc pageParameter = BlojsomUtils.getRequestValue(BlojsomConstants.PAGE_PARAM, httpServletRequest, true);
197
198         if (pageParameter != null) {
199             flavorTemplateForPage = BlojsomUtils.getTemplateForPage(flavorTemplate, pageParameter);
200
201             if (_logger.isDebugEnabled()) {
202                 _logger.debug("Retrieved template for page: " + flavorTemplateForPage);
203             }
204         }
205
206         // Setup the VelocityContext
207
populateVelocityContext(httpServletRequest, context);
208         VelocityContext velocityContext = new VelocityContext(context);
209         velocityContext.put(BLOJSOM_RENDER_TOOL, new BlojsomRenderTool(velocityEngine, velocityContext));
210
211         if (flavorTemplateForPage != null) {
212             // Try and look for the flavor page template for the individual user
213
if (!velocityEngine.templateExists(flavorTemplateForPage)) {
214                 if (_logger.isErrorEnabled()) {
215                     _logger.error("Could not find flavor page template for user: " + flavorTemplateForPage);
216                 }
217
218                 responseWriter.flush();
219                 destroyVelocityContext(velocityContext);
220
221                 return;
222             } else {
223                 try {
224                     velocityEngine.mergeTemplate(flavorTemplateForPage, BlojsomConstants.UTF8, velocityContext, responseWriter);
225                 } catch (Exception JavaDoc e) {
226                     if (_logger.isErrorEnabled()) {
227                         _logger.error(e);
228                     }
229
230                     responseWriter.flush();
231                     destroyVelocityContext(velocityContext);
232
233                     return;
234                 }
235             }
236
237             _logger.debug("Dispatched to flavor page template: " + flavorTemplateForPage);
238         } else {
239             // Otherwise, fallback and look for the flavor template for the individual user
240
if (!velocityEngine.templateExists(flavorTemplate)) {
241                 if (_logger.isErrorEnabled()) {
242                     _logger.error("Could not find flavor template for user: " + flavorTemplate);
243                 }
244
245                 responseWriter.flush();
246                 destroyVelocityContext(velocityContext);
247
248                 return;
249             } else {
250                 try {
251                     velocityEngine.mergeTemplate(flavorTemplate, BlojsomConstants.UTF8, velocityContext, responseWriter);
252                 } catch (Exception JavaDoc e) {
253                     if (_logger.isErrorEnabled()) {
254                         _logger.error(e);
255                     }
256
257                     responseWriter.flush();
258                     destroyVelocityContext(velocityContext);
259
260                     return;
261                 }
262             }
263
264             if (_logger.isDebugEnabled()) {
265                 _logger.debug("Dispatched to flavor template: " + flavorTemplate);
266             }
267         }
268
269         responseWriter.flush();
270         destroyVelocityContext(velocityContext);
271     }
272
273     /**
274      * Blojsom render tool mimics the functionality of the Velocity render tool to parse VTL markup added to a
275      * template
276      */

277     public class BlojsomRenderTool {
278
279         private static final String JavaDoc LOG_TAG = "BlojsomRenderTool";
280
281         private VelocityEngine _velocityEngine;
282         private VelocityContext _velocityContext;
283
284         /**
285          * Create a new instance of the render tool
286          *
287          * @param velocityEngine {@link VelocityEngine}
288          * @param velocityContext {@link VelocityContext}
289          */

290         public BlojsomRenderTool(VelocityEngine velocityEngine, VelocityContext velocityContext) {
291             _velocityEngine = velocityEngine;
292             _velocityContext = velocityContext;
293         }
294
295         /**
296          * Evaluate a string containing VTL markup
297          *
298          * @param template VTL markup
299          * @return Processed VTL or <code>null</code> if an error in evaluation
300          */

301         public String JavaDoc evaluate(String JavaDoc template) {
302             if (BlojsomUtils.checkNullOrBlank(template)) {
303                 return null;
304             }
305
306             StringWriter JavaDoc sw = new StringWriter JavaDoc();
307             boolean success = false;
308
309             try {
310                 if (_velocityEngine == null) {
311                     success = Velocity.evaluate(_velocityContext, sw, LOG_TAG, template);
312                 } else {
313                     success = _velocityEngine.evaluate(_velocityContext, sw, LOG_TAG, template);
314                 }
315             } catch (ParseErrorException e) {
316                 if (_logger.isErrorEnabled()) {
317                     _logger.error(e);
318                 }
319             } catch (MethodInvocationException e) {
320                 if (_logger.isErrorEnabled()) {
321                     _logger.error(e);
322                 }
323             } catch (ResourceNotFoundException e) {
324                 if (_logger.isErrorEnabled()) {
325                     _logger.error(e);
326                 }
327             } catch (IOException JavaDoc e) {
328                 if (_logger.isErrorEnabled()) {
329                     _logger.error(e);
330                 }
331             }
332
333             if (success) {
334                 return sw.toString();
335             }
336
337             return null;
338         }
339     }
340 }
341
Popular Tags