Coverage Report - org.webmacro.directive.EvalDirective
 
Classes in this File Line Coverage Branch Coverage Complexity
EvalDirective
5%
3/60
0%
0/26
5.2
 
 1  
 /*
 2  
  * EvalDirective.java
 3  
  *
 4  
  * Created on May 12, 2003, 2:25 PM
 5  
  *
 6  
  * Copyright (C) 1998-2003 Semiotek Inc.  All Rights Reserved.
 7  
  *
 8  
  * Redistribution and use in source and binary forms, with or without
 9  
  * modification, are permitted under the terms of either of the following
 10  
  * Open Source licenses:
 11  
  *
 12  
  * The GNU General Public License, version 2, or any later version, as
 13  
  * published by the Free Software Foundation
 14  
  * (http://www.fsf.org/copyleft/gpl.html);
 15  
  *
 16  
  *  or
 17  
  *
 18  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 19  
  *
 20  
  * This software is provided "as is", with NO WARRANTY, not even the
 21  
  * implied warranties of fitness to purpose, or merchantability. You
 22  
  * assume all risks and liabilities associated with its use.
 23  
  *
 24  
  * See www.webmacro.org for more information on the WebMacro project.
 25  
  */
 26  
 
 27  
 package org.webmacro.directive;
 28  
 
 29  
 import org.webmacro.Context;
 30  
 import org.webmacro.Macro;
 31  
 import org.webmacro.PropertyException;
 32  
 import org.webmacro.TemplateVisitor;
 33  
 import org.webmacro.engine.BuildContext;
 34  
 import org.webmacro.engine.BuildException;
 35  
 import org.webmacro.engine.StringMacro;
 36  
 import org.webmacro.engine.Variable;
 37  
 
 38  
 /**
 39  
  * Evaluate an instance of a webmacro target.
 40  
  * <pre>
 41  
  *   #eval $macroVar
 42  
  * or
 43  
  *   #eval $macroVar using $mapVar
 44  
  * </pre>
 45  
  *
 46  
  * @author  kkirsch
 47  
  */
 48  
 
 49  
 public class EvalDirective extends org.webmacro.directive.Directive
 50  
 {
 51  
 
 52  
    private static final int EVAL_EXPR = 1;
 53  
    private static final int EVAL_USING = 2;
 54  
    private static final int EVAL_MAP = 3;
 55  
    private static final int MAX_RECURSION_DEPTH = 100;
 56  
 
 57  
    //private Macro _evalMacro;
 58  
    private Object _evalTarget;
 59  0
    private Object _mapExpr = null;
 60  
 
 61  2
    private static final ArgDescriptor[] myArgs =
 62  
       new ArgDescriptor[] {
 63  
          new RValueArg(EVAL_EXPR),
 64  
          new OptionalGroup(2),
 65  
          new KeywordArg(EVAL_USING, "using"),
 66  
          new RValueArg(EVAL_MAP)};
 67  
 
 68  2
    private static final DirectiveDescriptor myDescr =
 69  
       new DirectiveDescriptor("eval", null, myArgs, null);
 70  
 
 71  
    public static DirectiveDescriptor getDescriptor()
 72  
    {
 73  6
       return myDescr;
 74  
    }
 75  
 
 76  
    /** Creates a new instance of EvalDirective. */
 77  
    public EvalDirective()
 78  0
    {
 79  0
    }
 80  
 
 81  
    public Object build(DirectiveBuilder builder, BuildContext bc)
 82  
       throws BuildException
 83  
    {
 84  0
       _evalTarget = builder.getArg(EVAL_EXPR, bc);
 85  0
       if (builder.getArg(EVAL_USING) != null)
 86  
       {
 87  
          // "using" keyword specified, get map expression
 88  0
          _mapExpr = builder.getArg(EVAL_MAP, bc);
 89  
       }
 90  
       //_result = (org.webmacro.engine.Block)builder.getArg(TEMPLET_RESULT, bc);
 91  0
       return this;
 92  
    }
 93  
 
 94  
    public void write(org.webmacro.FastWriter out, org.webmacro.Context context)
 95  
       throws org.webmacro.PropertyException, java.io.IOException
 96  
    {
 97  
       try
 98  
       {
 99  0
          Macro macro = null;
 100  
 
 101  
          // The target may be:
 102  
          // 1) a variable referencing a Macro
 103  
          // 2) a String to be evaluated as a template
 104  
          // 3) an expression that evaluates into one of the above?
 105  0
          Object targ = _evalTarget;
 106  0
          if (targ instanceof Variable)
 107  
          {
 108  
             // if variable, get it's value
 109  0
             targ = ((Variable) _evalTarget).getValue(context);
 110  
          }
 111  0
          if (targ instanceof String)
 112  
          {
 113  
             // convert string to template
 114  0
             targ = new StringMacro((String) targ);
 115  
          }
 116  0
          if (targ instanceof Macro)
 117  
          {
 118  0
             macro = (Macro) targ;
 119  
          }
 120  
          else
 121  
          {
 122  
             // throw and exception ... we don't know what to do with this!
 123  0
             throw new PropertyException("Invalid argument to #eval directive.  First arg must be a Macro or a String.");
 124  
          }
 125  0
          if (_mapExpr == null)
 126  
          {
 127  
             // no map specified, use current context
 128  0
             macro.write(out, context);
 129  
          }
 130  
          else
 131  
          {
 132  0
             Object argmap = _mapExpr;
 133  0
             if (argmap instanceof Macro)
 134  
             {
 135  0
                argmap = ((Macro) argmap).evaluate(context);
 136  
             }
 137  0
             if (!(argmap instanceof java.util.Map))
 138  
             {
 139  0
                throw new PropertyException("The supplied expression did not evaluate to a java.util.Map instance.");
 140  
             }
 141  
             // check for max recursion
 142  0
             int recursionDepth = 0;
 143  0
             if (context.containsKey("EvalDepth"))
 144  
             { // check the value
 145  
                try
 146  
                {
 147  0
                   recursionDepth =
 148  
                      ((Integer) context.get("EvalDepth")).intValue();
 149  0
                   recursionDepth++;
 150  
                }
 151  0
                catch (Exception e)
 152  
                {
 153  
                   // something bad happend, leave depth at default
 154  0
                }
 155  0
                                         if (recursionDepth > MAX_RECURSION_DEPTH)
 156  
                                         {
 157  0
                                                 throw new PropertyException(
 158  
                                                         "ERROR: A recursive call to #eval exceeded the maximum depth of "
 159  
                                                                 + MAX_RECURSION_DEPTH);
 160  
                                         }
 161  
             }
 162  0
             java.util.Map outerVars = null;
 163  0
             if (context.containsKey("OuterVars"))
 164  
             { // check the value
 165  
                try
 166  
                {
 167  0
                   outerVars = (java.util.Map) context.get("OuterVars");
 168  
                }
 169  0
                catch (Exception e)
 170  
                {
 171  
                   // something bad happened, use vars from calling context
 172  0
                }
 173  
             }
 174  0
             if (outerVars == null)
 175  0
                outerVars = context.getMap();
 176  0
             Context c = new Context(context.getBroker());
 177  
             // replace _variables map with supplied map
 178  0
             c.setMap((java.util.Map) argmap);
 179  
             // put current depth into the new context
 180  0
             c.put("EvalDepth", recursionDepth);
 181  
             // add a reference to parent context variables
 182  0
             c.put("OuterVars", outerVars);
 183  
             // add a reference to this macro
 184  0
             c.put("Self", macro);
 185  0
             macro.write(out, c);
 186  
          }
 187  
       }
 188  0
       catch (Exception e)
 189  
       {
 190  0
          if (e instanceof PropertyException)
 191  0
             throw (PropertyException) e;
 192  0
          throw new PropertyException("#eval: Unable to evaluate macro.", e);
 193  0
       }
 194  0
    }
 195  
 
 196  
    public void accept(TemplateVisitor v)
 197  
    {
 198  0
       v.beginDirective(myDescr.name);
 199  0
       v.visitDirectiveArg("EvalTarget", _evalTarget);
 200  0
       if (_mapExpr != null)
 201  
       {
 202  0
          v.visitDirectiveArg("EvalKeyword", "using");
 203  0
          v.visitDirectiveArg("EvalMap", _mapExpr);
 204  
       }
 205  0
       v.endDirective();
 206  0
    }
 207  
 
 208  
 }