##### Coverage Report - org.webmacro.directive.EvalDirective

Classes in this File | Line Coverage | Branch Coverage | Complexity
EvalDirective |
5% | 3/60
0% | 0/26
| 5.2;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 |  |
     }