diff --git a/build.xml b/build.xml
index 3f524a3b5..86d24cdaa 100644
--- a/build.xml
+++ b/build.xml
@@ -209,7 +209,9 @@
-
+
+
@@ -220,7 +222,12 @@
-
+
+
+
+
+
+
diff --git a/etc/libs-incl.xml b/etc/libs-incl.xml
index 660649f7b..b3021a384 100644
--- a/etc/libs-incl.xml
+++ b/etc/libs-incl.xml
@@ -14,6 +14,7 @@
+
diff --git a/src/java/com/threerings/presents/tools/GenDObjectTask.java b/src/java/com/threerings/presents/tools/GenDObjectTask.java
index a065d828d..039461bb6 100644
--- a/src/java/com/threerings/presents/tools/GenDObjectTask.java
+++ b/src/java/com/threerings/presents/tools/GenDObjectTask.java
@@ -27,15 +27,15 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
import java.io.File;
import java.io.IOException;
-import java.io.StringWriter;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
-import org.apache.velocity.VelocityContext;
import com.google.common.collect.Lists;
import com.samskivert.util.StringUtil;
@@ -129,16 +129,16 @@ public class GenDObjectTask extends GenTask
Class> ftype = f.getType();
String fname = f.getName();
- // create our velocity context
- VelocityContext ctx = new VelocityContext();
- ctx.put("field", fname);
- ctx.put("generated", GenUtil.getGeneratedAnnotation(getClass(), 4, false));
- ctx.put("type", GenUtil.simpleName(f));
- ctx.put("wrapfield", GenUtil.boxArgument(ftype, "value"));
- ctx.put("wrapofield", GenUtil.boxArgument(ftype, "ovalue"));
- ctx.put("clonefield", GenUtil.cloneArgument(_dsclass, f, "value"));
- ctx.put("capfield", StringUtil.unStudlyName(fname).toUpperCase());
- ctx.put("upfield", StringUtil.capitalize(fname));
+ // create a map to hold our template data
+ Map data = new HashMap();
+ data.put("field", fname);
+ data.put("generated", GenUtil.getGeneratedAnnotation(getClass(), 4, false));
+ data.put("type", GenUtil.simpleName(f));
+ data.put("wrapfield", GenUtil.boxArgument(ftype, "value"));
+ data.put("wrapofield", GenUtil.boxArgument(ftype, "ovalue"));
+ data.put("clonefield", GenUtil.cloneArgument(_dsclass, f, "value"));
+ data.put("capfield", StringUtil.unStudlyName(fname).toUpperCase());
+ data.put("upfield", StringUtil.capitalize(fname));
// determine the type of transport
TransportHint hint = f.getAnnotation(TransportHint.class);
@@ -155,14 +155,14 @@ public class GenDObjectTask extends GenTask
" com.threerings.presents.net.Transport.Type." +
hint.type().name() + ", " + hint.channel() + ")";
}
- ctx.put("transport", transport);
+ data.put("transport", transport);
// if this field is an array, we need its component types
if (ftype.isArray()) {
Class> etype = ftype.getComponentType();
- ctx.put("elemtype", GenUtil.simpleName(etype));
- ctx.put("wrapelem", GenUtil.boxArgument(etype, "value"));
- ctx.put("wrapoelem", GenUtil.boxArgument(etype, "ovalue"));
+ data.put("elemtype", GenUtil.simpleName(etype));
+ data.put("wrapelem", GenUtil.boxArgument(etype, "value"));
+ data.put("wrapoelem", GenUtil.boxArgument(etype, "ovalue"));
}
// if this field is a generic DSet, we need its bound type
@@ -175,10 +175,10 @@ public class GenDObjectTask extends GenTask
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)t;
if (pt.getActualTypeArguments().length > 0) {
- ctx.put("etype", GenUtil.simpleName(pt.getActualTypeArguments()[0]));
+ data.put("etype", GenUtil.simpleName(pt.getActualTypeArguments()[0]));
}
} else {
- ctx.put("etype", "DSet.Entry");
+ data.put("etype", "DSet.Entry");
}
}
@@ -190,19 +190,13 @@ public class GenDObjectTask extends GenTask
tname = "oidlist.tmpl";
}
- // now generate our bits
- StringWriter fwriter = new StringWriter();
- StringWriter mwriter = new StringWriter();
- _velocity.mergeTemplate(NAME_TMPL, "UTF-8", ctx, fwriter);
- _velocity.mergeTemplate(BASE_TMPL + tname, "UTF-8", ctx, mwriter);
-
- // and append them as appropriate to the string buffers
+ // append the merged templates as appropriate to the string buffers
if (ii > 0) {
fsection.append("\n");
msection.append("\n");
}
- fsection.append(fwriter.toString());
- msection.append(mwriter.toString());
+ fsection.append(mergeTemplate(NAME_TMPL, data));
+ msection.append(mergeTemplate(BASE_TMPL + tname, data));
}
// now bolt everything back together into a class declaration
diff --git a/src/java/com/threerings/presents/tools/GenReceiverTask.java b/src/java/com/threerings/presents/tools/GenReceiverTask.java
index 36da3e39e..77e6ba602 100644
--- a/src/java/com/threerings/presents/tools/GenReceiverTask.java
+++ b/src/java/com/threerings/presents/tools/GenReceiverTask.java
@@ -28,12 +28,9 @@ import java.util.Iterator;
import java.util.List;
import java.io.File;
-import java.io.StringWriter;
import com.google.common.collect.Iterators;
-import org.apache.velocity.VelocityContext;
-
import com.samskivert.util.ComparableArrayList;
import com.samskivert.util.StringUtil;
@@ -113,25 +110,20 @@ public class GenReceiverTask extends InvocationTask
checkedAdd(implist, rpackage + "." + rname);
implist.sort();
- VelocityContext ctx = new VelocityContext();
- ctx.put("name", name);
- ctx.put("package", spackage);
- ctx.put("methods", methods);
- ctx.put("imports", implist);
-
- StringWriter sw = new StringWriter();
- _velocity.mergeTemplate(SENDER_TMPL, "UTF-8", ctx, sw);
-
// determine the path to our sender file
String mpath = source.getPath();
mpath = mpath.replace("Receiver", "Sender");
mpath = replacePath(mpath, "/client/", "/server/");
- writeFile(mpath, sw.toString());
+ writeFile(mpath, mergeTemplate(SENDER_TMPL,
+ "name", name,
+ "package", spackage,
+ "methods", methods,
+ "imports", implist));
}
protected void generateDecoder (Class> receiver, File source, String rname, String rpackage,
- List methods, Iterator imports, String rcode)
- throws Exception
+ List methods, Iterator imports,
+ String rcode) throws Exception
{
String name = rname.replace("Receiver", "");
@@ -141,20 +133,15 @@ public class GenReceiverTask extends InvocationTask
checkedAdd(implist, InvocationDecoder.class.getName());
implist.sort();
- VelocityContext ctx = new VelocityContext();
- ctx.put("name", name);
- ctx.put("receiver_code", rcode);
- ctx.put("package", rpackage);
- ctx.put("methods", methods);
- ctx.put("imports", implist);
-
- StringWriter sw = new StringWriter();
- _velocity.mergeTemplate(DECODER_TMPL, "UTF-8", ctx, sw);
-
// determine the path to our sender file
String mpath = source.getPath();
mpath = mpath.replace("Receiver", "Decoder");
- writeFile(mpath, sw.toString());
+ writeFile(mpath, mergeTemplate(DECODER_TMPL,
+ "name", name,
+ "receiver_code", rcode,
+ "package", rpackage,
+ "methods", methods,
+ "imports", implist));
}
/** Specifies the path to the sender template. */
diff --git a/src/java/com/threerings/presents/tools/GenServiceTask.java b/src/java/com/threerings/presents/tools/GenServiceTask.java
index 608cc6685..54a1f6c78 100644
--- a/src/java/com/threerings/presents/tools/GenServiceTask.java
+++ b/src/java/com/threerings/presents/tools/GenServiceTask.java
@@ -24,12 +24,11 @@ package com.threerings.presents.tools;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import java.io.File;
-import java.io.StringWriter;
-
-import org.apache.velocity.VelocityContext;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
@@ -260,7 +259,7 @@ public class GenServiceTask extends InvocationTask
// remove imports in our own package
imports.removeSamePackage(mpackage);
- VelocityContext ctx = new VelocityContext();
+ Map ctx = new HashMap();
ctx.put("name", name);
ctx.put("generated", getGeneratedAnnotation(name));
ctx.put("package", mpackage);
@@ -272,10 +271,7 @@ public class GenServiceTask extends InvocationTask
String mpath = source.getPath();
mpath = mpath.replace("Service", "Marshaller");
mpath = replacePath(mpath, "/client/", "/data/");
-
- StringWriter sw = new StringWriter();
- _velocity.mergeTemplate(MARSHALLER_TMPL, "UTF-8", ctx, sw);
- writeFile(mpath, sw.toString());
+ writeFile(mpath, mergeTemplate(MARSHALLER_TMPL, ctx));
// if we're not configured with an ActionScript source root, don't generate the
// ActionScript versions
@@ -345,9 +341,7 @@ public class GenServiceTask extends InvocationTask
// generate an ActionScript version of our marshaller
String ampath = _asroot + File.separator + mppath + File.separator + mname + ".as";
- sw = new StringWriter();
- _velocity.mergeTemplate(AS_MARSHALLER_TMPL, "UTF-8", ctx, sw);
- writeFile(ampath, sw.toString());
+ writeFile(ampath, mergeTemplate(AS_MARSHALLER_TMPL, ctx));
// ----------- Part III - as listener marshallers
@@ -382,11 +376,9 @@ public class GenServiceTask extends InvocationTask
ctx.put("imports", imports.toList());
ctx.put("listener", listener);
- sw = new StringWriter();
- _velocity.mergeTemplate(AS_LISTENER_MARSHALLER_TMPL, "UTF-8", ctx, sw);
String aslpath = _asroot + File.separator + mppath +
File.separator + mname + "_" + listener.getName() + "Marshaller.as";
- writeFile(aslpath, sw.toString());
+ writeFile(aslpath, mergeTemplate(AS_LISTENER_MARSHALLER_TMPL, ctx));
}
// ----------- Part IV - as service
@@ -433,9 +425,7 @@ public class GenServiceTask extends InvocationTask
// generate an ActionScript version of our service
String aspath = _asroot + File.separator + sppath + File.separator + sname + ".as";
- sw = new StringWriter();
- _velocity.mergeTemplate(AS_SERVICE_TMPL, "UTF-8", ctx, sw);
- writeFile(aspath, sw.toString());
+ writeFile(aspath, mergeTemplate(AS_SERVICE_TMPL, ctx));
// ----------- Part V - as service listeners
Class> isil = InvocationService.InvocationListener.class;
@@ -470,20 +460,14 @@ public class GenServiceTask extends InvocationTask
ctx.put("imports", imports.toList());
ctx.put("listener", listener);
- sw = new StringWriter();
- _velocity.mergeTemplate(AS_LISTENER_SERVICE_TMPL, "UTF-8", ctx, sw);
String aslpath = _asroot + File.separator + sppath +
- File.separator + sname + "_" +
- listener.getName() + "Listener.as";
- writeFile(aslpath, sw.toString());
+ File.separator + sname + "_" + listener.getName() + "Listener.as";
+ writeFile(aslpath, mergeTemplate(AS_LISTENER_SERVICE_TMPL, ctx));
if (_aslistenerAdapters.contains(sname)) {
- sw = new StringWriter();
- _velocity.mergeTemplate(AS_LISTENER_ADAPTER_SERVICE_TMPL, "UTF-8", ctx, sw);
String aslapath = _asroot + File.separator + sppath +
- File.separator + sname + "_" +
- listener.getName() + "ListenerAdapter.as";
- writeFile(aslapath, sw.toString());
+ File.separator + sname + "_" + listener.getName() + "ListenerAdapter.as";
+ writeFile(aslapath, mergeTemplate(AS_LISTENER_ADAPTER_SERVICE_TMPL, ctx));
}
}
}
@@ -534,22 +518,16 @@ public class GenServiceTask extends InvocationTask
// remove imports in our own package
imports.removeSamePackage(dpackage);
- VelocityContext ctx = new VelocityContext();
- ctx.put("name", name);
- ctx.put("generated", getGeneratedAnnotation(name));
- ctx.put("package", dpackage);
- ctx.put("methods", sdesc.methods);
- ctx.put("imports", imports.toList());
-
- StringWriter sw = new StringWriter();
- _velocity.mergeTemplate(DISPATCHER_TMPL, "UTF-8", ctx, sw);
-
// determine the path to our marshaller file
String mpath = source.getPath();
mpath = mpath.replace("Service", "Dispatcher");
mpath = replacePath(mpath, "/client/", "/server/");
-
- writeFile(mpath, sw.toString());
+ writeFile(mpath, mergeTemplate(DISPATCHER_TMPL,
+ "name", name,
+ "generated", getGeneratedAnnotation(name),
+ "package", dpackage,
+ "methods", sdesc.methods,
+ "imports", imports.toList()));
}
protected void generateProvider (File source, ServiceDescription sdesc)
@@ -593,23 +571,17 @@ public class GenServiceTask extends InvocationTask
// remove imports in our own package
imports.removeSamePackage(mpackage);
- VelocityContext ctx = new VelocityContext();
- ctx.put("name", name);
- ctx.put("generated", getGeneratedAnnotation(name));
- ctx.put("package", mpackage);
- ctx.put("methods", sdesc.methods);
- ctx.put("listeners", sdesc.listeners);
- ctx.put("imports", imports.toList());
-
- StringWriter sw = new StringWriter();
- _velocity.mergeTemplate(PROVIDER_TMPL, "UTF-8", ctx, sw);
-
// determine the path to our provider file
String mpath = source.getPath();
mpath = mpath.replace("Service", "Provider");
mpath = replacePath(mpath, "/client/", "/server/");
-
- writeFile(mpath, sw.toString());
+ writeFile(mpath, mergeTemplate(PROVIDER_TMPL,
+ "name", name,
+ "generated", getGeneratedAnnotation(name),
+ "package", mpackage,
+ "methods", sdesc.methods,
+ "listeners", sdesc.listeners,
+ "imports", imports.toList()));
}
/**
diff --git a/src/java/com/threerings/presents/tools/GenTask.java b/src/java/com/threerings/presents/tools/GenTask.java
index 52f37b1bd..b3a9f1153 100644
--- a/src/java/com/threerings/presents/tools/GenTask.java
+++ b/src/java/com/threerings/presents/tools/GenTask.java
@@ -21,11 +21,17 @@
package com.threerings.presents.tools;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.ClasspathUtils;
+
+import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import com.samskivert.velocity.VelocityUtil;
@@ -60,6 +66,49 @@ public abstract class GenTask extends Task
((AntClassLoader)_cloader).setParent(getClass().getClassLoader());
}
+ /**
+ * Merges the specified template using the supplied mapping of keys to objects.
+ *
+ * @param data a series of key, value pairs where the keys must be strings and the values can
+ * be any object.
+ */
+ protected String mergeTemplate (String template, Object... data)
+ throws Exception
+ {
+ VelocityContext ctx = new VelocityContext();
+ for (int ii = 0; ii < data.length; ii += 2) {
+ ctx.put((String)data[ii], data[ii+1]);
+ }
+ return mergeTemplate(template, ctx);
+ }
+
+ /**
+ * Merges the specified template using the supplied mapping of string keys to objects.
+ *
+ * @return a string containing the merged text.
+ */
+ protected String mergeTemplate (String template, Map data)
+ throws Exception
+ {
+ VelocityContext ctx = new VelocityContext();
+ for (Map.Entry entry : data.entrySet()) {
+ ctx.put(entry.getKey(), entry.getValue());
+ }
+ return mergeTemplate(template, ctx);
+ }
+
+ /**
+ * A helper function for {@link #mergeTemplate(String, Map)} and friends. Don't
+ * use this directly as you'll end up depending on Velocity and your code won't build.
+ */
+ protected String mergeTemplate (String template, VelocityContext ctx)
+ throws Exception
+ {
+ StringWriter writer = new StringWriter();
+ _velocity.mergeTemplate(template, "UTF-8", ctx, writer);
+ return writer.toString();
+ }
+
protected Class> loadClass (String name)
{
if (_cloader == null) {
@@ -81,6 +130,7 @@ public abstract class GenTask extends Task
/** Used to do our own classpath business. */
protected ClassLoader _cloader;
- /** Used to generate source files from templates. */
+ /** Used to generate source files from templates. Don't use this directly from derived classes,
+ * use {@link #mergeTemplate}. */
protected VelocityEngine _velocity;
}