Coverage Report - org.webmacro.util.WMEval
 
Classes in this File Line Coverage Branch Coverage Complexity
WMEval
0%
0/83
0%
0/10
1.542
 
 1  
 /*
 2  
  * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
 3  
  *
 4  
  * Redistribution and use in source and binary forms, with or without
 5  
  * modification, are permitted under the terms of either of the following
 6  
  * Open Source licenses:
 7  
  *
 8  
  * The GNU General Public License, version 2, or any later version, as
 9  
  * published by the Free Software Foundation
 10  
  * (http://www.fsf.org/copyleft/gpl.html);
 11  
  *
 12  
  *  or
 13  
  *
 14  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 15  
  *
 16  
  * This software is provided "as is", with NO WARRANTY, not even the
 17  
  * implied warranties of fitness to purpose, or merchantability. You
 18  
  * assume all risks and liabilities associated with its use.
 19  
  *
 20  
  * See www.webmacro.org for more information on the WebMacro project.
 21  
  */
 22  
 
 23  
 package org.webmacro.util;
 24  
 
 25  
 import java.io.FileOutputStream;
 26  
 import java.io.InputStream;
 27  
 import java.io.OutputStream;
 28  
 
 29  
 import javax.servlet.Servlet;
 30  
 import javax.servlet.ServletException;
 31  
 import javax.servlet.http.HttpServletRequest;
 32  
 import javax.servlet.http.HttpServletResponse;
 33  
 
 34  
 import org.slf4j.Logger;
 35  
 import org.slf4j.LoggerFactory;
 36  
 
 37  
 import org.webmacro.Context;
 38  
 import org.webmacro.Template;
 39  
 import org.webmacro.WM;
 40  
 import org.webmacro.WMConstants;
 41  
 import org.webmacro.WebMacro;
 42  
 import org.webmacro.engine.StreamTemplate;
 43  
 import org.webmacro.resource.AbstractTemplateLoader;
 44  
 import org.webmacro.servlet.WMServlet;
 45  
 import org.webmacro.servlet.WebContext;
 46  
 
 47  
 
 48  
 /**
 49  
  * WMEval encapsulates an instance of WebMacro for reuse in any java application.
 50  
  * <p>
 51  
  * It's main benefits are a number of convenience methods for evaluating a template
 52  
  * and directing output either to a supplied output stream or to a file.
 53  
  * <p>
 54  
  * It can parse a single template stream and then evaluate that template
 55  
  * over a number of different contexts. And, it can maintain a single context
 56  
  * and evaluate different templates over the same context. Each time a context
 57  
  * or a template is provided, it is retained as state.
 58  
  * <p>
 59  
  * The context can therefore be preserved over multiple "writes" of different
 60  
  * templates.
 61  
  * <p>
 62  
  * The template stream can be any text stream but is often a rule stream containing
 63  
  * wm script directives.
 64  
  * <p>
 65  
  * This helper class is useful for evaluating WebMacro templates for which
 66  
  * flexibility in managing the evaluation options is key.
 67  
  * 
 68  
  * @author Lane Sharman
 69  
  * @version 3.0
 70  
  */
 71  
 public class WMEval
 72  
 {
 73  
 
 74  
     //-------public members-----
 75  
 
 76  
     //-------private and protected members-----
 77  
     private WebMacro wm;
 78  
 
 79  0
     static Logger _log =  LoggerFactory.getLogger(WMEval.class);
 80  
 
 81  
     private Template currentTemplate;
 82  
 
 83  
     //private OutputStream out = System.out;
 84  
 
 85  
     private Context context;
 86  
 
 87  
     /**
 88  
      * If an output file is not specified as an argument, it
 89  
      * must be found in the context under this key.
 90  
      */
 91  
     public static final String outputContextKey = "OutputFileName";
 92  
 
 93  
     //-------constructor(s)-----
 94  
     /**
 95  
      * Constructor.
 96  
      * Build a WebMacro environment for currentTemplate execution.
 97  
      */
 98  
     public WMEval()
 99  0
     {
 100  
         try {
 101  0
             wm = new WM();
 102  0
             init();
 103  0
         } catch (Exception e) {
 104  0
             throw new IllegalStateException(e);
 105  0
         }
 106  0
     }
 107  
 
 108  
     /**
 109  
      * Build a WebMacro environment to evaluate a template given it's name.
 110  
      */
 111  
     public WMEval(String templateName)
 112  0
     {
 113  
         try {
 114  0
             wm = new WM();
 115  0
             init();
 116  0
             parseLocalTemplate(templateName);
 117  0
         } catch (Exception e) {
 118  0
             throw new IllegalStateException(e);
 119  0
         }
 120  0
     }
 121  
 
 122  
     /**
 123  
      * The constructor for WebMacro decorator in a servlet context.
 124  
      * Build a WebMacro environment for currentTemplate execution.
 125  
      */
 126  
     public WMEval(Servlet servlet)
 127  0
     {
 128  
         try {
 129  0
             if (servlet == null)
 130  0
                 wm = new WM();
 131  
             else
 132  0
                 wm = new WM(servlet);
 133  0
             init();
 134  0
         } catch (Exception e) {
 135  0
             throw new IllegalStateException(e);
 136  0
         }
 137  0
     }
 138  
 
 139  
     private void init() { 
 140  0
         context = wm.getContext();
 141  0
     }
 142  
     /**
 143  
      * Return the settings associated with this WebMacro instance.
 144  
      */
 145  
     public Settings getSettings ()
 146  
     {
 147  0
         return wm.getBroker().getSettings();
 148  
     }
 149  
 
 150  
     /**
 151  
      * Return the log associated with this instance of WMEval.
 152  
      */
 153  
     public Logger getLog ()
 154  
     {
 155  0
         return _log;
 156  
     }
 157  
 
 158  
     //-------public initializers/destroyers-----
 159  
     /**
 160  
      * Initializes WMEval so that it can perform currentTemplate evaluation
 161  
      * on multiple contexts. Init parses the currentTemplate supplied.
 162  
      * <p>
 163  
      * The argument to init() is the currentTemplate as a stream allowing the 
 164  
      * currentTemplate to come from pretty much anywhere such as a url, 
 165  
      * a file, or a db field.
 166  
      * <p>
 167  
      * Care must be given to the fact that in parsing the currentTemplate, 
 168  
      * the current vm is able to resolve locations of other currentTemplates 
 169  
      * referenced within the supplied currentTemplate.
 170  
      * <p>
 171  
      * Note, once this is complete, the parsed currentTemplate can be applied 
 172  
      * to successive new object contexts. In other words, the application context
 173  
      * can assert new objects for currentTemplate application and remove others.
 174  
      * 
 175  
      * @param template The stream containing the top-level, unparsed currentTemplate.
 176  
      *
 177  
      */
 178  
     public Template init (InputStream template) throws Exception
 179  
     {
 180  0
         Template t = new StreamTemplate(wm.getBroker(),
 181  
                 template);
 182  0
         t.parse();
 183  0
         this.currentTemplate = t;
 184  0
         return t;
 185  
     }
 186  
 
 187  
     public void error (String msg, Exception e)
 188  
     {
 189  0
         _log.error(msg, e);
 190  0
     }
 191  
 
 192  
     /**
 193  
      * Provides for a new context to be established.
 194  
      */
 195  
     public Context getNewContext ()
 196  
     {
 197  0
         Context c = wm.getContext();
 198  0
         this.context = c;
 199  0
         return c;
 200  
     }
 201  
 
 202  
     public WebContext getNewContext (HttpServletRequest req,
 203  
             HttpServletResponse resp)
 204  
     {
 205  0
         WebContext c = wm.getWebContext(req, resp);
 206  0
         this.context = c;
 207  0
         return c;
 208  
     }
 209  
 
 210  
     /**
 211  
      * Gets the current context.
 212  
      */
 213  
     public Context getCurrentContext ()
 214  
     {
 215  0
         return this.context;
 216  
     }
 217  
 
 218  
     /**
 219  
      * Gets the current template.
 220  
      */
 221  
     public Template getCurrentTemplate ()
 222  
     {
 223  0
         return this.currentTemplate;
 224  
     }
 225  
 
 226  
     /**
 227  
      * A convenience method to find and parse a template in the local template path.
 228  
      * FIXME Do not set currentTemplate here
 229  
      */
 230  
     public Template parseLocalTemplate (String templateName) throws Exception
 231  
     {
 232  0
         Template t = wm.getTemplate(templateName);
 233  0
         this.currentTemplate = t;
 234  0
         return t;
 235  
     }
 236  
 
 237  
     /**
 238  
      * Supplies the parsed currentTemplate directly.
 239  
      * @param parsedTemplate The currentTemplate parsed possibly from a previous run.
 240  
      */
 241  
     public void setCurrentTemplate (Template parsedTemplate)
 242  
     {
 243  0
         this.currentTemplate = parsedTemplate;
 244  0
     }
 245  
 
 246  
     /**
 247  
      * Supplies a context to be  parsed currentTemplate directly.
 248  
      * @param c The context to be used for the evaluation.
 249  
      */
 250  
     public void setCurrentContext (Context c)
 251  
     {
 252  0
         this.context = c;
 253  0
     }
 254  
 
 255  
     /**
 256  
      * Sets the output stream to be different than the default, System.out.
 257  
      * @param out The new output stream for any output during currentTemplate evaluation.
 258  
      */
 259  
     //public void setOutputStream (OutputStream out)
 260  
     //{
 261  
     //    this.out = out;
 262  
     //}
 263  
 
 264  
     /**
 265  
      * Evaluates the context of this instance and the instance's
 266  
      * current template and current output stream using UTF8.
 267  
      */
 268  
     public String eval () throws Exception
 269  
     {
 270  0
         return eval(context, currentTemplate);
 271  
     }
 272  
 
 273  
     /**
 274  
      * Evaluate the context supplied against the current template.
 275  
      * @param context The WebMacro context.
 276  
      */
 277  
     public String eval (Context context) throws Exception
 278  
     {
 279  0
         return eval(context, currentTemplate);
 280  
     }
 281  
 
 282  
     /**
 283  
      * Evaluate the supplied template against the supplied context and 
 284  
      * return the result as a string.
 285  
      */
 286  
     public String eval (Context context, Template template) throws Exception
 287  
     {
 288  0
         return template.evaluateAsString(context);
 289  
     }
 290  
 
 291  
     /**
 292  
      * Evaluates the string template against the current context
 293  
      * and returns the value.
 294  
      * @param templateName The name of the template.
 295  
      * @return The output from the evaluated template
 296  
      */
 297  
     public String eval (String templateName) throws Exception
 298  
     {
 299  0
         return eval(context, templateName, null, null);
 300  
     }
 301  
 
 302  
     /**
 303  
      * Evaluate the named template against the given context
 304  
      * and return the result as a String. 
 305  
      * If an output stream is specified, the return value is 
 306  
      * also written out to the stream.
 307  
      * 
 308  
      * @param templateName The name of the template.
 309  
      * @param out An optional output stream.
 310  
      * @return The output from the evaluated template
 311  
      */
 312  
     public String eval (Context context, String templateName, OutputStream out)
 313  
             throws Exception
 314  
     {
 315  0
         return eval(context, templateName, out, null);
 316  
     }
 317  
 
 318  
     /**
 319  
      * Evaluates the context using a file template sending the output to a disk file.
 320  
      * <p>
 321  
      * This method is the preferred method when an output stream is to be written
 322  
      * as well as the value of the string is to be returned.
 323  
      * 
 324  
      * @param context The context to use.
 325  
      * @param templateName The input template file in the resource path.
 326  
      * @param out The output stream. If null, an attempt will be made to locate 
 327  
      *   the outputstream in the context using the output stream key if
 328  
      *   in the context. If no output stream can be resolved, the method does not
 329  
      *   throw an exception.
 330  
      * @param encoding If null, the platform's encoding will be used.
 331  
      * @return The output from the evaluation of the template.
 332  
      */
 333  
     public String eval (Context context, String templateName, OutputStream out,
 334  
             String encoding) throws Exception
 335  
     {
 336  0
         Template t = wm.getTemplate(templateName);
 337  0
         String value = t.evaluateAsString(context);
 338  
         // output the file
 339  0
         if (out == null) {
 340  0
             String outputFileName = (String) context.get(outputContextKey);
 341  0
             if (outputFileName != null) {
 342  0
                 out = new FileOutputStream(outputFileName);
 343  
             }
 344  
         }
 345  0
         if (out != null) // write it to out
 346  
         {
 347  0
             if (encoding == null) {
 348  0
                 out.write(value.getBytes());
 349  
             } else {
 350  0
                 out.write(value.getBytes(encoding));
 351  
             }
 352  0
             out.close();
 353  
         }
 354  0
         this.currentTemplate = t;
 355  0
         this.context = context;
 356  0
         return value;
 357  
     }
 358  
     /**
 359  
      * Evaluates the string template against a new context and writes
 360  
      * it to the http Response output stream using the proper encoding.
 361  
      * <p>
 362  
      * This is an exceptionally useful method for a servlet to use to
 363  
      * write out a template.
 364  
      * <p>
 365  
      * @param context The WM context to use.
 366  
      * @param templateName The name of the template.
 367  
      * @param resp The servlet response from which the encoding will be derived.
 368  
      * @return The output from the evaluated template.
 369  
      */
 370  
     public String eval (WebContext context, String templateName,
 371  
             HttpServletResponse resp) throws ServletException
 372  
     {
 373  0
         String value = null;
 374  
         try {
 375  0
             resp.setContentType("text/html");
 376  0
             String encoding = wm
 377  
                     .getConfig(WMConstants.TEMPLATE_OUTPUT_ENCODING);
 378  0
             value = eval(context, templateName, resp.getOutputStream(),
 379  
                     encoding);
 380  0
         } catch (Exception e) {
 381  0
             throw new ServletException(e);
 382  0
         }
 383  0
         return value;
 384  
     }
 385  
 
 386  
 
 387  
     /**
 388  
      *  Evaluate the named template against the given context.
 389  
      *  Writes the output to the given output file.
 390  
      *  
 391  
      * @param context the context to evaluate the template against
 392  
      * @param templateName  the name of the template to evaluate
 393  
      * @param outputFileName name of file to output to
 394  
      * @param append whether to apppend output
 395  
      * @param encoding the encoding to use, may be null
 396  
      * @return the String resulting from evaluating the template against the context
 397  
      * @throws Exception
 398  
      */
 399  
     public String eval (Context context, String templateName,
 400  
             String outputFileName, boolean append, String encoding)
 401  
         throws Exception
 402  
     {
 403  0
         OutputStream out = new FileOutputStream(outputFileName, append);
 404  0
         return eval(context, templateName, out, encoding);
 405  
     }
 406  
 
 407  
     /**
 408  
      * Free up resources when no longer needed.
 409  
      */
 410  
     public void destroy ()
 411  
     {
 412  0
         wm = null;
 413  0
         currentTemplate = null;
 414  0
         context = null;
 415  0
     }
 416  
 }