Hi,
Any reference in velocity template starting with a $ is taken from
the context. So your application should do somewhere:
context.put( "Class", new ClassTool() );
context.put( "Context", new ContextTool(context) );
context.put( "date", new java.util.Date() );
The original code is only in the mailing list archives, like:
"EncodeXXX context tools" in the thread
http://marc.theaimsgroup.com/?l=velocity-user&m=97723805517199&w=2
When the CVS repository was migrated to SVN, the contrib
tree was cleaned up and some of these tools were dropped.
I've put it also in the attachment. I don't know if these will go
through the mailing list...
Look for another ClassUtils in the current velocity source tree, or
take it from the SVN repository:
http://svn.apache.org/repos/asf/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/util/ClassUtils.java
Too bad this class has a private constructor, so it cannot be instantiated.
Please make a copy of it with a public constructor and leave the methods
you require, compile it, and make it available to your application (e.g.
put it in the path of WEB-INF/classes).
You will find other goodies from the velocity-tool subproject at:
http://svn.apache.org/repos/asf/jakarta/velocity/tools/trunk/src/java/org/apache/velocity/tools
As a side note for reading files, you can just do:
#set( $text = "#include('filename')" )
only if the file is accessible to the resource loader. In my command
line transformer tool, I have the current directory as the resource
loader path, and thus it works.
Also writing single files can be done with standard std0ut redirection.
P.S. this is all non-MVC use of velocity, but code generation is another
cool use of velocity (e.g. I export CSV from Access-DB and create a
Word-XML document from it with my template tool!).
Cheers,
Christoph
Anagha wrote:
Christoph,
Thanks for suggestions.
Currently I'm using vel-1.4 and tried a sample macro from your script below.
#macro( fileWrite $filename $text )
#set( $out = $Class.newInstance("java.io.FileOutputStream", $filename) )
#set( $data = $text.getBytes() )
#call( $out.write($data) )
#call( $out.close() )
#end
##
#macro( call $foo )#if($foo)#**##end#end
#fileWrite( "SampJava" "intercae ABC{}" )
I'm expecting that a file "SampJava" should be created with the text
"intercae ABC{}" in it.
Here I see "Class: variable is not set.
This is not working, Pls have a look for this macro.
Also, in vel-1.4 I did see "ContextTool" class, pls. let me know its
package.
Thanks,
Anagha
On 2/7/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
Hi Anagha,
I sometimes use velocity to generate diverse ASCII files from
CSV or other inputs. I use my own TemplateTool that has some
few goodies in the context - like the ClassTool used in the macro
below.
##
------------------------------------------------------------------------
## Macro to write a text to a file.
##
------------------------------------------------------------------------
#macro( fileWrite $filename $text )
#set( $out = $Class.newInstance("java.io.FileOutputStream", $filename)
)
#set( $data = $text.getBytes() )
#call( $out.write($data) )
#call( $out.close() )
#end
##
##
------------------------------------------------------------------------
## convenience directive to invoke a method and ignore the return value
##
------------------------------------------------------------------------
#macro( call $foo )#if($foo)#**##end#end
##
##
------------------------------------------------------------------------
## Some helpful local context tools:
##
------------------------------------------------------------------------
#set( $LF = $Context.formDecode("%0A") )
#set( $Integer = 1 )
#set( $Long = $Integer.longValue() )
#set( $now = $date.clone() )
##
##
------------------------------------------------------------------------
## Some simple formatters
##
------------------------------------------------------------------------
#macro( digits4 $number )#*
*##set( $id = "$number" )#* -- access the macro paramter,
ensure its a String
*##set( $id = "0000$id.trim()" )#* -- prepend the padding, clipping
whitespace artefacts
*##set( $len = $id.length() - 4 )#* -- compute the offset for the rest
length
*#$id.substring($len)## -- emit the resulting padded string
#end
#macro( digits2 $number )#*
*##set( $id = "$number" )#*
*##set( $id = "00$id.trim()" )#*
*##set( $len = $id.length() - 2 )#*
*#$id.substring($len)##
#end
#macro( dateStr $d )#*
*##set( $y = $d.year + 1900 )#*
*##digits4($y)#digits2($d.month)#digits2($d.date)#digits2($d.hours)#digits2($d.minutes)#digits2($d.seconds)##
#end
You can do things like:
## -- read file
#set( $text = "#parse($inputName)" )
#set( $lines = $text.trim().split($LF) )
#foreach( $line in $lines )
...
#end
...
#set( $filename =
"E${statelliteId}_${orderId}_#digits4($nr)_#dateStr($now).ORD" )
writing output to: $filename
#fileWrite( $filename $order )##
This does things that maybe should have been done in perl ;)
Cheers,
Christoph
Anagha wrote:
Hi,
I'm using VTL to build Java file. I need to change/insert some
keywords,
variables in the Java file based on context paramters.
Instead of putting the whole Java file in ".vm" file, can I load the
file in
some test program and put the "File" descriptor in the context?
Later in ".vm" I'll retrieve this file descriptor from context and
output
some lines of the file.
I'have tried in similar way for ".xml' where I load and built Document
object from XML in test program. I put the "root" element of the xml
in the context and later processed the doc in ".vm" by extracting root
from
context.
I want to know can we do on similar lines for File descriptor object.
Any help is welcome.
--
Thanks & Regards,
Anagha
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
--
Thanks & Regards,
Anagha
/*
* $Header: $
* $Revision: 1.0 $
* $Date: 2001/06/13 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.tools;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
/**
* Provides utilities for instantiating classes out of templates.
*
* Company: Deutsches Zentrum fuer Luft- und Raumfahrt
* @author [EMAIL PROTECTED]
*/
public class ClassTool
{
/**
* Empty constructor.
*/
public ClassTool()
{
}
/**
* Returns a class by specifying its name.
*
* @param className The name of the desired class.
* @return The class matching the requested name.
*/
public static Class classForName(String className)
{
try
{
return Class.forName(className);
}
catch( Exception ignore )
{
// ingore and return null
}
return null;
}
/**
* Instantiates a class by specifying its name (via empty constructor).
*
* @param className The name of the class to instantiates.
* @return A new instance of the requested class.
*/
public static Object newInstance(String className) throws Exception
{
Class cls = Class.forName(className);
Class[] params = new Class[0];
try
{
Constructor constructor = cls.getConstructor(params);
return constructor.newInstance( new Object[0] );
} catch (Exception ex) {
Constructor constructor = cls.getDeclaredConstructor(params);
if ( Modifier.isPrivate( constructor.getModifiers() ) )
return cls; // class with static methods
}
return null;
}
/**
* Convenience method which instantiates a class by specifying
* its name and one parameter.
*
* @param className The name of the class to instantiates.
* @param param A single parameters used to call the constructor.
* @return A new instance of the requested class.
*/
public static Object newInstance(String className, Object param)
throws Exception
{
return newInstance( className, new Object[] {param} );
}
/**
* Convenience method which instantiates a class by specifying
* its name and two parameters.
*
* @param className The name of the class to instantiates.
* @param param1 First parameters used to call the constructor.
* @param param2 Second parameters used to call the constructor.
* @return A new instance of the requested class.
*/
public static Object newInstance( String className,
Object param1, Object param2 )
throws Exception
{
return newInstance( className, new Object[] {param1, param2} );
}
/**
* Instantiates a class by specifying its name and parameters.
*
* @param className The name of the class to instantiates.
* @param params Array of parameters used to call the constructor.
* @return A new instance of the requested class.
*/
public static Object newInstance(String className, Object[] params)
throws Exception
{
Class cls = Class.forName(className);
Constructor constructor = getConstructor(cls, params);
return constructor.newInstance(params);
}
/**
* Enhancement of the class objects own getConstructor() which takes
* in consideration subclassing and primitives. The params
* parameter is an array of objects that should be matched
* classwise to the constructors formal parameter types, in declared
* order. If params is null, it is treated as if it were an empty
* array.
*
* @param cls the class to search for a matching constructor
* @param params the array of parameters that will be used to
* invoke the constructor
* @return the Method object of the public constructor that
* matches the above
* @see java.lang.Class#getConstructor(Class[])
**/
public static Constructor getConstructor(Class cls, Object[] params)
{
Constructor[] constructors = cls.getConstructors();
for (int i = 0; i < constructors.length; ++i )
{
Class[] parameterTypes = constructors[i].getParameterTypes();
// The methods we are trying to compare must
// the same number of arguments.
if (parameterTypes.length == params.length)
{
// Make sure the given parameter is a valid
// subclass of the method parameter in question.
for (int j = 0; ; j++)
{
if (j >= parameterTypes.length)
return constructors[i]; // found
Class c = parameterTypes[j];
Object p = params[j];
if ( c.isPrimitive() )
{
try
{
if ( c != p.getClass().getField("TYPE").get(p) )
break;
} catch (Exception ex) {
break; // p is not a primitive derivate
}
}
else if ( (p != null) &&
!c.isAssignableFrom( p.getClass() ) )
break;
} // for all parameters
} // if same length
} // for all contructors
return null;
}
/**
* Get a <code>Method</code> from a <code>Class</code> with the
* requested name which accepts the specified parameters.
*
* @param clazz The <code>Class</code> to whose method is searched.
* @param methodName The name of the desired method.
* @param params The parameters that will be passed when calling
* the method.
*/
public static Method getMethod( Class clazz,
String methodName,
Object[] params )
{
Method[] methods = clazz.getMethods();
Class[] parameterTypes = null;
Method method = null;
int numMethods = methods.length;
for (int i = 0; i < numMethods; ++i)
{
method = methods[i];
parameterTypes = method.getParameterTypes();
// The methods we are trying to compare must
// the same number of arguments.
if (parameterTypes.length == params.length)
{
// Make sure the given parameter is a valid
// subclass of the method parameter in question.
for (int j = 0; ; j++)
{
if (j >= parameterTypes.length)
return method;
Class c = parameterTypes[j];
Object p = params[j];
if ( c.isPrimitive() )
{
try
{
if ( c != p.getClass().getField("TYPE").get(p) )
break;
}
catch (Exception ex)
{
break; // p is not a primitive derivate
}
}
else if ( (p != null) &&
!c.isAssignableFrom( p.getClass() ) )
break;
}
}
}
return null;
}
} // end of ClassTool.java
/*
* $Header: $
* $Revision: 1.0 $
* $Date: 2001/06/13 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.tools;
import java.util.Arrays;
import java.util.Vector;
import java.util.Hashtable;
import java.net.URLEncoder;
import org.apache.velocity.context.Context;
/**
* Provides convenient context utilities for Velocity.
*
* @company Deutsches Zentrum fuer Luft- und Raumfahrt
* @author Christoph.Reck at dlr de
*/
public class ContextTool
{
protected Context context = null;
/**
* Constructor needs a backpointer to the context.
*
* @param context A Context.
*/
public ContextTool(Context context)
{
this.context = context;
}
/**
* Provides transparent access to the container of the
* Context hashtable (e.g. for debug dump).
*
* @return The current web context.
*/
public Context getContext()
{
return context;
}
/**
* Translates a string into <code>x-www-form-urlencoded</code> format.
* This method is just a wrapper to java.net.URLEncoder.encode().
*
* @param str The string to encode.
* @return The URL-encoded string.
* @see java.net.URLEncoder
*/
public static String URLEncode(String str)
{
if (str == null)
return null;
return URLEncoder.encode(str);
}
/**
* Encode the characters <, >, " and & to
* &lt;, &gt;, &quot, &amp; respectively.
* <code><input type="text"
value="$formater.encodeMarkup($anyText)"></code>
*
* @param text The string to encode.
* @return The HTML encoded string.
*/
public static String encodeMarkup(String text)
{
char[] array = text.toCharArray();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < array.length; i++) {
switch (array[i]) {
case '<':
buffer.append("<");
break;
case'>':
buffer.append(">");
break;
case '&':
buffer.append("&");
break;
case '"':
buffer.append(""");
break;
default:
buffer.append(array[i]);
break;
}
}
return buffer.toString();
}
/**
* Encode space to + and any non alphanumeric character to %XX.
* Taken from Apache Cocoon XSPUtil.
*
* @param text The string to encode.
* @return The form encoded string.
*/
public static String formEncode(String text) throws Exception
{
StringBuffer buffer = new StringBuffer();
char[] c = text.toCharArray();
for (int i = 0; i < c.length; i++)
{
if (isAlphaNumeric(c[i]))
{
buffer.append(c[i]);
}
else if (c[i] == ' ')
{
buffer.append('+');
}
else
{
buffer.append('%');
String hex = Integer.toHexString((byte) c[i]).toUpperCase();
if (hex.length() < 2)
buffer.append('0');
buffer.append(hex);
}
}
return buffer.toString();
}
/**
* Decode space from + and %XX to its character from.
* Taken from Apache Cocoon XSPUtil.
*
* @param text The string to decode.
* @return The decoded string.
*/
public static String formDecode(String s) throws Exception
{
StringBuffer sb = new StringBuffer();
for(int i=0; i<s.length(); i++)
{
char c = s.charAt(i);
switch (c)
{
case '+':
sb.append(' ');
break;
case '%':
try
{
sb.append((char)Integer.parseInt(
s.substring(i+1,i+3),16));
}
catch (NumberFormatException e)
{
throw new IllegalArgumentException();
}
i += 2;
break;
default:
sb.append(c);
}
}
// Undo conversion to external encoding
String result = sb.toString();
byte[] inputBytes = result.getBytes("8859_1");
return new String(inputBytes);
}
/**
* Convenience function to check for alphanumeric characters.
* Taken from Apache Cocoon XSPUtil.
*
* @param c The character to check.
* @return true if it is [_A-Za-z0-9].
*/
public static boolean isAlphaNumeric(char c)
{
return c == '_' ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9');
}
/**
* Encodes any non alphanumeric character from a string to make
* it usable as a form variable. Any non alphanumeric is deleted
* from the string and the following character is uppercased.
* A following second non alphanumerics is changed to a '_'.
* A string starting with a numeric is prefixed with a '_'. <p>
* Example <code>1abc.def*.ghI.JKL</code> gets converted to
* <code>_1abcDef_GhI_JKL</code>.
*
* @param text String to encode.
* @return Filtered string.
*/
public static String encodeToName(String text)
{
StringBuffer buffer = new StringBuffer( text.length() );
// ensure the string starts with and alpha character
char c = text.charAt(0);
if ( (c >= '0') && (c <= '9') )
buffer.append('_');
char prev = ' ';
boolean makeUppercase = false;
for (int i = 0; i < text.length(); ++i)
{
c = text.charAt(i);
if (isAlphaNumeric(c))
{
if (makeUppercase)
buffer.append( text.substring(i, i+1).toUpperCase() );
else
buffer.append(c);
makeUppercase = false;
prev = c;
}
else
{
if (makeUppercase || ((prev >= 'A') && (prev <= 'Z')) )
buffer.append('_');
// else deleted
makeUppercase = true;
}
}
return buffer.toString();
}
/**
* Convenience function to create an <code>java.lang.Vector</code>
* within a template.
*
* @param size
* @return An empty Vector.
* @see java.util.Vector
*/
public static Vector newVector(int size)
{
return new Vector(size);
}
/**
* Convenience function to create an <code>java.lang.Hashtable</code>
* within a template.
*
* @param size The default hashsize (avoids the original default of 101).
* @return An empty Hashtable.
* @see java.util.Hashtable
*/
public static Hashtable newHashtable(int size)
{
return new Hashtable(size);
}
/**
* Convenience function to create an empty array within a template.<br>
* This can be used as a for-loop replacement:<code>
* #foreach ($index in $Context.newArray(10))
* ## do something 10 times or use $index
* #end</code>
*
* @param size
* @return An object array contining the numbers 0 till (size-1).
*/
public static Object newArray(int size)
{
Object[] array = new Object[size];
for (int i = 0; i < size; ++i)
{
array[i] = new Integer(i);
}
return array;
}
/**
* Convenience function to access an element of an array.
*
* @param index
* @param array
* @return Element at the specified array index.
*/
public static Object getElement(int index, Object[] array)
{
return array[index];
}
/**
* Convenience function to access an element of an array and
* allow specifying a default value.
*
* @param index
* @param array
* @param dv The default value.
* @return Element at the specified array index.
*/
public static Object getElement(int index, Object[] array, Object dv)
{
Object value = (index >= array.length) ? dv : array[index];
return (value != null) ? value : dv;
}
/**
* Convenience function sort the elements of an array.
*
* @param array
* @return The sorted array.
*/
public static Object[] sort(Object[] array)
{
if ((array == null) || (array.length == 0))
return array;
Object[] sorted = new Object[array.length];
System.arraycopy(array, 0, sorted, 0, array.length);
Arrays.sort(sorted);
return sorted;
}
/**
* Split a string into tokens.
*
* @param text The string to split.
* @param separator The string used to separate the tokens.
* @return An array containing the separated tokens.
*/
public static Vector tokenize(String text, String separator)
{
Vector vector = new Vector();
int from = 0;
int till = 0;
while( till >= 0 )
{
till = text.indexOf(separator, from);
if (till >= 0)
vector.add( text.substring(from, till) );
else if (from < text.length())
vector.add( text.substring(from) ); // rest at the end
else
vector.add(""); // empty string after last separator
from = till + separator.length();
}
return vector;
}
} // end of ContextTool.java
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]