From: Lane S. <la...@op...> - 2005-08-01 00:59:52
|
Hi Keats, Do you really want to include this in the pending 2.1 release? Have you considered that you now have to document 2 ways to set a property, #properties and #set? Will this confuse a new person to WebMacro? Is your #property ... a big advantage over #set $Object.Property = "foo" It is certainly a nice convenience. Just not sure that its inclusion will improve more than its support and documentation demands will warrant. -Lane Keats Kirsch wrote: > I created a new directive called Properties directive. This can be > handy if you want to set a bunch of properties on an object within a > template; essentially providing a abbreviated, readable syntax. You > can also combine it with the #include directive for processing a > properties file. (Just be careful of comments: use "##" or "# " to > keep them from confusing the parser.) > > I'm attaching the source and I will commit it to the core if folks > agree it is worthy. > > Here's some test WMScript that illustrates the usage: > > ## Test using default object: java.util.Properties > #set $Name="Keats Kirsch" > #set $Age=45 > <h3>\#properties test</h3> > #properties $p { > Name: $Name > Age = $Age > } > My age is $p.Age<br> > My name is $p.Name<br> > ## Test using a pre-existing POJO (non-map) > <h3>More \#properties</h3> > #bean $Cal="java.util.Calendar" scope=static > #set $GCal=$Cal.Instance > Today: $GCal.Time, FirstDayOfWeek: $GCal.FirstDayOfWeek, Lenient: > $GCal.Lenient > <br> > #properties $GCal { > FirstDayOfWeek=0 > Lenient=false > } > Today: $GCal.Time, FirstDayOfWeek: $GCal.FirstDayOfWeek, Lenient: > $GCal.Lenient > <br> > >------------------------------------------------------------------------ > >/* > * Copyright (C) 2005 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.StringTemplate; >import org.webmacro.engine.Variable; >import org.webmacro.servlet.TextTool; > >import java.io.IOException; >import java.util.Hashtable; > >/* > * > * @author Keats Kirsch > * Set properties on an object using Java properties file type syntax > * > */ >public class PropertiesDirective extends Directive >{ > > private static final String DEFAULT_CLASS_NAME = "java.util.Hashtable"; > private static final int PROPS_TARGET = 1; > private static final int PROPS_CLASS = 2; > private static final int PROPS_CLASSNAME = 3; > private static final int PROPS_RESULT = 4; > > private Variable target; > private Object result; > private String _className; > //private boolean asMacro = false; > > private static final ArgDescriptor[] myArgs = > new ArgDescriptor[] { > new LValueArg(PROPS_TARGET), > new OptionalGroup(3), > new KeywordArg(PROPS_CLASS, "class"), > new AssignmentArg(), > new QuotedStringArg(PROPS_CLASSNAME), > new BlockArg(PROPS_RESULT)}; > > private static final DirectiveDescriptor myDescr = > new DirectiveDescriptor("properties", null, myArgs, null); > > public static DirectiveDescriptor getDescriptor() > { > return myDescr; > } > > public PropertiesDirective() > { > } > > public Object build(DirectiveBuilder builder, BuildContext bc) > throws BuildException > { > try > { > target = (Variable) builder.getArg(PROPS_TARGET, bc); > } > catch (ClassCastException e) > { > throw new NotVariableBuildException(myDescr.name, e); > } > _className = (String) builder.getArg(PROPS_CLASSNAME, bc); > if (_className == null) > _className = DEFAULT_CLASS_NAME; > // > > // asMacro = (macroKeyword != null); > result = builder.getArg(PROPS_RESULT, bc); > return this; > } > > public void write(FastWriter out, Context context) > throws PropertyException, IOException > { > > try > { > if (!context.containsKey(target.getName())) > { > // target doesn't exist. Must create. > try > { > Class c = Class.forName(_className); > Object o = c.newInstance(); > target.setValue(context, o); > } > catch (RuntimeException re) > { > throw new PropertyException( > "Failed to create instance of " > + _className > + " for the #properties directive. " > + re, > re); > } > > } > // if (result instanceof Macro && !asMacro) > // target.setValue(context, ((Macro) result).evaluate(context)); > // else > // evaluate result macro > Object o = ((Macro) result).evaluate(context); > String res = (String) ((Macro) result).evaluate(context); > String[] lines = TextTool.getLines(res); > String s, prop, val; > String prefix = "#set $" + target.getVariableName() + "."; > for (int i = 0; i < lines.length; i++) > { > s = lines[i].trim(); > if (s.length() > 0 && !s.startsWith("#")) > { > for (int j = 0; j < s.length(); j++) > { > char ch = s.charAt(j); > if (ch == ':' || ch == '=') > { > prop = s.substring(0, j).trim(); > //TODO check if valid property name? > val = s.substring(j + 1).trim(); > // convert to WM syntax and evaluate > // TODO determine if quotes are needed, i.e., is it a number? > if (val.length() > 0) > { > // try first as a string > s = prefix + prop + "=\"" + val + "\""; > try > { > new StringTemplate( > context.getBroker(), > s).evaluateAsString( > context); > } > catch (WebMacroException wme) > { > // try again without quotes. > s = prefix + prop + "=" + val; > try > { > new StringTemplate(context.getBroker(),s) > .evaluateAsString(context); > } > catch (WebMacroException wme2) > { > // TODO utilize the EEH from the context? > throw new PropertyException("Failed to set property \"" > + prop + "\" to value \"" + val + "\" on variable \"" > + target.getVariableName() + "\" of type " > + target.getClass().getName(), > wme2); > } > } > break; > } > } > } > } > //target.setValue(context, result); > // parse the > } > } > catch (PropertyException e) > { > throw e; > } > catch (Exception e) > { > String errorText = "#properties: Unable to set " + target; > writeWarning(errorText, context, out); > } > } > > public void accept(TemplateVisitor v) > { > v.beginDirective(myDescr.name); > v.visitDirectiveArg("PropertiesClassKeyword", "class"); > v.visitDirectiveArg("PropertiesClassName", _className); > v.visitDirectiveArg("PropertiesTarget", target); > v.visitDirectiveArg("PropertiesValue", result); > v.endDirective(); > } > >} > > -- Lane Sharman Providing Private and SPAM-Free Email http://www.opendoors.com 858-755-2868 |