Save This Page
Home » freemarker-2.3.13 » freemarker.template.utility » [javadoc | source]
    1   /*
    2    * Copyright (c) 2003 The Visigoth Software Society. All rights
    3    * reserved.
    4    *
    5    * Redistribution and use in source and binary forms, with or without
    6    * modification, are permitted provided that the following conditions
    7    * are met:
    8    *
    9    * 1. Redistributions of source code must retain the above copyright
   10    *    notice, this list of conditions and the following disclaimer.
   11    *
   12    * 2. Redistributions in binary form must reproduce the above copyright
   13    *    notice, this list of conditions and the following disclaimer in
   14    *    the documentation and/or other materials provided with the
   15    *    distribution.
   16    *
   17    * 3. The end-user documentation included with the redistribution, if
   18    *    any, must include the following acknowledgement:
   19    *       "This product includes software developed by the
   20    *        Visigoth Software Society (http://www.visigoths.org/)."
   21    *    Alternately, this acknowledgement may appear in the software itself,
   22    *    if and wherever such third-party acknowledgements normally appear.
   23    *
   24    * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
   25    *    project contributors may be used to endorse or promote products derived
   26    *    from this software without prior written permission. For written
   27    *    permission, please contact visigoths@visigoths.org.
   28    *
   29    * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
   30    *    nor may "FreeMarker" or "Visigoth" appear in their names
   31    *    without prior written permission of the Visigoth Software Society.
   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 VISIGOTH SOFTWARE SOCIETY OR
   37    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   38    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   39    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   40    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   41    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   42    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   43    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   44    * SUCH DAMAGE.
   45    * ====================================================================
   46    *
   47    * This software consists of voluntary contributions made by many
   48    * individuals on behalf of the Visigoth Software Society. For more
   49    * information on the Visigoth Software Society, please see
   50    * http://www.visigoths.org/
   51    */
   52   
   53   package freemarker.template.utility;
   54   
   55   import freemarker.template;
   56   import freemarker.core.Environment;
   57   import java.io;
   58   import java.util.Map;
   59   
   60   /**
   61    * A transform that captures the output of a block of FTL code and stores that in a variable.
   62    *
   63    * <p>As this transform is initially present in the shared variable set, you can always
   64    * access it from the templates:</p>
   65    *
   66    * <pre>
   67    * &lt;@capture_output var="captured">
   68    *   ...
   69    * &lt;/@capture_output>
   70    * </pre>
   71    *
   72    * <p>And later in the template you can use the captured output:</p>
   73    *
   74    * ${captured}
   75    *
   76    * <p>This transform requires one of three parameters: <code>var</code>, <code>local</code>, or <code>global</code>.
   77    * Each of them specifies the name of the variable that stores the captured output, but the first creates a
   78    * variable in a name-space (as &lt;#assign>), the second creates a macro-local variable (as &lt;#local>),
   79    * and the last creates a global variable (as &lt;#global>).
   80    * </p>
   81    * <p>In the case of an assignment within a namespace, there is an optional parameter
   82    * <code>namespace</code> that indicates in which namespace to do the assignment.
   83    * if this is omitted, the current namespace is used, and this will be, by far, the most
   84    * common usage pattern.</p>
   85    *
   86    * @deprecated Use block-assignments instead, as <code>&lt;assign x>...&lt;/assign></code>.
   87    *
   88    * @version $Id: CaptureOutput.java,v 1.31 2004/01/06 17:06:43 szegedia Exp $
   89    */
   90   public class CaptureOutput implements TemplateTransformModel {
   91   
   92       public Writer getWriter(final Writer out, final Map args) throws TemplateModelException {
   93           String errmsg = "Must specify the name of the variable in "
   94                   + "which to capture the output with the 'var' or 'local' or 'global' parameter.";
   95           if (args == null) throw new TemplateModelException(errmsg);
   96   
   97           boolean local = false, global=false;
   98           final TemplateModel nsModel = (TemplateModel) args.get("namespace");
   99           Object varNameModel = args.get("var");
  100           if (varNameModel == null) {
  101               varNameModel = args.get("local");
  102               if (varNameModel == null) {
  103                   varNameModel = args.get("global");
  104                   global = true;
  105               } else {
  106                   local = true;
  107               }
  108               if (varNameModel == null) {
  109                   throw new TemplateModelException(errmsg);
  110               }
  111           }
  112           if (args.size()==2) {
  113               if (nsModel == null) {
  114                   throw new TemplateModelException("Second parameter can only be namespace");
  115               }
  116               if (local) {
  117                   throw new TemplateModelException("Cannot specify namespace for a local assignment");
  118               }
  119               if (global) {
  120                   throw new TemplateModelException("Cannot specify namespace for a global assignment");
  121               }
  122               if (!(nsModel instanceof Environment.Namespace)) {
  123                   throw new TemplateModelException("namespace parameter does not specify a namespace. It is a " + nsModel.getClass().getName());
  124               }
  125           }
  126           else if (args.size() != 1) throw new TemplateModelException(
  127                   "Bad parameters. Use only one of 'var' or 'local' or 'global' parameters.");
  128   
  129           if(!(varNameModel instanceof TemplateScalarModel)) {
  130               throw new TemplateModelException("'var' or 'local' or 'global' parameter doesn't evaluate to a string");
  131           }
  132           final String varName = ((TemplateScalarModel) varNameModel).getAsString();
  133           if(varName == null) {
  134               throw new TemplateModelException("'var' or 'local' or 'global' parameter evaluates to null string");
  135           }
  136   
  137           final StringBuffer buf = new StringBuffer();
  138           final Environment env = Environment.getCurrentEnvironment();
  139           final boolean localVar = local;
  140           final boolean globalVar = global;
  141   
  142           return new Writer() {
  143   
  144               public void write(char cbuf[], int off, int len) {
  145                   buf.append(cbuf, off, len);
  146               }
  147   
  148               public void flush() throws IOException {
  149                   out.flush();
  150               }
  151   
  152               public void close() throws IOException {
  153                   SimpleScalar result = new SimpleScalar(buf.toString());
  154                   try {
  155                       if (localVar) {
  156                           env.setLocalVariable(varName, result);
  157                       } else if (globalVar) {
  158                           env.setGlobalVariable(varName, result);
  159                       }
  160                       else {
  161                           if (nsModel == null) {
  162                               env.setVariable(varName, result);
  163                           } else {
  164                               ((Environment.Namespace) nsModel).put(varName, result);
  165                           }
  166                       }
  167                   } catch (java.lang.IllegalStateException ise) { // if somebody uses 'local' outside a macro
  168                       throw new IOException("Could not set variable " + varName + ": " + ise.getMessage());
  169                   }
  170               }
  171           };
  172       }
  173   }

Save This Page
Home » freemarker-2.3.13 » freemarker.template.utility » [javadoc | source]