From: marcel.huijkman <mar...@ra...> - 2005-03-12 07:50:05
|
/* * Copyright (C) 2005. 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); * * 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. * * @author Mike Weerdenburg * * @version 14-01-2005 * */ package org.webmacro.directive; import org.webmacro.*; import org.webmacro.engine.*; /** * EvalStringTemplateDirective allows you to evaluate a string just like it is a include / template against the current context.<p> * * Syntax:<pre> * #EvalStringTemplate $valueToEvaluateAsString [to $variable] *</pre> * */ public class EvalStringTemplateDirective extends Directive { /* the argument is NOT a file, but a string represending the template! */ private static final int PARSE_VALUE = 1; private static final int PARSE_TO = 2; private static final int PARSE_TO_VARIABLE = 3; private Variable _varTarget = null; private static final UndefinedMacro UNDEF = UndefinedMacro.getInstance(); private static final ArgDescriptor[] _args = new ArgDescriptor[] { new StringArg(PARSE_VALUE), new OptionalGroup(2), new KeywordArg(PARSE_TO, "to"), new LValueArg(PARSE_TO_VARIABLE), }; private static final DirectiveDescriptor _desc = new DirectiveDescriptor("evalStringTemplate", null, _args, null); public static DirectiveDescriptor getDescriptor () { return _desc; } // // these values are customized for this directive during build() // /** Logging can be good */ protected Log _log; /** the value as a Macro, if the value arg is a Macro */ protected Macro _macroValue; /** * the name given to the directive by webmacro configuration. */ protected String _directiveName; public final Object build (DirectiveBuilder builder, BuildContext bc) throws BuildException { // Get a log-instance. // In webmacro.properties : LogLevel.directive=DEBUG _log = bc.getLog("directive"); // name of this directive _directiveName = builder.getName(); // if a target provided, then output to the target! if (builder.getArg(PARSE_TO_VARIABLE, bc) != null) { try { _varTarget = (Variable) builder.getArg(PARSE_TO_VARIABLE, bc); } catch (ClassCastException e) { // throw new NotVariableBuildException(myDescr.name, e); } } Object o = builder.getArg(PARSE_VALUE, bc); if (o instanceof Macro) { // The value passed to us was a Macro (needs to be evaluated later). // If u use : #evalStringTemplate $myDatabaseFilledStringToEvaluate _macroValue = (Macro) o; } else { // If it's not a Macro, then generate an BuildException. // If u use : #evalStringTemplate "This is a string with nothing to parse!" throw new BuildException("#" + _directiveName + " was expecting a non-static value to evaluate, example: #" + _directiveName + " \"$myDatabaseFilledStringToEvaluate is very interesting!\""); } return this; } /** * Write out the included file to the specified FastWriter. If the * included file is actually a template, it is evaluated against the * <code>context</code> parameter before being written to the FastWriter */ public void write (FastWriter out, Context context) throws PropertyException { Broker broker = context.getBroker(); String strValue = null; // the value arg passed to us was a Macro, so evaluate and check it now. if (_macroValue != null) { Object obValue = _macroValue.evaluate(context); // Only set the value if the macro provided not is null and not Undefined. if ( (obValue != null) && (obValue != UNDEF) ) { strValue = obValue.toString(); } } if (strValue == null) { throw new PropertyException("#" + _directiveName + " value cannot be undefined or null"); } // Use the current templateName as templateName for the StringTemplate. // exampl. c:/wwwroot/templates/test.wm String templateName = context.getTemplateEvaluationContext()._templateName; // Use the current template location & directive name, so whe can re-trace error's. // exampl. c:/wwwroot/templates/test.wm:46.2 #evalStringTemplate if (templateName.indexOf(" #" + _directiveName) == -1) templateName = context.getCurrentLocation() + " #" + _directiveName; if (_log.loggingDebug()) { _log.debug("#" + _directiveName + " \"valueToEvaluateAsStringTemplate\"" + ((_varTarget == null) ? "" : " to $" + _varTarget.getVariableName())); } if (_log.loggingWarning()) { if (strValue.indexOf("#" + _directiveName) > -1) { // when in debug or warning mode, output a warning if a evalStringTemplate tries to use a evalStringTemplate // there could be situtations where this is desired, but it's good to make // the user aware of what they're doing _log.warning("#" + _directiveName + " uses a #" + _directiveName + ", maybe itself? (endless loop!) at " + context.getCurrentLocation()); } } // Create the new StringTemplate. Template tmplTemplate = new StringTemplate (broker, strValue, templateName); if (_varTarget != null) { // if a target variable provided, then output to the target. _varTarget.setValue(context, tmplTemplate.evaluateAsString(context)); } else { // else output to the specified FastWriter. out.write(tmplTemplate.evaluateAsBytes(out.getEncoding(), context)); } } public void accept (TemplateVisitor v) { v.beginDirective(_desc.name); v.visitDirectiveArg("EvalStringTemplate", _macroValue); if (_varTarget != null) v.visitDirectiveArg("EvalStringTemplateTarget", _varTarget); v.endDirective(); } } |