"Map classByName" could as well be "Set cachedClassNames", storing only
class names and using "cachedClassNames.contains(className)" instead of
"classByName.get(name) != null". It can be somewhat confusing to code
readers why do we store the class beside its name - we don't use the stored
class object anywhere.
Attila.
----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: 2001. szeptember 10. 12:36
Subject: cvs commit:
jakarta-velocity/src/java/org/apache/velocity/util/introspection
ClassMap.java Introspector.java
> geirm 01/09/10 03:36:09
>
> Modified: src/java/org/apache/velocity/util/introspection
> ClassMap.java Introspector.java
> Log:
> PROVISIONAL changes to Introspector that mix reengineering by
> Atilla Szegedi and a patch to revert *that* back to using
> Class as the key to the map, with a second map to hold
> name->class for dumping.
>
> I think I got it all together correctly - if not, yell :)
>
> Revision Changes Path
> 1.13 +9 -1
jakarta-velocity/src/java/org/apache/velocity/util/introspection/ClassMap.ja
va
>
> Index: ClassMap.java
> ===================================================================
> RCS file:
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/util/introspection/C
lassMap.java,v
> retrieving revision 1.12
> retrieving revision 1.13
> diff -u -r1.12 -r1.13
> --- ClassMap.java 2001/08/11 19:04:21 1.12
> +++ ClassMap.java 2001/09/10 10:36:09 1.13
> @@ -70,7 +70,7 @@
> * @author <a href="mailto:[EMAIL PROTECTED]">Bob McWhirter</a>
> * @author <a href="mailto:[EMAIL PROTECTED]">Attila Szegedi</a>
> * @author <a href="mailto:[EMAIL PROTECTED]">Geir Magnusson Jr.</a>
> - * @version $Id: ClassMap.java,v 1.12 2001/08/11 19:04:21 geirm Exp $
> + * @version $Id: ClassMap.java,v 1.13 2001/09/10 10:36:09 geirm Exp $
> */
> public class ClassMap
> {
> @@ -101,6 +101,14 @@
> this.clazz = clazz;
> populateMethodCache();
> }
> +
> + /**
> + * @return the class object whose methods are cached by this map.
> + */
> + Class getCachedClass()
> + {
> + return clazz;
> + }
>
> /**
> * Find a Method using the methodKey
>
>
>
> 1.11 +1 -179
jakarta-velocity/src/java/org/apache/velocity/util/introspection/Introspecto
r.java
>
> Index: Introspector.java
> ===================================================================
> RCS file:
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/util/introspection/I
ntrospector.java,v
> retrieving revision 1.10
> retrieving revision 1.11
> diff -u -r1.10 -r1.11
> --- Introspector.java 2001/09/09 21:50:33 1.10
> +++ Introspector.java 2001/09/10 10:36:09 1.11
> @@ -1,179 +1 @@
> -package org.apache.velocity.util.introspection;
> -
> -/*
> - * The Apache Software License, Version 1.1
> - *
> - * Copyright (c) 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", "Velocity", 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/>.
> - */
> -
> -import java.util.Hashtable;
> -
> -import java.lang.reflect.Method;
> -import java.lang.reflect.Modifier;
> -
> -import org.apache.velocity.runtime.RuntimeServices;
> -
> -/**
> - * This basic function of this class is to return a Method
> - * object for a particular class given the name of a method
> - * and the parameters to the method in the form of an Object[]
> - *
> - * The first time the Introspector sees a
> - * class it creates a class method map for the
> - * class in question. Basically the class method map
> - * is a Hastable where Method objects are keyed by a
> - * concatenation of the method name and the names of
> - * classes that make up the parameters.
> - *
> - * For example, a method with the following signature:
> - *
> - * public void method(String a, StringBuffer b)
> - *
> - * would be mapped by the key:
> - *
> - * "method" + "java.lang.String" + "java.lang.StringBuffer"
> - *
> - * This mapping is performed for all the methods in a class
> - * and stored for
> - * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
> - * @author <a href="mailto:[EMAIL PROTECTED]">Bob McWhirter</a>
> - * @version $Id: Introspector.java,v 1.10 2001/09/09 21:50:33 geirm Exp
$
> - */
> -public class Introspector
> -{
> - private static Hashtable classMethodMaps = new Hashtable();
> - private RuntimeServices rsvc = null;
> -
> - public void init( RuntimeServices r )
> - {
> - this.rsvc = r;
> - }
> -
> - public Method getMethod(Class c, String name, Object[] params)
> - throws Exception
> - {
> - if (c == null)
> - {
> - throw new Exception (
> - "Introspector.getMethod(): Class method key was null: "
+ name );
> - }
> -
> - /*
> - * If this is the first time seeing this class
> - * then create a method map for this class and
> - * store it in Hashtable of class method maps.
> - */
> - if (!classMethodMaps.containsKey(c))
> - {
> - /*
> - * Lots of threads might be whizzing through here,
> - * so we do a double-checked lock, which only involves
> - * synchronization when there's a key-miss. Avoids
> - * doing duplicate work, and constructing objects twice
> - * in particular race conditions
> - */
> -
> - /*
> - * Though, some folks say that double-checked-locking
> - * doesn't necessarily work-as-expected in Java on
> - * multi-proc machines. Doesn't make things worse,
> - * but just doesn't help as much as you'd imagine it
> - * would. Darn re-ordering of instructions.
> - */
> - synchronized (classMethodMaps)
> - {
> - if (!classMethodMaps.containsKey(c))
> - {
> - classMethodMaps.put(c, new ClassMap(c));
> - }
> - }
> - }
> - return findMethod(c, name, params);
> - }
> -
> - /**
> - * Find a method in a class.
> - *
> - * @param Class class to search
> - * @param String name of method
> - * @param Object[] parameters
> - */
> - private Method findMethod(Class c, String name, Object[] params)
> - {
> - ClassMap classMethodMap = (ClassMap) classMethodMaps.get(c);
> - return classMethodMap.findMethod(name, params);
> - }
> -
> - /**
> - * Checks whether the provided object implements a given method.
> - *
> - *
> - * @param object The object to check.
> - * @param methodName The method to check for.
> - * @return Whether the method is implemented.
> - */
> - public boolean implementsMethod(Object object, String methodName)
> - {
> - int m;
> -
> - Method[] methods = object.getClass().getMethods();
> -
> - for (m = 0 ; m < methods.length ; ++m)
> - {
> - if (methodName.equals(methods[m].getName()))
> - {
> - break;
> - }
> - }
> -
> - return (m < methods.length);
> - }
> -}
> +package org.apache.velocity.util.introspection;/* * The Apache Software
License, Version 1.1 * * Copyright (c) 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",
"Velocity", 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/>. */import
java.util.*;import java.lang.reflect.Method;import
java.lang.reflect.Modifier;import
org.apache.velocity.runtime.RuntimeServices;/** * This basic function of
this class is to return a Method * object for a particular class given the
name of a method * and the parameters to the method in the form of an
Object[] * * The first time the Introspector sees a * class it creates a
class method map for the * class in question. Basically the class method map
* is a Hastable where Method objects are keyed by a * concatenation of the
method name and the names of * classes that make up the parameters. * * For
example, a method with the following signature: * * public void
method(String a, StringBuffer b) * * would be mapped by the key: * *
"method" + "java.lang.String" + "java.lang.StringBuffer" * * This mapping is
performed for all the methods in a class * and stored for * @author <a
href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a> * @author <a
href="mailto:[EMAIL PROTECTED]">Bob McWhirter</a> * @author <a
href="mailto:[EMAIL PROTECTED]">Attila Szegedi</a> * @author <a
href="mailto:[EMAIL PROTECTED]">Paulo Gaspar</a> * @version $Id:
Introspector.java,v 1.11 2001/09/10 10:36:09 geirm Exp $ */public class
Introspector{ private RuntimeServices rsvc = null; /* * Holds the
method maps for the classes we know about, * keyed by Class */
private final Map classMethodMaps = new HashMap(); /* * Holds
the qualified class name to Class mapping */ private final Map
classByName = new HashMap(); /** * Recieves our RuntimeServices
object */ public void init( RuntimeServices r ) { this.rsvc
= r; } public Method getMethod(Class c, String name, Object[]
params) throws Exception { if (c == null)
{ throw new Exception (
"Introspector.getMethod(): Class method key was null: " + name ); }
ClassMap classMap = null; synchronized(classMethodMaps)
{ classMap = (ClassMap)classMethodMaps.get(c);
/* * if we don't have this, check to see if we have it
* by name. if so, then we have a classloader change * so dump
our caches. */ if ( classMap == null)
{ Class cachedClass = (Class) classByName.get( c.getName() );
if ( cachedClass != null) { clearCache();
rsvc.info("Introspector : detected classloader change. Dumping
} classMap =
Map(c); } } return
classMap.findMethod(name, params); } /** * Creates a class map for
specific class and registers it in the * cache. Also adds the qualified
name to the name->class map * for later Classloader change detection.
*/ private ClassMap createClassMap(Class c) { ClassMap classMap
= new ClassMap(c); classMethodMaps.put( c, classMap);
classByName.put(c.getName(), c); return classMap; } /** *
Clears the classmap and classname * caches */ private void
clearCache() { classMethodMaps.clear();
classByName.clear(); } /** * Checks whether the
provided object implements a given method. * * * @param object
The object to check. * @param methodName The method to check for. *
@return Whether the method is implemented. */ public
boolean implementsMethod(Object object, String methodName) { int
m; Method[] methods = object.getClass().getMethods();
for (m = 0 ; m < methods.length ; ++m) { if
(methodName.equals(methods[m].getName())) {
break; } } return (m <
methods.length); }}
> \ No newline at end of file
>
>
>
>