#properties directive
Keats Kirsch <[email protected]> Sat, 30 Jul 2005 16:33:47 -0400
| Newsgroups | gmane.comp.java.webmacro.user |
|---|---|
| Message-ID | <[email protected]> |
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>
PropertiesDirective.java
(text/plain, 6.4 KB)
/*
* 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();
}
}