KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jpublish > servlet > JPublishServlet


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

48
49 package org.jpublish.servlet;
50
51 import java.io.IOException JavaDoc;
52 import java.io.OutputStream JavaDoc;
53
54 import javax.servlet.ServletConfig JavaDoc;
55 import javax.servlet.ServletContext JavaDoc;
56 import javax.servlet.ServletException JavaDoc;
57 import javax.servlet.http.HttpServlet JavaDoc;
58 import javax.servlet.http.HttpServletRequest JavaDoc;
59 import javax.servlet.http.HttpServletResponse JavaDoc;
60 import javax.servlet.http.HttpSession JavaDoc;
61
62 import com.anthonyeden.lib.util.MessageUtilities;
63 import org.apache.commons.logging.Log;
64 import org.apache.commons.logging.LogFactory;
65 import org.jpublish.EntityNotFoundException;
66 import org.jpublish.JPublishEngine;
67 import org.jpublish.RequestContext;
68 import org.jpublish.SiteContext;
69 import org.jpublish.util.PathUtilities;
70 import org.jpublish.util.URLUtilities;
71 import org.jpublish.util.encoding.CharacterEncodingMap;
72 import org.jpublish.util.mime.MimeTypeMap;
73
74 /**
75  * Servlet which delegates requests to the JPublish engine.
76  *
77  * <p>The servlet should be configured to handler all requests for its context. In addition, a init-parameter called
78  * config must be included in the <code>web.xml</code> file. The value of this parameter must be the path to the site's
79  * configuration file relative to the webapp root.</p>
80  *
81  * @author Anthony Eden
82  */

83
84 public class JPublishServlet extends HttpServlet JavaDoc {
85
86     private static final Log log = LogFactory.getLog(JPublishServlet.class);
87
88     private JPublishEngine engine = null;
89     private SiteContext siteContext = null;
90
91     /**
92      * Initialize the servlet.
93      *
94      * @param servletConfig The Servlet configuration
95      * @throws ServletException
96      */

97
98     public void init(ServletConfig JavaDoc servletConfig) throws
99             ServletException JavaDoc {
100         super.init(servletConfig);
101         log.info("Initializing JPublish servlet");
102
103         ServletContext JavaDoc servletContext = getServletContext();
104
105         String JavaDoc configLocation = servletConfig.getInitParameter("config");
106         if (log.isDebugEnabled()) {
107             log.debug("Config location: " + configLocation);
108         }
109         
110         // create the site context
111
try {
112             log.debug("Creating site context");
113             siteContext = new SiteContext(servletContext);
114             siteContext.loadConfiguration(configLocation);
115
116             log.debug("Creating JPublish engine");
117             engine = new JPublishEngine(siteContext);
118         } catch (Throwable JavaDoc e) {
119             log.error("Error creating SiteContext: " + e.getMessage());
120             throw new ServletException JavaDoc(e);
121         }
122
123         log.info("JPublish servlet initialized.");
124     }
125
126     /**
127      * Called when the Servlet is destroyed.
128      */

129
130     public void destroy() {
131         engine.destroy();
132     }
133
134     /**
135      * Called when the HTTP request method is GET. This method just calls the doPost() method.
136      *
137      * @param request The HTTP request
138      * @param response The HTTP response
139      * @throws ServletException
140      * @throws IOException
141      */

142
143     public void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
144             throws ServletException JavaDoc, IOException JavaDoc {
145         doPost(request, response);
146     }
147
148     /**
149      * Called when the HTTP request method is POST. This method provides the main control logic.
150      *
151      * @param request The HTTP request
152      * @param response The HTTP response
153      * @throws ServletException
154      * @throws IOException
155      */

156
157     public void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
158             throws ServletException JavaDoc, IOException JavaDoc {
159         // get the real path
160
String JavaDoc path = PathUtilities.getRealPath(siteContext,
161                 request.getPathInfo());
162         if (log.isDebugEnabled()) {
163             log.debug("Real path: " + path);
164         }
165
166         // check to see if dispatching is necessary
167
if (siteContext.getPathDispatcher().canDispatch(path)) {
168
169             //only one of the ifs below should positively react
170
String JavaDoc dispatcherName = siteContext.getPathDispatcher().canForwardDispatch(path);
171             if (dispatcherName != null) {
172                 siteContext.getPathDispatcher().forward(request, response, dispatcherName);
173             }
174
175             dispatcherName = siteContext.getPathDispatcher().canIncludeDispatch(path);
176             if (dispatcherName != null) {
177                 siteContext.getPathDispatcher().include(request, response, dispatcherName);
178             }
179
180             return;
181         }
182
183         // create the session facade
184
log.debug("Creating session facade");
185         HttpSession JavaDoc session = new HttpSessionFacade(request);
186         if (log.isDebugEnabled()) {
187             log.debug("Session facade: " + session);
188         }
189         
190         // get the character encoding map
191
CharacterEncodingMap characterEncodingMap =
192                 siteContext.getCharacterEncodingManager().getMap(path);
193         
194         // set the request character encoding for parameter data
195
if (requireVersion(2, 3)) {
196             request.setCharacterEncoding(characterEncodingMap.getRequestEncoding());
197         }
198         
199         // set the response content type
200
int lastDotIndex = path.lastIndexOf(".");
201         if (lastDotIndex >= 0) {
202             String JavaDoc extension = path.substring(lastDotIndex + 1);
203             String JavaDoc mimeType = siteContext.getMimeTypeMap().getMimeType(extension);
204             String JavaDoc contentType = getMimeTypeWithCharset(mimeType,
205                     characterEncodingMap.getResponseEncoding());
206             response.setContentType(contentType);
207             if (log.isDebugEnabled()) {
208                 log.debug("Content type for extension " + extension + " is " +
209                         contentType);
210             }
211         } else {
212             response.setContentType(getMimeTypeWithCharset(MimeTypeMap.DEFAULT_MIME_TYPE,
213                     characterEncodingMap.getResponseEncoding()));
214             log.debug("No extension found, using default content type.");
215         }
216         
217         // put "raw" responses right here. This is a feature which
218
// should be added - a raw resource would be returned immediately
219
// without executing any actions.
220

221         /*
222         ResourceManager rawResourceManager =
223             siteContext.getRawResourceManager();
224         if(rawResourceManager.exists(path)){
225             OutputStream out = response.getOutputStream();
226             response.setDateHeader("Last-Modified",
227                 rawResourceManager.getLastModified(path));
228             try{
229                 rawResourceManager.load(path, out);
230                 out.flush();
231             } catch(SocketException e){
232                 if(log.isWarnEnabled())
233                     log.warn("Error writing to output stream: " +
234                     e.getMessage());
235             }
236             return;
237         }
238         */

239     
240         // construct the RequestContext
241
RequestContext context = RequestContext.getRequestContext();
242         // clear the context
243
context.clear();
244         log.debug("Cleared the context");
245         
246         // put standard servlet stuff into the context
247
context.put("path", path);
248         context.put("request", request);
249         context.put("response", response);
250         log.debug("Putting session in the context");
251         context.put("session", session);
252         context.put("application", getServletContext());
253         
254         // add the character encoding map to the context
255
context.put("characterEncodingMap", characterEncodingMap);
256         
257         // add the URLUtilities to the context
258
context.put("urlUtilities", new URLUtilities(request, response));
259
260         // put the context into the request for use by other servlets when dispatching
261
request.setAttribute("context", context);
262
263         OutputStream JavaDoc out = response.getOutputStream();
264         try {
265             engine.render(out);
266
267             String JavaDoc redirect = context.getRedirect();
268             if (redirect != null) {
269                 // context.clear();
270
//log.debug("Cleared context");
271
response.sendRedirect(redirect);
272             }
273
274         } catch (EntityNotFoundException e) {
275             Object JavaDoc[] args = {e.getMessage()};
276             String JavaDoc msg = MessageUtilities.getMessage(getClass(),
277                     JPublishEngine.MESSAGE_PACKAGE, "fileNotFound", args);
278             log.error(msg);
279             if (!response.isCommitted()) {
280                 response.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
281             }
282         } catch (Throwable JavaDoc e) {
283             Object JavaDoc[] args = {e.getMessage()};
284             String JavaDoc msg = MessageUtilities.getMessage(getClass(),
285                     JPublishEngine.MESSAGE_PACKAGE, "errorRenderingPage", args);
286             log.error(msg);
287             if (!response.isCommitted()) {
288                 throw new ServletException JavaDoc("Error rendering page", e);
289             }
290         } finally {
291             /*
292             if (!context.isForwarded()) {
293                 context.clear();
294             }
295             */

296         }
297     }
298
299     /**
300      * Append the charset to the given mime type.
301      *
302      * @param mimeType The mime type
303      * @param charSet The character set
304      * @return The full mimetype + character set
305      */

306
307     private String JavaDoc getMimeTypeWithCharset(String JavaDoc mimeType, String JavaDoc charSet) {
308         // currently the charset is appended to all mime types. This could
309
// cause problems for non-text mime types. Thus if the problem
310
// does manifest in the future it should be possible to specify
311
// which mime types support character sets in the config. -AE
312

313         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
314         buffer.append(mimeType);
315         buffer.append("; charset=");
316         buffer.append(charSet);
317         return buffer.toString();
318     }
319
320     /**
321      * Return true if the ServletContext major and minor version are greater than or equal to the given arguments.
322      *
323      * @param majorVersion The required major version
324      * @param minorVersion The required minor version
325      * @return True if the version is equal to or greater than the given args
326      */

327
328     private boolean requireVersion(int majorVersion, int minorVersion) {
329         ServletContext JavaDoc servletContext = getServletContext();
330         return ((servletContext.getMajorVersion() > majorVersion) ||
331                 (servletContext.getMajorVersion() == majorVersion &&
332                 servletContext.getMinorVersion() >= minorVersion)
333                 );
334     }
335
336 }
337
Popular Tags