Save This Page
Home » freemarker-2.3.13 » freemarker.core » [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.core;
   54   
   55   import freemarker.template;
   56   import freemarker.ext.beans.BeanModel;
   57   
   58   /**
   59    * An abstract class for nodes in the parse tree 
   60    * that represent a FreeMarker expression.
   61    */
   62   abstract public class Expression extends TemplateObject {
   63   
   64       abstract TemplateModel _getAsTemplateModel(Environment env) throws TemplateException;
   65       abstract boolean isLiteral();
   66   
   67       // Used to store a constant return value for this expression. Only if it
   68       // is possible, of course.
   69       
   70       TemplateModel constantValue;
   71   
   72       // Hook in here to set the constant value if possible.
   73       
   74       void setLocation(Template template, int beginColumn, int beginLine, int endColumn, int endLine)
   75       throws
   76           ParseException
   77       {
   78           super.setLocation(template, beginColumn, beginLine, endColumn, endLine);
   79           if (isLiteral()) {
   80               try {
   81                   constantValue = _getAsTemplateModel(null);
   82               } catch (Exception e) {
   83               // deliberately ignore.
   84               }
   85           }
   86       }
   87       
   88       public final TemplateModel getAsTemplateModel(Environment env) throws TemplateException {
   89           return constantValue != null ? constantValue : _getAsTemplateModel(env);
   90       }
   91       
   92       String getStringValue(Environment env) throws TemplateException {
   93           return getStringValue(getAsTemplateModel(env), this, env);
   94       }
   95       
   96       static String getStringValue(TemplateModel referentModel, Expression exp, Environment env)
   97       throws
   98           TemplateException
   99       {
  100           if (referentModel instanceof TemplateNumberModel) {
  101               return env.formatNumber(EvaluationUtil.getNumber((TemplateNumberModel) referentModel, exp, env));
  102           }
  103           if (referentModel instanceof TemplateDateModel) {
  104               TemplateDateModel dm = (TemplateDateModel) referentModel;
  105               return env.formatDate(EvaluationUtil.getDate(dm, exp, env), dm.getDateType());
  106           }
  107           if (referentModel instanceof TemplateScalarModel) {
  108               return EvaluationUtil.getString((TemplateScalarModel) referentModel, exp, env);
  109           }
  110           if(env.isClassicCompatible()) {
  111               if (referentModel instanceof TemplateBooleanModel) {
  112                   return ((TemplateBooleanModel)referentModel).getAsBoolean() ? "true" : "";
  113               }
  114               if (referentModel == null) {
  115                   return "";
  116               }
  117           }
  118           assertNonNull(referentModel, exp, env);
  119           
  120           String msg = "Error " + exp.getStartLocation()
  121                        +"\nExpecting a string, " 
  122                        + (env.isClassicCompatible() ? "boolean, " : "" )
  123                        + "date or number here, Expression " + exp 
  124                        + " is instead a " 
  125                        + referentModel.getClass().getName();
  126           throw new NonStringException(msg, env);
  127       }
  128   
  129       Expression deepClone(String name, Expression subst) {
  130           Expression clone = _deepClone(name, subst);
  131           clone.copyLocationFrom(this);
  132           return clone;
  133       }
  134   
  135       abstract Expression _deepClone(String name, Expression subst);
  136   
  137       boolean isTrue(Environment env) throws TemplateException {
  138           TemplateModel referent = getAsTemplateModel(env);
  139           if (referent instanceof TemplateBooleanModel) {
  140               return ((TemplateBooleanModel) referent).getAsBoolean();
  141           }
  142           if (env.isClassicCompatible()) {
  143               return referent != null && !isEmpty(referent);
  144           }
  145           assertNonNull(referent, this, env);
  146           String msg = "Error " + getStartLocation()
  147                        + "\nExpecting a boolean (true/false) expression here"
  148                        + "\nExpression " + this + " does not evaluate to true/false "
  149                        + "\nit is an instance of " + referent.getClass().getName();
  150           throw new NonBooleanException(msg, env);
  151       }
  152   
  153   
  154       static boolean isEmpty(TemplateModel model) throws TemplateModelException
  155       {
  156           if (model instanceof BeanModel) {
  157               return ((BeanModel) model).isEmpty();
  158           } else if (model instanceof TemplateSequenceModel) {
  159               return ((TemplateSequenceModel) model).size() == 0;
  160           } else if (model instanceof TemplateScalarModel) {
  161               String s = ((TemplateScalarModel) model).getAsString();
  162               return (s == null || s.length() == 0);
  163           } else if (model instanceof TemplateCollectionModel) {
  164               return !((TemplateCollectionModel) model).iterator().hasNext();
  165           } else if (model instanceof TemplateHashModel) {
  166               return ((TemplateHashModel) model).isEmpty();
  167           } else if (model instanceof TemplateNumberModel
  168                   || model instanceof TemplateDateModel
  169                   || model instanceof TemplateBooleanModel) {
  170               return false;
  171           } else {
  172               return true;
  173           }
  174       }
  175   }

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