There's a field introspector written by a Velocity user in the Wiki. You can configure velocity.properties to reference this. It require velocity version 1.4.

PublicFieldUberspect.java
-------------------------------------------------------------------------------------------------------------
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.velocity.tools.generic.introspection;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import org.apache.velocity.util.introspection.Info;
import org.apache.velocity.util.introspection.UberspectImpl;
import org.apache.velocity.util.introspection.VelPropertyGet;
import org.apache.velocity.util.introspection.VelPropertySet;
/**
* Uberspect implementation that exposes public fields.
* Also exposes the explicit "length" field of arrays.
*
* <p>To use, tell Velocity to use this class for introspection
* by adding the following to your velocity.properties:<br />
*
* <code>
* runtime.introspector.uberspect = org.apache.velocity.tools.generic.introspection.PublicFieldUberspect
* </code>
* </p>
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
public class PublicFieldUberspect extends UberspectImpl
{
/**
* Default constructor.
*/
public PublicFieldUberspect()
{
}
/**
* Property getter - returns VelPropertyGet appropos for #set($foo = $bar.woogie).
* <br />
* Returns a special {@link VelPropertyGet} for the <code>length</code> property of arrays.
* Otherwise tries the regular routine.  If a getter was not found,
* returns a {@link VelPropertyGet} that gets from public fields.
*
* @param obj the object
* @param identifier the name of the property
* @param i a bunch of information.
* @return a valid <code>VelPropertyGet</code>, if it was found.
* @throws Exception failed to create a valid <code>VelPropertyGet</code>.
*/
public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i)
throws Exception
{
Class clazz = obj.getClass();
boolean isArray = clazz.isArray();
boolean isLength = identifier.equals("length");
if (isArray && isLength)
{
return new ArrayLengthGetter();
}
VelPropertyGet getter = super.getPropertyGet(obj, identifier, i);
// there is no clean way to see if super succeeded
// @see http://issues.apache.org/bugzilla/show_bug.cgi?id=31742
try
{
getter.getMethodName();
return getter;
}
catch (NullPointerException notFound)
{
}
Field field = obj.getClass().getField(identifier);
if (field != null)
{
return new PublicFieldGetter(field);
}
return null;
}
/**
* Property setter - returns VelPropertySet appropos for #set($foo.bar = "geir").
* <br />
* First tries the regular routine.  If a setter was not found,
* returns a {@link VelPropertySet} that sets to public fields.
*
* @param obj the object
* @param identifier the name of the property
* @param arg the value to set to the property
* @param i a bunch of information.
* @return a valid <code>VelPropertySet</code>, if it was found.
* @throws Exception failed to create a valid <code>VelPropertySet</code>.
*/
public VelPropertySet getPropertySet(Object obj, String identifier,
Object arg, Info i) throws Exception
{
VelPropertySet setter = super.getPropertySet(obj, identifier, arg, i);
if (setter != null)
{
return setter;
}
Field field = obj.getClass().getField(identifier);
if (field != null)
{
return new PublicFieldSetter(field);
}
return null;
}
/**
* Implementation of {@link VelPropertyGet} that gets from public fields.
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
protected class PublicFieldGetter implements VelPropertyGet
{
/** The <code>Field</code> object representing the property. */
private Field field = null;
/**
* Constructor.
*
* @param field The <code>Field</code> object representing the property.
*/
public PublicFieldGetter(Field field)
{
this.field = field;
}
/**
* Returns the value of the public field.
*
* @param o the object
* @return the value
* @throws Exception failed to get the value from the object
*/
public Object invoke(Object o) throws Exception
{
return this.field.get(o);
}
/**
* This class is cacheable, so it returns <code>true</code>.
*
* @return <code>true</code>.
*/
public boolean isCacheable()
{
return true;
}
/**
* Returns <code>"public field getter"</code>, since there is no method.
*
* @return <code>"public field getter"</code>
*/
public String getMethodName()
{
return "public field getter";
}
}
/**
* Implementation of {@link VelPropertyGet} that gets length from arrays.
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
protected class ArrayLengthGetter implements VelPropertyGet
{
/**
* Constructor.
*/
public ArrayLengthGetter()
{
}
/**
* Returns the length of the array.
*
* @param o the array
* @return the length
* @throws Exception failed to get the length from the array
*/
public Object invoke(Object o) throws Exception
{
// Thanks to Eric Fixler for this refactor.
return new Integer(Array.getLength(o));
}
/**
* This class is cacheable, so it returns <code>true</code>.
*
* @return <code>true</code>.
*/
public boolean isCacheable()
{
return true;
}
/**
* Returns <code>"array length getter"</code>, since there is no method.
*
* @return <code>"array length getter"</code>
*/
public String getMethodName()
{
return "array length getter";
}
}
/**
* Implementation of {@link VelPropertySet} that sets to public fields.
*
* @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
* @version $Id: $
*/
protected class PublicFieldSetter implements VelPropertySet
{
/** The <code>Field</code> object representing the property. */
private Field field = null;
/**
* Constructor.
*
* @param field The <code>Field</code> object representing the property.
*/
public PublicFieldSetter(Field field)
{
this.field = field;
}
/**
* Sets the value to the public field.
*
* @param o the object
* @param value the value to set
* @return always <code>null</code>
* @throws Exception failed to set the value to the object
*/
public Object invoke(Object o, Object value) throws Exception
{
this.field.set(o, value);
return null;
}
/**
* This class is cacheable, so it returns <code>true</code>.
*
* @return <code>true</code>.
*/
public boolean isCacheable()
{
return true;
}
/**
* Returns <code>"public field setter"</code>, since there is no method.
*
* @return <code>"public field setter"</code>
*/
public String getMethodName()
{
return "public field setter";
}
}
}


See
http://wiki.apache.org/jakarta-velocity/PublicFieldUberspect


只有注册用户登录后才能发表评论。


网站导航: