Re: #properties directive
Lane Sharman <[email protected]> Sun, 31 Jul 2005 16:17:31 -0700
| Newsgroups | gmane.comp.java.webmacro.user |
|---|---|
| Message-ID | <[email protected]> |
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