Thanks for sharing the code Llewellyn. You're basically making strategy objects for Velocity parsing. In the past I've done the chaining you describe by just using a map of parameter/values that get passed around and ultimately put in the context. This is more explicit but a little more complex. Not sure which approach is better.

I'm thinking ContextAware and VelocityParser represent a use case for velocity and is probably best off in the user examples in the Wiki. If there's interest from the community in building up the framework, maybe the Tools project might be interested in the long term. But I suggest you start with the Wiki. You can add it here yourself.
http://wiki.apache.org/jakarta-velocity/ContributedCode

I am interested in integrating your TestableUberspector (not as a separate introspector, but as a feature of the current one). If you want to submit a patch against the current introspector (with unit tests, preferably) into Bugzilla, we can take a look at it.

WILL

----- Original Message ----- From: "Llewellyn Falco" <[EMAIL PROTECTED]>
To: "Velocity Developers List" <[email protected]>
Sent: Thursday, June 23, 2005 6:26 PM
Subject: What is ContextAware & VelocityParser


Ok just wanted to explain the 2 nice tools that have been useful to us.
ContextAware and VelocityParser Allow me show a small piece of end code that shows why this is nice.

 /***********************************************************************/
 public MyJavaDocs implements ContextAware
 {
    private Class clazz;
    public MyJavaDocs(Class clazz)
   {
       this.clazz = clazz;
   }

   public String generateHtml()
   {
       return VelocityParser.parseString("someFile.html", this);
   }
   public String generateXml()
   {
       return VelocityParser.parseString("someFile.xml", this);
   }
   public void setupContext(Context context)
   {
       context.put("time", new Date());
       context.put("class", clazz);
   }
 }
 /***********************************************************************/


1) ContextAware

public interface ContextAware
{
 public void setupContext(Context context);
}


The basic idea here is to allow for both a call back from your utility VelocityParser. And to allow for cascading. Imagine an overRidesuch as this.
 /***********************************************************************/
 public MyCopywritedJavaDocs extends MyJavaDocs
 {
   public void setupContext(Context context)
   {
       super.setupContext(context);
       context.put("writer", "Copywrite");
       new SomeUtils().setupContext(context);
   }
}

 /***********************************************************************/


   2) VelocityParser

this boils down to settingUp properties and commons and callbacks for given senariors. it would be generally overridden (it's static but...) per your implementation.

   mine right now has the following functions.
   parseJarFile(String template, ContextAware process)
   parseFile(String template, ContextAware process)
   parseString(String template, ContextAware process)
   parseFile(String template, Properties props , ContextAware process)


here's my full current implementation. My project "WebSiteProject" tends to call WebSiteProjectParser which has simular functions. and i have written ones that have a setup configuration, but either way this stuff is light, merely have an implemation is what counts.

package com.spun.util.velocity;

import java.io.File;
import java.io.StringWriter;
import java.util.Properties;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import com.spun.facilitate.util.Commons;
import com.spun.facilitate.util.Config;
import com.spun.util.ObjectUtils;



public class VelocityParser
{

 /***********************************************************************/

 public static String parseJarFile(String template, ContextAware process)
 {
   Properties props = new Properties();
   if (Config.FORCE_ACTUAL_FILE_INSTEAD_OF_JAR)
   {
props.put("file.resource.loader.path", Config.ALTERNATIVE_TEMPLATE_DIRECTORY + ", " + Config.TEMPLATE_DIRECTORY);
     props.put("file.resource.cache", "" + true);
   }
   else
   {
     props.put("resource.loader", "class");
props.put("class.resource.loader.description", "Velocity Classpath Resource Loader"); props.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
     props.put("class.resource.cache", "" + true);
   }
props.put("runtime.introspector.uberspect", "com.spun.util.velocity.TestableUberspect");
   props.put("velocimacro.context.localscope", "" + true);
props.put("velocimacro.permissions.allow.inline.local.scope", "" + true);
   return parseFile(template, props, process);
 }
 /***********************************************************************/
 public static String parseFile(String template, ContextAware process)
 {
   Properties props = new Properties();
   int pathBreak = template.lastIndexOf(File.separatorChar);
   pathBreak = pathBreak == -1 ? template.length() : pathBreak;
   String path = template.substring(0, pathBreak);
   String file = template.substring(pathBreak + 1);
props.put("runtime.introspector.uberspect", "com.spun.util.velocity.TestableUberspect");
   props.put("file.resource.loader.path", path);
   props.put("velocimacro.context.localscope", "" + true);
props.put("velocimacro.permissions.allow.inline.local.scope", "" + true);
   return parseFile(file, props, process);
 }
 /***********************************************************************/
 public static String parseString(String template, ContextAware process)
 {
   Properties props = new Properties();
   props.put("resource.loader", "class");
props.put("class.resource.loader.class", "com.spun.util.velocity.StringResourceLoader");
   props.put("velocimacro.context.localscope", "" + true);
props.put("runtime.introspector.uberspect", "com.spun.util.velocity.TestableUberspect"); props.put("velocimacro.permissions.allow.inline.local.scope", "" + true);
   return parseFile(template, props, process);
 }

/***********************************************************************/
public static String parseFile(String template, Properties props , ContextAware process)
 {
   try
   {
   props.put("directive.foreach.counter.initial.value", "0");
 Velocity.init(props);
 VelocityContext context = new VelocityContext();
 Template velocityTemplate = Velocity.getTemplate(template);

 process.setupContext(context);
   context.put("config", Config.INSTANCE);
   context.put("commons", Commons.INSTANCE);

 StringWriter out = new StringWriter();
 velocityTemplate.merge(context, out);
   return out.toString();
   }
   catch (Exception e)
   {
     throw ObjectUtils.throwAsError(e);
   }
 }
 /***********************************************************************/
 /***********************************************************************/
}

   enjoy.

   Llewellyn.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to