You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by ve...@jakarta.apache.org on 2004/11/05 06:55:37 UTC
[Jakarta-Velocity Wiki] New: MultiUberspect
Date: 2004-11-04T21:55:37
Editor: EricFixler <fi...@fixler.com>
Wiki: Jakarta-Velocity Wiki
Page: MultiUberspect
URL: http://wiki.apache.org/jakarta-velocity/MultiUberspect
no comment
New Page:
/** org.apache.velocity.tools.generic.introspection.MultiUberspect
Allows Velocity to Introspect other types of Objects
November 2004
Eric Fixler <fi...@smete.org>
$Id: MultiUberspect.java,v 1.1.2.2 2004/11/05 05:51:00 fix Exp $
*/
/*
* 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.util.*;
import org.apache.velocity.util.introspection.Info;
import org.apache.velocity.util.introspection.Uberspect;
import org.apache.velocity.util.introspection.UberspectImpl;
import org.apache.velocity.util.introspection.VelPropertyGet;
import org.apache.velocity.util.introspection.VelPropertySet;
/**
* Expanded Uberspect implementation that allows you to designate custom Uberspects on
* a per class basis, so that classes that don't follow the Java Beans specification can
* be handled like beans in Velocity Templates.
*
* <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.MultiUberspect
* </code>
* </p>
*
* @author <a href="mailto:fix@smete.org">Eric Fixler</a>
* @version $Id: MultiUberspect.java,v 1.1.2.2 2004/11/05 05:51:00 fix Exp $
*/
public class MultiUberspect extends UberspectImpl {
private final Map customIntrospectors = new HashMap();
private final Map derivedIntrospectors = new HashMap();
public MultiUberspect() {}
protected boolean useSuperclassIntrospector = false;
/** <p>If true, and a class is encountered for which a custom Uberspect has not been registered,
will check to see if any superclasses of class have registered Uberspects. If so, will use
the superclass' Uberspect.</p>
<p>When false (the default), will only return a custom Uberspect if the requested Objects class
has had a Uberspect explicitly registered.</p>
@param b the flag
*/
public void setUseSuperclassIntrospector(boolean b) { this.useSuperclassIntrospector = b; }
/** Whether of not we will look for a superclass Uberspect if an exact match for a custom Uberspect is not found. */
public final boolean getUseSuperclassIntrospector() { return this.useSuperclassIntrospector; }
/** Register a custom uberspect
@param clz The class handled by this Uberspect
@param u The Uberspect
*/
public void addIntrospector(Class clz, Uberspect u) {
try {
u.init();
} catch (Exception e) {
return;
}
this.customIntrospectors.put(clz, u);
this.derivedIntrospectors.clear();
this.derivedIntrospectors.put(clz, u);
}
/** Unregister a custom uberspect.
@param clz The class handled by the Uberspect
*/
public void removeIntrospector(Class clz) {
this.customIntrospectors.remove(clz);
this.derivedIntrospectors.clear();
this.derivedIntrospectors.putAll(this.customIntrospectors);
}
/** Get the Uberspect, if one exists
@param clz The class for which to get an Uberspect
@return an Uberspect, or null if none exists
*/
protected Uberspect getCustomIntrospector(Class clz) {
Uberspect uber = (Uberspect) this.derivedIntrospectors.get(clz);
if ((! this.useSuperclassIntrospector) || (uber != null)) return uber;
synchronized(this.derivedIntrospectors) {
Iterator it = this.customIntrospectors.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Class checkClz = (Class) entry.getKey();
if (checkClz.isAssignableFrom(clz)) {
uber = (Uberspect) entry.getValue();
this.derivedIntrospectors.put(clz, uber);
return uber;
}
}
}
return null;
}
/**
* Property getter - returns VelPropertyGet appropos for #set($foo = $bar.woogie).
* <br />
* Looks to see if a custom Uberspect has been registered for obj.getClass().
* If a getter was not found, tries the regular routine.
*
* @param obj the object
* @param identifier the name of the property
* @param info 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 info)
throws Exception
{
Uberspect uberspect = (Uberspect) this.getCustomIntrospector(obj.getClass());
return (uberspect != null)
? uberspect.getPropertyGet(obj, identifier, info)
: super.getPropertyGet(obj, identifier, info);
}
/**
* Property setter - returns VelPropertySet appropos for #set($foo.bar = "geir").
* <br />
* Looks to see if a custom Uberspect has been registered for obj.getClass().
* If a setter was not found, tries the regular routine.
*
* @param obj the object
* @param identifier the name of the property
* @param arg the value to set to the property
* @param info 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 info) throws Exception
{
Uberspect uberspect = (Uberspect) this.getCustomIntrospector(obj.getClass());
return (uberspect != null)
? uberspect.getPropertySet(obj, identifier, arg, info)
: super.getPropertySet(obj, identifier, arg, info);
}
/**
Change this source if you use this, since you won't have the classes referenced here.
(Obviously, would be better to assign the mappings elsewhere)
*/
public void init() throws Exception {
super.init();
this.addIntrospector(Class.forName("com.canto.cumulus.Record"), new CumulusRecordUberspect());
}
}
// $Log: MultiUberspect.java,v $
// Revision 1.1.2.2 2004/11/05 05:51:00 fix
// Added useSuperclassIntrospector to turn superclass scaling on and off
//
---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org