geirm 01/05/13 21:43:37
Modified: src/java/org/apache/velocity/util/introspection
ClassMap.java
Log:
Minor changes that seem to solve the introspection problem when a
class is not public yet the interface methods are. The idea is simple -
analyze the interfaces as well as classes, add only the public members
of the public interfaces/classes, and don't bother repeating.
I am not 100% sure of this yet, but letting a few people examine it and
batter it about will help.
Revision Changes Path
1.9 +71 -5
jakarta-velocity/src/java/org/apache/velocity/util/introspection/ClassMap.java
Index: ClassMap.java
===================================================================
RCS file:
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/util/introspection/ClassMap.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- ClassMap.java 2001/03/05 11:48:44 1.8
+++ ClassMap.java 2001/05/14 04:43:36 1.9
@@ -65,7 +65,8 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Bob McWhirter</a>
- * @version $Id: ClassMap.java,v 1.8 2001/03/05 11:48:44 jvanzyl Exp $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Geir Magnusson Jr.</a>
+ * @version $Id: ClassMap.java,v 1.9 2001/05/14 04:43:36 geirm Exp $
*/
// TODO: public boolean (String[] list)
@@ -150,19 +151,84 @@
/**
* Populate the Map of direct hits. These
* are taken from all the public methods
+ * of all the public classes / interfaces
* that our class provides.
*/
private void populateMethodCache()
{
- Method[] methods = clazz.getMethods();
- StringBuffer methodKey;
+ /*
+ * start with the interfaces
+ */
+ Class[] classes = clazz.getInterfaces();
+
+ for (int j = 0; j < classes.length; j++)
+ {
+ /*
+ * if the class is public, then add it to the cache
+ */
+
+ if (Modifier.isPublic( classes[j].getModifiers()))
+ {
+ populateMethodCache( classes[j] );
+ }
+ }
+
+ /*
+ * and now the classes
+ */
+
+ classes = clazz.getClasses();
+
+ for (int j = 0; j < classes.length; j++)
+ {
+ /*
+ * if the class is public, then add it to the cache
+ */
+
+ if (Modifier.isPublic( classes[j].getModifiers()))
+ {
+ populateMethodCache( classes[j] );
+ }
+ }
+ }
+
+ /**
+ * adds all public methods to the method cache
+ * and map
+ * @param claz Class to analyze
+ */
+ private void populateMethodCache( Class claz )
+ {
+ /*
+ * now, get all methods, from both interfaces
+ * as well as super
+ */
+
+ Method[] methods = claz.getMethods();
+ String methodKey = null;
+
for (int i = 0; i < methods.length; i++)
{
+ /*
+ * only care if the method is public
+ */
+
if (Modifier.isPublic(methods[i].getModifiers()))
{
- methodMap.add(methods[i]);
- methodCache.put(makeMethodKey(methods[i]), methods[i]);
+ methodKey = makeMethodKey( methods[i] );
+
+ /*
+ * Only add this if we don't already have it, because the method
+ * key doesn't distinguish for which class/interface it
+ * belongs FOR THIS CLASS. And it shouldn't matter.
+ */
+
+ if( methodCache.get( methodKey ) == null)
+ {
+ methodMap.add( methods[i] );
+ methodCache.put( methodKey, methods[i]);
+ }
}
}
}