View Javadoc

1   package org.apache.fulcrum.template.jsp;
2   
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21   */
22  
23  
24  import java.io.OutputStream;
25  import java.io.Writer;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.apache.avalon.framework.configuration.Configuration;
30  import org.apache.avalon.framework.configuration.ConfigurationException;
31  import org.apache.avalon.framework.context.Context;
32  import org.apache.avalon.framework.service.ServiceException;
33  import org.apache.avalon.framework.service.ServiceManager;
34  import org.apache.fulcrum.template.BaseTemplateEngineService;
35  import org.apache.fulcrum.template.TemplateContext;
36  import org.apache.fulcrum.template.TemplateException;
37  import org.apache.fulcrum.template.TemplateService;
38  
39  /**
40   * This is a Service that can process JSP templates from within a Turbine
41   * screen.
42   *
43   * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
44   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
45   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
46   */
47  public class TurbineJspService
48      extends BaseTemplateEngineService
49      implements JspService
50  {
51      /** paths as given in the configuration file */
52      private String[] rawPaths;
53  
54      /** The base path[s] prepended to filenames given in arguments */
55      private String[] templatePaths;
56  
57      /** The relative path[s] prepended to filenames */
58      private String[] relativeTemplatePaths;
59  
60      /** The buffer size for the output stream. */
61      private int bufferSize;
62  
63      /** The class to handle looking up template names */
64      private TemplateService templateService;
65      /**
66       * Adds some convenience objects to the request.  For example an instance
67       * of JspLink which can be used to generate links to other templates.
68       *
69       * @param RunData the turbine rundata object
70       */
71  
72      /*
73       *    public void addDefaultObjects(RunData data)
74       *    {
75       *        HttpServletRequest req = data.getRequest();
76       *        //req.setAttribute(LINK, new JspLink(data));
77       *        req.setAttribute(RUNDATA, data);
78       *    }
79       */
80  
81      /**
82       * The buffer size
83       *
84       */
85      public int getDefaultBufferSize()
86      {
87          return bufferSize;
88      }
89  
90      /**
91       * Process the request
92       *
93       * @param RunData
94       * @param String the filename of the template.
95       * @throws ServiceException Any exception trown while processing will be
96       *         wrapped into a ServiceException and rethrown.
97       */
98      /*
99       *    public void handleRequest(RunData data, String filename)
100      *       throws ServiceException
101      *    {
102      *       handleRequest(data, filename, false);
103      *    }
104      */
105 
106     /**
107      * Process the request
108      *
109      * @param RunData
110      * @param String the filename of the template.
111      * @param boolean whether to perform a forward or include.
112      * @throws ServiceException Any exception trown while processing will be
113      *         wrapped into a ServiceException and rethrown.
114      */
115     /*
116      *    public void handleRequest(RunData data, String filename, boolean isForward)
117      *       throws ServiceException
118      *    {
119      *       // template name with relative path
120      *       String relativeTemplateName = getRelativeTemplateName(filename);
121      *
122      *       if (relativeTemplateName == null)
123      *       {
124      *           throw new ServiceException(
125      *           "Template " + filename + " not found in template paths");
126      *       }
127      *
128      *       // get the RequestDispatcher for the JSP
129      *       RequestDispatcher dispatcher = data.getServletContext()
130      *           .getRequestDispatcher(relativeTemplateName);
131      *
132      *       try
133      *       {
134      *           if (isForward)
135      *           {
136      *               // forward the request to the JSP
137      *               dispatcher.forward( data.getRequest(), data.getResponse() );
138      *           }
139      *           else
140      *           {
141      *               data.getOut().flush();
142      *               // include the JSP
143      *               dispatcher.include( data.getRequest(), data.getResponse() );
144      *           }
145      *       }
146      *       catch(Exception e)
147      *       {
148      *           // as JSP service is in Alpha stage, let's try hard to send the error
149      *           // message to the browser, to speed up debugging
150      *           try
151      *           {
152      *               data.getOut().print("Error encountered processing a template: "+filename);
153      *               e.printStackTrace(data.getOut());
154      *           }
155      *           catch(IOException ignored)
156      *           {
157      *           }
158      *
159      *           // pass the exception to the caller according to the general
160      *           // contract for tamplating services in Turbine
161      *           throw new ServiceException(
162      *               "Error encountered processing a template:" + filename, e);
163      *       }
164      *    }
165      */
166 
167     /**
168      * Currently a no-op.  This method must be implemented so that the
169      * the JSP service comformith to the TemplateEngineService
170      * interface.
171      */
172     public String handleRequest(TemplateContext context, String template)
173         throws TemplateException
174     {
175         // TODO: Implement me!
176         return "";
177     }
178 
179     /**
180      * Currently a no-op.  This method must be implemented so that the
181      * the JSP service comformith to the TemplateEngineService
182      * interface.
183      */
184     public void handleRequest(
185         TemplateContext context,
186         String template,
187         OutputStream outputStream)
188         throws TemplateException
189     {
190         // TODO: Implement me!
191     }
192 
193     /**
194      * @see org.apache.fulcrum.template.TemplateEngineService#handleRequest(
195      * Context, String, Writer)
196      */
197     public void handleRequest(
198         TemplateContext context,
199         String template,
200         Writer writer)
201         throws TemplateException
202     {
203         // TODO: Implement me!
204     }
205 
206     /**
207      * Determine whether a given template exists. This service
208      * currently only supports file base template hierarchies
209      * so we will use the utility methods provided by
210      * the template service to do the searching.
211      *
212      * @param String template
213      * @return boolean
214      */
215     public boolean templateExists(String template)
216     {
217         return templateService.templateExists(template, templatePaths);
218     }
219     /**
220      * Searchs for a template in the default.template path[s] and
221      * returns the template name with a relative path which is
222      * required by <a href="http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletContext.html#getRequestDispatcher(java.lang.String)">
223      * javax.servlet.RequestDispatcher</a>
224      *
225      * @param String template
226      * @return String
227      */
228 
229     public String getRelativeTemplateName(String template)
230     {
231         /*
232          * A dummy String[] object used to pass a String to
233          * TurbineTemplate.templateExists
234          */
235         String[] testTemplatePath = new String[1];
236 
237         /**
238          * Find which template path the template is in
239          */
240         for (int i = 0; i < relativeTemplatePaths.length; i++)
241         {
242             testTemplatePath[0] = getRealPath(relativeTemplatePaths[i]);
243             if (templateService.templateExists(template, testTemplatePath))
244             {
245                 return relativeTemplatePaths[i] + template;
246             }
247         }
248 
249         return null;
250     }
251 
252     /*
253      *    public void doBuildBeforeAction(RunData data)
254      *    {
255      *        addDefaultObjects(data);
256      *
257      *        try
258      *        {
259      *            //We try to set the buffer size from defaults
260      *            data.getResponse().setBufferSize(getDefaultBufferSize());
261      *        }
262      *        catch (IllegalStateException ise )
263      *        {
264      *            //If the response was already commited, we die silently
265      *            //No logger here?
266      *        }
267      *    }
268      *
269      *    public void doBuildAfterAction(RunData data)
270      *    {
271      *        // do nothing
272      *    }
273      *
274      *    public void doPostBuild(RunData data)
275      *    {
276      *        // do nothing
277      *    }
278      */
279 
280     // ---------------- Avalon Lifecycle Methods ---------------------
281 
282     /**
283      * Avalon component lifecycle method
284      */
285     public void configure(Configuration conf) throws ConfigurationException
286     {
287 
288         List pathList = new ArrayList();
289         final Configuration[] paths = conf.getChildren("template-path");
290         if (paths != null)
291         {
292             for (int i = 0; i < paths.length; i++)
293             {
294                 pathList.add(paths[i].getValue());
295             }
296         }
297         rawPaths = (String[]) pathList.toArray(new String[pathList.size()]);
298 
299         bufferSize = conf.getAttributeAsInteger("buffer-size", 8192);
300 
301         // Register with the template service.
302         registerConfiguration(conf, "jsp");
303 
304         // Use the turbine template service to translate the template paths.
305         templatePaths = templateService.translateTemplatePaths(rawPaths);
306 
307         // Set relative paths from config.
308         // Needed for javax.servlet.RequestDispatcher
309         relativeTemplatePaths = rawPaths;
310         // Make sure that the relative paths begin with /
311         for (int i = 0; i < relativeTemplatePaths.length; i++)
312         {
313             if (!relativeTemplatePaths[i].startsWith("/"))
314             {
315                 relativeTemplatePaths[i] = "/" + relativeTemplatePaths[i];
316             }
317         }
318     }
319 
320     // ---------------- Avalon Lifecycle Methods ---------------------
321     /**
322      * Avalon component lifecycle method
323      */
324     public void service(ServiceManager manager) throws ServiceException
325     {
326         super.service(manager);
327         templateService = (TemplateService)manager.lookup(TemplateService.ROLE);
328 
329     }
330 }