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 java.io;
   56   import java.util;
   57   
   58   import freemarker.template;
   59   
   60   /**
   61    * An element for the unified macro/transform syntax. 
   62    */
   63   final class UnifiedCall extends TemplateElement {
   64   
   65       private Expression nameExp;
   66       private Map namedArgs;
   67       private List positionalArgs, bodyParameterNames;
   68       boolean legacySyntax;
   69   
   70       UnifiedCall(Expression nameExp,
   71            Map namedArgs,
   72            TemplateElement nestedBlock,
   73            List bodyParameterNames) 
   74       {
   75           this.nameExp = nameExp;
   76           this.namedArgs = namedArgs;
   77           this.nestedBlock = nestedBlock;
   78           this.bodyParameterNames = bodyParameterNames;
   79       }
   80   
   81       UnifiedCall(Expression nameExp,
   82            List positionalArgs,
   83            TemplateElement nestedBlock,
   84            List bodyParameterNames) 
   85       {
   86           this.nameExp = nameExp;
   87           this.positionalArgs = positionalArgs;
   88           if (nestedBlock == TextBlock.EMPTY_BLOCK) {
   89               nestedBlock = null;
   90           }
   91           this.nestedBlock = nestedBlock;
   92           this.bodyParameterNames = bodyParameterNames;
   93       }
   94   
   95   
   96       void accept(Environment env) throws TemplateException, IOException {
   97           TemplateModel tm = nameExp.getAsTemplateModel(env);
   98           if (tm == Macro.DO_NOTHING_MACRO) return; // shortcut here.
   99           if (tm instanceof Macro) {
  100               Macro macro = (Macro) tm;
  101               if (macro.isFunction && !legacySyntax) {
  102                   throw new TemplateException("Routine " + macro.getName() + 
  103                           " is a function. A function can only be called " +
  104                           "within the evaluation of an expression.", env);
  105               }    
  106               env.visit(macro, namedArgs, positionalArgs, bodyParameterNames,
  107                       nestedBlock);
  108           }
  109           else {
  110               boolean isDirectiveModel = tm instanceof TemplateDirectiveModel; 
  111               if (isDirectiveModel || tm instanceof TemplateTransformModel) {
  112                   Map args;
  113                   if (namedArgs != null && !namedArgs.isEmpty()) {
  114                       args = new HashMap();
  115                       for (Iterator it = namedArgs.entrySet().iterator(); it.hasNext();) {
  116                           Map.Entry entry = (Map.Entry) it.next();
  117                           String key = (String) entry.getKey();
  118                           Expression valueExp = (Expression) entry.getValue();
  119                           TemplateModel value = valueExp.getAsTemplateModel(env);
  120                           args.put(key, value);
  121                       }
  122                   } else {
  123                       args = EmptyMap.instance;
  124                   }
  125                   if(isDirectiveModel) {
  126                       env.visit(nestedBlock, (TemplateDirectiveModel) tm, args, 
  127                               bodyParameterNames);
  128                   }
  129                   else { 
  130                       env.visit(nestedBlock, (TemplateTransformModel) tm, args);
  131                   }
  132               }
  133               else if (tm == null) {
  134                   throw new InvalidReferenceException(this.getStartLocation() + " " +
  135                           nameExp + " not found.", env);
  136               } else {
  137                   throw new TemplateException(getStartLocation() + ": " + nameExp + 
  138                           " is not a user-defined directive. It is a " + 
  139                           tm.getClass().getName(), env);
  140               }
  141           }
  142       }
  143   
  144       public String getCanonicalForm() {
  145           StringBuffer buf = new StringBuffer("<@");
  146           buf.append(nameExp.getCanonicalForm());
  147           if (positionalArgs != null) {
  148               for (int i=0; i<positionalArgs.size(); i++) {
  149                   Expression arg = (Expression) positionalArgs.get(i);
  150                   if (i!=0) {
  151                       buf.append(',');
  152                   }
  153                   buf.append(' ');
  154                   buf.append(arg.getCanonicalForm());
  155               }
  156           }
  157           else {
  158               ArrayList keys = new ArrayList(namedArgs.keySet());
  159               Collections.sort(keys);
  160               for (int i=0; i<keys.size();i++) {
  161                   Expression arg = (Expression) namedArgs.get(keys.get(i));
  162                   buf.append(' ');
  163                   buf.append(keys.get(i));
  164                   buf.append('=');
  165                   buf.append(arg.getCanonicalForm());
  166               }
  167           }
  168           if (nestedBlock == null) {
  169               buf.append("/>");
  170           } 
  171           else {
  172               buf.append('>');
  173               buf.append(nestedBlock.getCanonicalForm());
  174               buf.append("</@");
  175               if (nameExp instanceof Identifier || (nameExp instanceof Dot && ((Dot) nameExp).onlyHasIdentifiers())) {
  176                   buf.append(nameExp);
  177               }
  178               buf.append('>');
  179           }
  180           return buf.toString();
  181       }
  182   
  183       public String getDescription() {
  184           return "user-directive " + nameExp;
  185       }
  186   /*
  187       //REVISIT
  188       boolean heedsOpeningWhitespace() {
  189           return nestedBlock == null;
  190       }
  191   
  192       //REVISIT
  193       boolean heedsTrailingWhitespace() {
  194           return nestedBlock == null;
  195       }*/
  196   }

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