From: <ke...@us...> - 2003-07-23 19:20:34
|
Update of /cvsroot/webmacro/webmacro/src/org/webmacro/directive In directory sc8-pr-cvs1:/tmp/cvs-serv7991 Added Files: EvalDirective.java TempletDirective.java Log Message: initial commit of #eval and #templet directives --- NEW FILE: EvalDirective.java --- /* * EvalDirective.java * * Created on May 12, 2003, 2:25 PM * * Copyright (C) 1998-2003 Semiotek Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted under the terms of either of the following * Open Source licenses: * * The GNU General Public License, version 2, or any later version, as * published by the Free Software Foundation * (http://www.fsf.org/copyleft/gpl.html); * * or * * The Semiotek Public License (http://webmacro.org/LICENSE.) * * This software is provided "as is", with NO WARRANTY, not even the * implied warranties of fitness to purpose, or merchantability. You * assume all risks and liabilities associated with its use. * * See www.webmacro.org for more information on the WebMacro project. */ package org.webmacro.directive; import org.webmacro.*; import org.webmacro.engine.BuildContext; import org.webmacro.engine.BuildException; import org.webmacro.engine.Variable; import org.webmacro.directive.*; /** * * @author kkirsch * Usage: * #eval $macroVar * or * #eval $macroVar using $mapVar * */ public class EvalDirective extends org.webmacro.directive.Directive { private static final int EVAL_VAR = 1; private static final int EVAL_USING = 2; private static final int EVAL_MAP_EXPR = 3; private static final int MAX_RECURSION_DEPTH = 100; //private Macro _evalMacro; private Variable _evalTarget; private Object _mapExpr = null; private static final ArgDescriptor[] myArgs = new ArgDescriptor[] { new LValueArg(EVAL_VAR), new OptionalGroup(2), new KeywordArg(EVAL_USING, "using"), new RValueArg(EVAL_MAP_EXPR) }; private static final DirectiveDescriptor myDescr = new DirectiveDescriptor("eval", null, myArgs, null); public static DirectiveDescriptor getDescriptor() { return myDescr; } /** Creates a new instance of EvalDirective */ public EvalDirective() { } public Object build(DirectiveBuilder builder, BuildContext bc) throws BuildException { try { _evalTarget = (Variable)builder.getArg(EVAL_VAR, bc); //_evalMacro = (Macro)o; } catch (ClassCastException e) { throw new NotVariableBuildException(myDescr.name, e); } if (builder.getArg(EVAL_USING) != null) { // "using" keyword specified, get map expression _mapExpr = builder.getArg(EVAL_MAP_EXPR, bc); } //_result = (org.webmacro.engine.Block)builder.getArg(TEMPLET_RESULT, bc); return this; } public void write(org.webmacro.FastWriter out, org.webmacro.Context context) throws org.webmacro.PropertyException, java.io.IOException { try { String s = null; Context c = null; Macro macro = (Macro)_evalTarget.getValue(context); if (_mapExpr == null) { // no map specified, use current context s = (String)macro.evaluate(context); } else { Object o = _mapExpr; if (o instanceof Macro) { o = ((Macro)o).evaluate(context); } if (!(o instanceof java.util.Map)) { throw new PropertyException("The supplied expression did not evaluate to a java.util.Map instance."); } // check for max recursion int recursionDepth = 0; if (context.containsKey("EvalDepth")) { // check the value try { recursionDepth = ((Integer)context.get("EvalDepth")).intValue(); recursionDepth++; if (recursionDepth > MAX_RECURSION_DEPTH) { throw new PropertyException( "ERROR: A recursive call to #eval exceeded the maximum depth of " + MAX_RECURSION_DEPTH); } } catch (Exception e){ // something bad happend, leave depth at default } } java.util.Map outerVars = null; if (context.containsKey("OuterVars")) { // check the value try { outerVars = (java.util.Map)context.get("OuterVars"); } catch (Exception e){ // something bad happend, use vars from calling context } } if (outerVars == null) outerVars = context.getMap(); c = new Context(context.getBroker()); // replace _variables map with supplied map c.setMap((java.util.Map)o); // put current depth into the new context c.put("EvalDepth", recursionDepth); // add a reference to parent context variables c.put("OuterVars", outerVars); // add a reference to this macro c.put("Self", macro); s = (String)macro.evaluate(c); } out.write(s); } catch (Exception e) { if (e instanceof PropertyException) throw e; throw new PropertyException("#eval: Unable to evaluate macro.", e); } } public void accept(TemplateVisitor v) { v.beginDirective(myDescr.name); v.visitDirectiveArg("EvalTarget", _evalTarget); if (_mapExpr != null){ v.visitDirectiveArg("EvalKeyword", "using"); v.visitDirectiveArg("EvalMap", _mapExpr); } v.endDirective(); } } --- NEW FILE: TempletDirective.java --- /* * TempletDirective.java * * Created on May 12, 2003, 2:25 PM * * Copyright (C) 1998-2003 Semiotek Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted under the terms of either of the following * Open Source licenses: * * The GNU General Public License, version 2, or any later version, as * published by the Free Software Foundation * (http://www.fsf.org/copyleft/gpl.html); * * or * * The Semiotek Public License (http://webmacro.org/LICENSE.) * * This software is provided "as is", with NO WARRANTY, not even the * implied warranties of fitness to purpose, or merchantability. You * assume all risks and liabilities associated with its use. * * See www.webmacro.org for more information on the WebMacro project. */ package org.webmacro.directive; import org.webmacro.*; import org.webmacro.engine.BuildContext; import org.webmacro.engine.BuildException; import org.webmacro.engine.Variable; import org.webmacro.directive.*; /** This directive allows a block within a template to be reused * as a "templet" that can be invoked using the #eval directive. * @author Keats Kirsch * @since June 2003 * @see org.webmacro.directive.EvalDirective */ public class TempletDirective extends org.webmacro.directive.Directive { private static final int TEMPLET_TARGET = 1; private static final int TEMPLET_RESULT = 2; private Variable _target; private org.webmacro.engine.Block _result; static private org.webmacro.servlet.TemplateTool _templateTool; private static final ArgDescriptor[] myArgs = new ArgDescriptor[] { new LValueArg(TEMPLET_TARGET), new BlockArg(TEMPLET_RESULT) }; private static final DirectiveDescriptor myDescr = new DirectiveDescriptor("templet", null, myArgs, null); /** Returns the descriptor for this directive * @return the directive descriptor */ public static DirectiveDescriptor getDescriptor() { return myDescr; } /** Creates a new instance of TempletDirective */ public TempletDirective() { } /** Build the directive. Parses the block and saves it. * @param builder The Builder * @param bc The BuildContext * @throws BuildException when directive cannot build its arguments, * e.g., when the first argument is not a valid lval. * @return the built directive */ public Object build(DirectiveBuilder builder, BuildContext bc) throws BuildException { try { _target = (Variable) builder.getArg(TEMPLET_TARGET, bc); } catch (ClassCastException e) { throw new NotVariableBuildException(myDescr.name, e); } _result = (org.webmacro.engine.Block)builder.getArg(TEMPLET_RESULT, bc); // store the variable name in the block for debugging _result.setTemplateName(_target.getVariableName()); return this; } /** Do nothing. This directive is completely evaluated * at build time. * @param out the FastWriter * @param context the Context * @throws PropertyException N/A * @throws IOException N/A */ public void write(org.webmacro.FastWriter out, org.webmacro.Context context) throws org.webmacro.PropertyException, java.io.IOException { try { _target.setValue(context, _result); } catch (PropertyException e) { throw e; } catch (Exception e) { String errorText = "#templet: Unable to set " + _target; if (!(e instanceof PropertyException)) { throw new PropertyException(errorText, e); } else throw (PropertyException)e; //writeWarning(errorText, context, out); } } /** Used by template visitors * @param v a template vistor */ public void accept(TemplateVisitor v) { v.beginDirective(myDescr.name); v.visitDirectiveArg("TempletTarget", _target); v.visitDirectiveArg("TempletValue", _result); v.endDirective(); } } |