Coverage Report - org.melati.servlet.TemplateServlet
 
Classes in this File Line Coverage Branch Coverage Complexity
TemplateServlet
88%
45/51
78%
11/14
2.5
 
 1  
 /*
 2  
  * $Source$
 3  
  * $Revision$
 4  
  *
 5  
  * Copyright (C) 2000 Tim Joyce
 6  
  *
 7  
  * Part of Melati (http://melati.org), a framework for the rapid
 8  
  * development of clean, maintainable web applications.
 9  
  *
 10  
  * Melati is free software; Permission is granted to copy, distribute
 11  
  * and/or modify this software under the terms either:
 12  
  *
 13  
  * a) the GNU General Public License as published by the Free Software
 14  
  *    Foundation; either version 2 of the License, or (at your option)
 15  
  *    any later version,
 16  
  *
 17  
  *    or
 18  
  *
 19  
  * b) any version of the Melati Software License, as published
 20  
  *    at http://melati.org
 21  
  *
 22  
  * You should have received a copy of the GNU General Public License and
 23  
  * the Melati Software License along with this program;
 24  
  * if not, write to the Free Software Foundation, Inc.,
 25  
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
 26  
  * GNU General Public License and visit http://melati.org to obtain the
 27  
  * Melati Software License.
 28  
  *
 29  
  * Feel free to contact the Developers of Melati (http://melati.org),
 30  
  * if you would like to work out a different arrangement than the options
 31  
  * outlined here.  It is our intention to allow Melati to be used by as
 32  
  * wide an audience as possible.
 33  
  *
 34  
  * This program is distributed in the hope that it will be useful,
 35  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 36  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 37  
  * GNU General Public License for more details.
 38  
  *
 39  
  * Contact details for copyright holder:
 40  
  *
 41  
  *     Tim Joyce <timj At paneris.org>
 42  
  *     http://paneris.org/
 43  
  *     68 Sandbanks Rd, Poole, Dorset. BH14 8BY. UK
 44  
  */
 45  
 
 46  
 package org.melati.servlet;
 47  
 
 48  
 import java.io.PrintWriter;
 49  
 import java.io.StringWriter;
 50  
 
 51  
 import javax.servlet.ServletException;
 52  
 import javax.servlet.ServletConfig;
 53  
 
 54  
 import org.melati.Melati;
 55  
 import org.melati.util.MelatiWriter;
 56  
 import org.melati.template.ServletTemplateEngine;
 57  
 import org.melati.template.ServletTemplateContext;
 58  
 import org.melati.template.MultipartTemplateContext;
 59  
 import org.melati.template.Template;
 60  
 
 61  
 /**
 62  
  * Base class to use Melati with a Template Engine.
 63  
  * To create your own servlet simply extend this class, 
 64  
  * overriding the <code>doTemplateRequest</code> method.
 65  
  *
 66  
  * @author Tim Joyce
 67  
  * $Revision$
 68  
  */
 69  18
 public abstract class TemplateServlet extends PoemServlet {
 70  
 
 71  
   /**
 72  
    * Eclipse generated. 
 73  
    */
 74  
   private static final long serialVersionUID = -5228388231472549208L;
 75  
   
 76  
   // the template engine
 77  
   protected ServletTemplateEngine templateEngine;
 78  
 
 79  
   /**
 80  
    * Initialise the template engine.
 81  
    *
 82  
    * @param config a <code>ServletConfig</code>
 83  
    * @throws ServletException if the ServletTemplateEngine has a problem
 84  
    */
 85  
   public void init(ServletConfig config) throws ServletException {
 86  18
     super.init(config);
 87  18
     templateEngine = melatiConfig.getServletTemplateEngine();
 88  18
     templateEngine.init(melatiConfig, this);
 89  18
   }
 90  
 
 91  
   /**
 92  
    * Set the ServletTemplateEngine and ServletTemplateContext in our Melati.
 93  
    * This allows us to parse any uploaded files before we enter
 94  
    * our PoemSession (so we don't hang on to transactions
 95  
    * unnecessarily).
 96  
    *
 97  
    * @param melati the current Melati
 98  
    * @throws Exception if anything goes wrong
 99  
    */
 100  
   protected void prePoemSession(Melati melati) throws Exception {
 101  
     // for this request, set the Initialised Template Engine
 102  509
     melati.setTemplateEngine(templateEngine);
 103  509
     ServletTemplateContext templateContext =
 104  509
             templateEngine.getServletTemplateContext(melati);
 105  
 
 106  509
     melati.setTemplateContext(templateContext);
 107  509
   }
 108  
 
 109  
   protected void doPoemRequest(Melati melati) throws Exception {
 110  507
     ServletTemplateContext templateContext = melati.getServletTemplateContext();
 111  
     // If we have a multi-part form, we use a different template context
 112  
     // which allows us to access the uploaded files as well as fields.
 113  
     // This used to be in prePoemSession, but the use case was pretty thin,
 114  
     // the main Adaptor is PoemFileFormDataAdaptor, which needs to be in session.
 115  507
     String contentType = melati.getRequest().getHeader("content-type");
 116  507
     if (contentType != null && contentType.length() >= 19 &&
 117  40
         contentType.substring(0,19).equalsIgnoreCase("multipart/form-data")) {
 118  7
       templateContext =
 119  
         new MultipartTemplateContext(melati, templateContext);
 120  
     }
 121  
 
 122  507
     templateContext.put("melati", melati);
 123  507
     templateContext.put("ml", melati.getMarkupLanguage());
 124  
 
 125  507
     String templateName = doTemplateRequest(melati,templateContext);
 126  
 
 127  
     // only expand a template if we have one (it could be a redirect)
 128  498
     if (templateName != null) {
 129  490
       templateName = addExtension(templateName);
 130  490
       templateEngine.expandTemplate(melati.getWriter(), 
 131  
                                     templateName,
 132  
                                     templateContext);
 133  
     }
 134  494
   }
 135  
   
 136  
   /**
 137  
    * The template extension is added in an overridable method
 138  
    * to allow the application developer to specify their own template
 139  
    * extensions.
 140  
    * <p>
 141  
    * To obtain nice URLs one method is to call your templates 
 142  
    * <code>foo.html.wm</code> for example, your urls can then look like
 143  
    * <code>servlet/db/table/troid/method.html</code>.
 144  
    */
 145  
   protected String addExtension(String templateName) {
 146  490
     if (!templateName.endsWith(templateEngine.templateExtension()))  
 147  490
       return templateName + templateEngine.templateExtension();
 148  
     else
 149  0
       return templateName;      
 150  
   }
 151  
 
 152  
    
 153  
   /**
 154  
    * Send an error message.
 155  
    * 
 156  
    * Single call to the templet loader giving purpose (error) and 
 157  
    * Exception class.
 158  
    *
 159  
    * This will look in the purpose directory, 
 160  
    * the standard templet directory and the classpath, in that order, 
 161  
    * for a templet.
 162  
    * This can no longer fail with NotFoundException, 
 163  
    * as the Object templet will always be found 
 164  
    * (or this is a broken installation).
 165  
    *
 166  
    * @param melati the {@link Melati}
 167  
    * @param e      the {@link Exception} to report
 168  
    */
 169  
   public void error(Melati melati, Exception e) {
 170  20
     melati.getResponse().setStatus(httpStatusCode(e));
 171  20
     ServletTemplateContext templateContext = melati.getServletTemplateContext();
 172  
     // If this a DB error which has occurred prior to 
 173  
     // the establishment of a template context
 174  20
     if (templateContext == null) {
 175  0
       super.error(melati, e);
 176  
     } else 
 177  
 
 178  
     // has it been trapped already, if so, we don't need to relog it here
 179  20
     if (!(e instanceof TrappedException)) {
 180  
       try {
 181  
         // log it
 182  10
         e.printStackTrace(System.err);
 183  
         // and put it on the page
 184  10
         MelatiWriter mw =  melati.getWriter();
 185  
         // get rid of anything that has been written so far
 186  10
         mw.reset();
 187  10
         templateContext.put("melati",melati);
 188  10
         templateContext.put("ml", melati.getMarkupLanguage());
 189  10
         templateContext.put("object", e);
 190  10
         StringWriter sw = new StringWriter();
 191  10
         e.printStackTrace(new PrintWriter(sw));
 192  10
         templateContext.put("error",sw);
 193  10
         templateContext.put("sysAdminName", getSysAdminName());
 194  10
         templateContext.put("sysAdminEmail", getSysAdminEmail());
 195  
 
 196  
         Template errorTemplate;
 197  10
         errorTemplate = melati.getConfig().getTempletLoader().
 198  10
               templet(melati.getTemplateEngine(), melati.getMarkupLanguage(),"error", e.getClass());
 199  10
         templateEngine.expandTemplate(mw, errorTemplate, templateContext);
 200  10
         melati.write();
 201  0
       } catch (Exception f) {
 202  0
         System.err.println("Error finding/writing error template:");
 203  0
         f.printStackTrace();
 204  0
         super.error(melati,e);
 205  10
       }
 206  
     }
 207  20
   }
 208  
 
 209  
 
 210  
   /**
 211  
    * Prepare context and establish name of template to interpolate against it. 
 212  
    *
 213  
    * Override this method to build up your own output.
 214  
    *
 215  
    * @param melati the current Melati
 216  
    * @param templateContext the current <code>ServletTemplateContext</code>
 217  
    * @return a Template name, possibly excluding extension.
 218  
    */
 219  
   protected abstract String doTemplateRequest(Melati melati, 
 220  
                                               ServletTemplateContext templateContext)
 221  
       throws Exception;
 222  
 }