KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > blojsom > servlet > BlojsomServlet


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.servlet;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.blojsom.blog.Blog;
36 import org.blojsom.blog.Category;
37 import org.blojsom.blog.Comment;
38 import org.blojsom.blog.Entry;
39 import org.blojsom.dispatcher.Dispatcher;
40 import org.blojsom.fetcher.Fetcher;
41 import org.blojsom.fetcher.FetcherException;
42 import org.blojsom.plugin.Plugin;
43 import org.blojsom.plugin.PluginException;
44 import org.blojsom.util.BlojsomConstants;
45 import org.blojsom.util.BlojsomUtils;
46 import org.springframework.beans.BeansException;
47 import org.springframework.context.support.ClassPathXmlApplicationContext;
48
49 import javax.servlet.ServletConfig JavaDoc;
50 import javax.servlet.ServletException JavaDoc;
51 import javax.servlet.http.HttpServlet JavaDoc;
52 import javax.servlet.http.HttpServletRequest JavaDoc;
53 import javax.servlet.http.HttpServletResponse JavaDoc;
54 import java.io.IOException JavaDoc;
55 import java.io.UnsupportedEncodingException JavaDoc;
56 import java.util.Date JavaDoc;
57 import java.util.HashMap JavaDoc;
58 import java.util.Map JavaDoc;
59 import java.util.Properties JavaDoc;
60
61 /**
62  * BlojsomServlet
63  *
64  * @author David Czarnecki
65  * @version $Id: BlojsomServlet.java,v 1.10 2006/09/26 02:55:24 czarneckid Exp $
66  * @since blojsom 3.0
67  */

68 public class BlojsomServlet extends HttpServlet JavaDoc {
69
70     protected Log _logger = LogFactory.getLog(BlojsomServlet.class);
71
72     protected String JavaDoc[] BLOJSOM_CONFIGURATION_FILES = {"blojsom.xml"};
73     protected ClassPathXmlApplicationContext _classPathXmlApplicationContext;
74
75     /**
76      * Initialize blojsom
77      *
78      * @param servletConfig {@link ServletConfig}
79      * @throws ServletException If there is an error initializing blojsom
80      */

81     public void init(ServletConfig JavaDoc servletConfig) throws ServletException JavaDoc {
82         super.init(servletConfig);
83
84         ServletConfigFactoryBean.setServletConfig(servletConfig);
85
86         try {
87             _classPathXmlApplicationContext = new ClassPathXmlApplicationContext(BLOJSOM_CONFIGURATION_FILES);
88         } catch (BeansException e) {
89             if (_logger.isErrorEnabled()) {
90                 _logger.error(e);
91             }
92
93             throw new ServletException JavaDoc(e);
94         }
95
96         servletConfig.getServletContext().setAttribute(BlojsomConstants.BLOJSOM_APPLICATION_CONTEXT, _classPathXmlApplicationContext);
97
98         if (_logger.isDebugEnabled()) {
99             _logger.debug("blojsom: All Your Blog Are Belong To Us");
100         }
101     }
102
103     /**
104      * Handle requests made to blojsom
105      *
106      * @param httpServletRequest {@link HttpServletRequest} request
107      * @param httpServletResponse {@link HttpServletResponse} response
108      * @throws ServletException If there is an error serving the request
109      * @throws IOException If there is an error serving the request
110      */

111     protected void service(HttpServletRequest JavaDoc httpServletRequest, HttpServletResponse JavaDoc httpServletResponse) throws ServletException JavaDoc, IOException JavaDoc {
112         try {
113             httpServletRequest.setCharacterEncoding(BlojsomConstants.UTF8);
114         } catch (UnsupportedEncodingException JavaDoc e) {
115             if (_logger.isErrorEnabled()) {
116                 _logger.error(e);
117             }
118         }
119
120         // Make sure that we have a request URI ending with a / otherwise we need to
121
// redirect so that the browser can handle relative link generation
122
if (!httpServletRequest.getRequestURI().endsWith("/")) {
123             StringBuffer JavaDoc redirectURL = new StringBuffer JavaDoc();
124             redirectURL.append(httpServletRequest.getRequestURI());
125             redirectURL.append("/");
126             if (httpServletRequest.getParameterMap().size() > 0) {
127                 redirectURL.append("?");
128                 redirectURL.append(BlojsomUtils.convertRequestParams(httpServletRequest));
129             }
130
131             if (_logger.isDebugEnabled()) {
132                 _logger.debug("Redirecting the user to: " + redirectURL.toString());
133             }
134
135             httpServletResponse.sendRedirect(redirectURL.toString());
136
137             return;
138         }
139
140         Properties JavaDoc blojsomDefaultProperties = (Properties JavaDoc) _classPathXmlApplicationContext.getBean("defaultProperties");
141
142         // Check for an overriding id
143
String JavaDoc blogId = httpServletRequest.getParameter(BlojsomConstants.BLOG_ID_PARAM);
144         if (BlojsomUtils.checkNullOrBlank(blogId)) {
145             String JavaDoc blogIdFromPath = BlojsomUtils.getBlogFromPath(httpServletRequest.getPathInfo());
146             if (blogIdFromPath == null) {
147                 blogId = blojsomDefaultProperties.getProperty(BlojsomConstants.DEFAULT_BLOG_IP);
148             } else {
149                 blogId = blogIdFromPath;
150             }
151         }
152
153         if (BlojsomUtils.checkNullOrBlank(blogId)) {
154             httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Blog ID not specified");
155
156             return;
157         }
158
159         Fetcher fetcher = (Fetcher) _classPathXmlApplicationContext.getBean("fetcher");
160
161         Blog blog;
162         try {
163             blog = fetcher.loadBlog(blogId);
164         } catch (FetcherException e) {
165             if (_logger.isErrorEnabled()) {
166                 _logger.error(e);
167             }
168
169             // Try and use the default blog ID if a blog ID is specified and unable to load the blog
170
String JavaDoc defaultBlogId = blojsomDefaultProperties.getProperty(BlojsomConstants.DEFAULT_BLOG_IP);
171             if (BlojsomUtils.checkNullOrBlank(defaultBlogId)) {
172                 httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Unable to load blog ID: " + blogId);
173
174                 return;
175             } else {
176                 try {
177                     blog = fetcher.loadBlog(defaultBlogId);
178                 } catch (FetcherException e1) {
179                     if (_logger.isErrorEnabled()) {
180                         _logger.error(e);
181                     }
182
183                     httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Unable to load blog ID: " + defaultBlogId);
184
185                     return;
186                 }
187             }
188         }
189
190         if ("true".equals(blog.getProperty(BlojsomConstants.USE_DYNAMIC_BLOG_URLS))) {
191             BlojsomUtils.resolveDynamicBaseAndBlogURL(httpServletRequest, blog, blogId);
192         }
193
194         // Determine the requested flavor
195
String JavaDoc flavor = httpServletRequest.getParameter(BlojsomConstants.FLAVOR_PARAM);
196         if (BlojsomUtils.checkNullOrBlank(flavor)) {
197             flavor = blog.getProperty(BlojsomConstants.BLOG_DEFAULT_FLAVOR_IP);
198             if (blog.getTemplates().get(flavor) == null) {
199                 flavor = BlojsomConstants.DEFAULT_FLAVOR_HTML;
200             }
201         } else {
202             if (blog.getTemplates().get(flavor) == null) {
203                 flavor = blog.getProperty(BlojsomConstants.BLOG_DEFAULT_FLAVOR_IP);
204                 if (blog.getTemplates().get(flavor) == null) {
205                     flavor = BlojsomConstants.DEFAULT_FLAVOR_HTML;
206                 }
207             }
208         }
209
210         // Setup the initial context for the fetcher, plugins, and finally the dispatcher
211
HashMap JavaDoc context = new HashMap JavaDoc();
212
213         // Setup the resource manager in the context
214
context.put(BlojsomConstants.RESOURCE_MANAGER_CONTEXT_KEY, _classPathXmlApplicationContext.getBean("resourceManager"));
215         context.put(BlojsomConstants.BLOJSOM_REQUESTED_FLAVOR, flavor);
216
217         Entry[] entries = null;
218         Category[] categories = null;
219
220         try {
221             categories = fetcher.fetchCategories(httpServletRequest, httpServletResponse, blog, flavor, context);
222             entries = fetcher.fetchEntries(httpServletRequest, httpServletResponse, blog, flavor, context);
223         } catch (FetcherException e) {
224             if (_logger.isErrorEnabled()) {
225                 _logger.error(e);
226             }
227         }
228
229         String JavaDoc[] pluginChain;
230         Map JavaDoc plugins = blog.getPlugins();
231
232         // Check to see if the user would like to override the plugin chain
233
if (httpServletRequest.getParameter(BlojsomConstants.PLUGINS_PARAM) != null) {
234             pluginChain = BlojsomUtils.parseCommaList(httpServletRequest.getParameter(BlojsomConstants.PLUGINS_PARAM));
235         } else {
236             if (plugins.containsKey(flavor) && !BlojsomUtils.checkNullOrBlank(((String JavaDoc) plugins.get(flavor)).trim())) {
237                 pluginChain = BlojsomUtils.parseOnlyCommaList((String JavaDoc) plugins.get(flavor), true);
238             } else {
239                 pluginChain = BlojsomUtils.parseOnlyCommaList((String JavaDoc) plugins.get("default"), true);
240             }
241         }
242
243         // Invoke the plugins in the order in which they were specified
244
if ((entries != null) && (pluginChain != null) && (pluginChain.length > 0)) {
245             for (int i = 0; i < pluginChain.length; i++) {
246                 String JavaDoc plugin = pluginChain[i];
247                 try {
248                     Plugin pluginToExecute = (Plugin) _classPathXmlApplicationContext.getBean(plugin);
249                     if (_logger.isDebugEnabled()) {
250                         _logger.debug("blojsom plugin execution: " + pluginToExecute.getClass().getName());
251                     }
252                     try {
253                         entries = pluginToExecute.process(httpServletRequest, httpServletResponse, blog, context, entries);
254                         pluginToExecute.cleanup();
255                     } catch (PluginException e) {
256                         if (_logger.isErrorEnabled()) {
257                             _logger.error(e);
258                         }
259                     }
260                 } catch (BeansException e) {
261                     if (_logger.isErrorEnabled()) {
262                         _logger.error("Plugin not available: " + plugin);
263                     }
264                 }
265             }
266         } else {
267             if (_logger.isDebugEnabled()) {
268                 _logger.debug("No entries available for plugins to process or no plugins specified for flavor");
269             }
270         }
271
272         String JavaDoc blogdate = null;
273         String JavaDoc blogISO8601Date = null;
274         String JavaDoc blogUTCDate = null;
275         Date JavaDoc blogDateObject = null;
276
277         boolean sendLastModified = true;
278         if (httpServletRequest.getParameter(BlojsomConstants.OVERRIDE_LASTMODIFIED_PARAM) != null) {
279             sendLastModified = Boolean.getBoolean(httpServletRequest.getParameter(BlojsomConstants.OVERRIDE_LASTMODIFIED_PARAM));
280         }
281
282         // If we have entries, construct a last modified on the most recent entry
283
// Additionally, set the blog date
284
if (sendLastModified) {
285             if ((entries != null) && (entries.length > 0)) {
286                 Entry _entry = entries[0];
287                 long _lastmodified;
288
289                 if (_entry.getNumComments() > 0) {
290                     Comment _comment = _entry.getCommentsAsArray()[_entry.getNumComments() - 1];
291                     _lastmodified = _comment.getCommentDate().getTime();
292                     if (_logger.isDebugEnabled()) {
293                         _logger.debug("Adding last-modified header for most recent entry comment");
294                     }
295                 } else {
296                     _lastmodified = _entry.getDate().getTime();
297                     if (_logger.isDebugEnabled()) {
298                         _logger.debug("Adding last-modified header for most recent blog entry");
299                     }
300                 }
301
302                 // Check for the Last-Modified object from one of the plugins
303
if (context.containsKey(BlojsomConstants.BLOJSOM_LAST_MODIFIED)) {
304                     Long JavaDoc lastModified = (Long JavaDoc) context.get(BlojsomConstants.BLOJSOM_LAST_MODIFIED);
305                     if (lastModified.longValue() > _lastmodified) {
306                         _lastmodified = lastModified.longValue();
307                     }
308                 }
309
310                 // Generates an ETag header based on the string value of LastModified as an ISO8601 Format
311
String JavaDoc etagLastModified = BlojsomUtils.getISO8601Date(new Date JavaDoc(_lastmodified));
312                 httpServletResponse.addHeader(BlojsomConstants.HTTP_ETAG, "\"" + BlojsomUtils.digestString(etagLastModified) + "\"");
313
314                 httpServletResponse.addDateHeader(BlojsomConstants.HTTP_LASTMODIFIED, _lastmodified);
315                 blogdate = entries[0].getRFC822Date();
316                 blogISO8601Date = entries[0].getISO8601Date();
317                 blogDateObject = entries[0].getDate();
318                 blogUTCDate = BlojsomUtils.getUTCDate(entries[0].getDate());
319             } else {
320                 if (_logger.isDebugEnabled()) {
321                     _logger.debug("Adding last-modified header for current date");
322                 }
323
324                 Date JavaDoc today = new Date JavaDoc();
325                 blogdate = BlojsomUtils.getRFC822Date(today);
326                 blogISO8601Date = BlojsomUtils.getISO8601Date(today);
327                 blogUTCDate = BlojsomUtils.getUTCDate(today);
328                 blogDateObject = today;
329                 httpServletResponse.addDateHeader(BlojsomConstants.HTTP_LASTMODIFIED, today.getTime());
330                 // Generates an ETag header based on the string value of LastModified as an ISO8601 Format
331
httpServletResponse.addHeader(BlojsomConstants.HTTP_ETAG, "\"" + BlojsomUtils.digestString(blogISO8601Date) + "\"");
332             }
333         }
334
335         context.put(BlojsomConstants.BLOJSOM_DATE, blogdate);
336         context.put(BlojsomConstants.BLOJSOM_DATE_ISO8601, blogISO8601Date);
337         context.put(BlojsomConstants.BLOJSOM_DATE_OBJECT, blogDateObject);
338         context.put(BlojsomConstants.BLOJSOM_DATE_UTC, blogUTCDate);
339
340         // Finish setting up the context for the dispatcher
341
context.put(BlojsomConstants.BLOJSOM_BLOG, blog);
342         context.put(BlojsomConstants.BLOJSOM_ENTRIES, entries);
343         context.put(BlojsomConstants.BLOJSOM_CATEGORIES, categories);
344         context.put(BlojsomConstants.BLOJSOM_VERSION, BlojsomConstants.BLOJSOM_VERSION_NUMBER);
345         context.put(BlojsomConstants.BLOJSOM_BLOG_ID, blog.getBlogId());
346         context.put(BlojsomConstants.BLOJSOM_SITE_URL, blog.getBlogBaseURL());
347
348         context.put(BlojsomConstants.BLOJSOM_BLOG_ID, blog.getBlogId());
349
350         String JavaDoc templateAndType = (String JavaDoc) blog.getTemplates().get(flavor);
351         String JavaDoc[] templateData = BlojsomUtils.parseOnlyCommaList(templateAndType, true);
352         String JavaDoc templateExtension = BlojsomUtils.getFileExtension(templateData[0]);
353        
354         Dispatcher dispatcher = null;
355         try {
356             dispatcher = (org.blojsom.dispatcher.Dispatcher) _classPathXmlApplicationContext.getBean(templateExtension);
357         } catch (BeansException e) {
358             if (_logger.isErrorEnabled()) {
359                 _logger.error(e);
360             }
361
362             httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unable to retrieve dispatcher for template extension: " + templateExtension);
363         }
364         dispatcher.dispatch(httpServletRequest, httpServletResponse, blog, context, templateData[0], templateData[1]);
365     }
366
367     /**
368      * Take blojsom out of service
369      */

370     public void destroy() {
371         super.destroy();
372
373         _classPathXmlApplicationContext.destroy();
374
375         if (_logger.isDebugEnabled()) {
376             _logger.debug("blojsom destroyed");
377         }
378     }
379 }
380
Popular Tags