You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by mb...@apache.org on 2004/12/16 22:11:19 UTC
cvs commit: ant/src/main/org/apache/tools/ant IntrospectionHelper.java
mbenson 2004/12/16 13:11:19
Modified: src/main/org/apache/tools/ant IntrospectionHelper.java
Log:
More LOC; also shrank constructor so checkstyle wouldn't complain.
Revision Changes Path
1.93 +176 -232 ant/src/main/org/apache/tools/ant/IntrospectionHelper.java
Index: IntrospectionHelper.java
===================================================================
RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -r1.92 -r1.93
--- IntrospectionHelper.java 22 Nov 2004 09:23:26 -0000 1.92
+++ IntrospectionHelper.java 16 Dec 2004 21:11:19 -0000 1.93
@@ -17,7 +17,6 @@
package org.apache.tools.ant;
-import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -44,37 +43,37 @@
* EMPTY_MAP was added in java 1.3 (EMTPY_SET and EMPTY_LIST
* is in java 1.2!)
*/
- private static final Map EMPTY_MAP = Collections.unmodifiableMap(
- new HashMap());
+ private static final Map EMPTY_MAP
+ = Collections.unmodifiableMap(new HashMap(0));
/**
* Map from attribute names to attribute types
* (String to Class).
*/
- private Hashtable attributeTypes;
+ private Hashtable attributeTypes = new Hashtable();
/**
* Map from attribute names to attribute setter methods
* (String to AttributeSetter).
*/
- private Hashtable attributeSetters;
+ private Hashtable attributeSetters = new Hashtable();
/**
* Map from attribute names to nested types
* (String to Class).
*/
- private Hashtable nestedTypes;
+ private Hashtable nestedTypes = new Hashtable();
/**
* Map from attribute names to methods to create nested types
* (String to NestedCreator).
*/
- private Hashtable nestedCreators;
+ private Hashtable nestedCreators = new Hashtable();
/**
* Vector of methods matching add[Configured](Class) pattern.
*/
- private List addTypeMethods;
+ private List addTypeMethods = new ArrayList();
/**
* The method to invoke to add PCDATA.
@@ -167,12 +166,6 @@
* @see #getHelper(Class)
*/
private IntrospectionHelper(final Class bean) {
- attributeTypes = new Hashtable();
- attributeSetters = new Hashtable();
- nestedTypes = new Hashtable();
- nestedCreators = new Hashtable();
- addTypeMethods = new ArrayList();
-
this.bean = bean;
Method[] methods = bean.getMethods();
@@ -183,37 +176,28 @@
Class[] args = m.getParameterTypes();
// check of add[Configured](Class) pattern
- if (args.length == 1
- && java.lang.Void.TYPE.equals(returnType)
+ if (args.length == 1 && java.lang.Void.TYPE.equals(returnType)
&& ("add".equals(name) || "addConfigured".equals(name))) {
insertAddTypeMethod(m);
continue;
}
-
// not really user settable properties on tasks
if (org.apache.tools.ant.Task.class.isAssignableFrom(bean)
&& args.length == 1 && isHiddenSetMethod(name, args[0])) {
continue;
}
-
// hide addTask for TaskContainers
if (isContainer() && args.length == 1 && "addTask".equals(name)
&& org.apache.tools.ant.Task.class.equals(args[0])) {
continue;
}
-
-
- if ("addText".equals(name)
- && java.lang.Void.TYPE.equals(returnType)
- && args.length == 1
- && java.lang.String.class.equals(args[0])) {
+ if ("addText".equals(name) && java.lang.Void.TYPE.equals(returnType)
+ && args.length == 1 && java.lang.String.class.equals(args[0])) {
addText = methods[i];
-
} else if (name.startsWith("set")
&& java.lang.Void.TYPE.equals(returnType)
- && args.length == 1
- && !args[0].isArray()) {
+ && args.length == 1 && !args[0].isArray()) {
String propName = getPropertyName(name, "set");
if (attributeSetters.get(propName) != null) {
@@ -237,139 +221,56 @@
particular order.
*/
}
- AttributeSetter as
- = createAttributeSetter(m, args[0], propName);
+ AttributeSetter as = createAttributeSetter(m, args[0], propName);
if (as != null) {
attributeTypes.put(propName, args[0]);
attributeSetters.put(propName, as);
}
-
- } else if (name.startsWith("create")
- && !returnType.isArray()
- && !returnType.isPrimitive()
- && args.length == 0) {
+ } else if (name.startsWith("create") && !returnType.isArray()
+ && !returnType.isPrimitive() && args.length == 0) {
String propName = getPropertyName(name, "create");
// Check if a create of this property is already present
// add takes preference over create for CB purposes
if (nestedCreators.get(propName) == null) {
nestedTypes.put(propName, returnType);
- nestedCreators.put(propName, new NestedCreator(m) {
- Object create(
- Project project, Object parent, Object ignore)
- throws InvocationTargetException,
- IllegalAccessException {
- return m.invoke(parent, new Object[] {});
- }
- });
+ nestedCreators.put(propName, new CreateNestedCreator(m));
}
} else if (name.startsWith("addConfigured")
- && java.lang.Void.TYPE.equals(returnType)
- && args.length == 1
- && !java.lang.String.class.equals(args[0])
- && !args[0].isArray()
- && !args[0].isPrimitive()) {
-
+ && java.lang.Void.TYPE.equals(returnType) && args.length == 1
+ && !java.lang.String.class.equals(args[0])
+ && !args[0].isArray() && !args[0].isPrimitive()) {
try {
Constructor constructor = null;
try {
- constructor =
- args[0].getConstructor(new Class[] {});
+ constructor = args[0].getConstructor(new Class[] {});
} catch (NoSuchMethodException ex) {
constructor =
- args[0].getConstructor(new Class[] {
- Project.class});
+ args[0].getConstructor(new Class[] {Project.class});
}
- final Constructor c = constructor;
String propName = getPropertyName(name, "addConfigured");
nestedTypes.put(propName, args[0]);
- nestedCreators.put(propName, new NestedCreator(m) {
- boolean isPolyMorphic() {
- return true;
- }
-
- Class getElementClass() {
- return c.getDeclaringClass();
- }
-
- Object create(
- Project project, Object parent, Object child)
- throws InvocationTargetException,
- IllegalAccessException, InstantiationException {
- if (child != null) {
- // Empty
- } else if (c.getParameterTypes().length == 0) {
- child = c.newInstance(new Object[] {});
- } else {
- child = c.newInstance(new Object[] {
- project});
- }
- if (child instanceof PreSetDef.PreSetDefinition) {
- child = ((PreSetDef.PreSetDefinition) child)
- .createObject(project);
- }
- return child;
- }
-
- void store(Object parent, Object child)
- throws InvocationTargetException,
- IllegalAccessException, InstantiationException {
- m.invoke(parent, new Object[] {child});
- }
-
- });
+ nestedCreators.put(propName, new AddNestedCreator(m,
+ constructor, AddNestedCreator.ADD_CONFIGURED));
} catch (NoSuchMethodException nse) {
// ignore
}
} else if (name.startsWith("add")
- && java.lang.Void.TYPE.equals(returnType)
- && args.length == 1
- && !java.lang.String.class.equals(args[0])
- && !args[0].isArray()
- && !args[0].isPrimitive()) {
-
+ && java.lang.Void.TYPE.equals(returnType) && args.length == 1
+ && !java.lang.String.class.equals(args[0])
+ && !args[0].isArray() && !args[0].isPrimitive()) {
try {
Constructor constructor = null;
try {
- constructor =
- args[0].getConstructor(new Class[] {});
+ constructor = args[0].getConstructor(new Class[] {});
} catch (NoSuchMethodException ex) {
constructor =
- args[0].getConstructor(new Class[] {
- Project.class});
+ args[0].getConstructor(new Class[] {Project.class});
}
- final Constructor c = constructor;
String propName = getPropertyName(name, "add");
nestedTypes.put(propName, args[0]);
- nestedCreators.put(propName, new NestedCreator(m) {
- boolean isPolyMorphic() {
- return true;
- }
-
- Class getElementClass() {
- return c.getDeclaringClass();
- }
-
- Object create(
- Project project, Object parent, Object child)
- throws InvocationTargetException,
- IllegalAccessException, InstantiationException {
- if (child != null) {
- // ignore
- } else if (c.getParameterTypes().length == 0) {
- child = c.newInstance(new Object[] {});
- } else {
- child = c.newInstance(new Object[] {
- project});
- }
- if (child instanceof PreSetDef.PreSetDefinition) {
- child = ((PreSetDef.PreSetDefinition) child)
- .createObject(project);
- }
- m.invoke(parent, new Object[] {child});
- return child;
- }
- });
+ nestedCreators.put(propName, new AddNestedCreator(m,
+ constructor, AddNestedCreator.ADD));
} catch (NoSuchMethodException nse) {
// ignore
}
@@ -424,21 +325,16 @@
* The method will make sure the helper will be cleaned up at the end of
* the project, and only one instance will be created for each class.
*
- * @param p the project instance
+ * @param p the project instance.
* @param c The class for which a helper is required.
* Must not be <code>null</code>.
*
* @return a helper for the specified class
*/
- public static synchronized IntrospectionHelper getHelper(Project p,
- Class c) {
- IntrospectionHelper ih = (IntrospectionHelper) helpers.get(c);
- if (ih == null) {
- ih = new IntrospectionHelper(c);
- helpers.put(c, ih);
- // Cleanup at end of project
- p.addBuildListener(ih);
- }
+ public static IntrospectionHelper getHelper(Project p, Class c) {
+ IntrospectionHelper ih = getHelper(c);
+ // Cleanup at end of project
+ p.addBuildListener(ih);
return ih;
}
@@ -755,8 +651,7 @@
return (
nestedCreators.containsKey(name.toLowerCase(Locale.US))
&& (uri.equals(parentUri) || "".equals(uri)))
- || isDynamic()
- || addTypeMethods.size() != 0;
+ || isDynamic() || addTypeMethods.size() != 0;
}
/**
@@ -822,10 +717,9 @@
throws BuildException {
Class nt = (Class) nestedTypes.get(elementName);
if (nt == null) {
- String msg = "Class " + bean.getName()
- + " doesn't support the nested \"" + elementName
- + "\" element.";
- throw new UnsupportedElementException(msg, elementName);
+ throw new UnsupportedElementException("Class "
+ + bean.getName() + " doesn't support the nested \""
+ + elementName + "\" element.", elementName);
}
return nt;
}
@@ -846,9 +740,9 @@
throws BuildException {
Class at = (Class) attributeTypes.get(attributeName);
if (at == null) {
- String msg = "Class " + bean.getName()
- + " doesn't support the \"" + attributeName + "\" attribute.";
- throw new UnsupportedAttributeException(msg, attributeName);
+ throw new UnsupportedAttributeException("Class "
+ + bean.getName() + " doesn't support the \""
+ + attributeName + "\" attribute.", attributeName);
}
return at;
}
@@ -866,9 +760,8 @@
public Method getAddTextMethod()
throws BuildException {
if (!supportsCharacters()) {
- String msg = "Class " + bean.getName()
- + " doesn't support nested text data.";
- throw new BuildException(msg);
+ throw new BuildException("Class " + bean.getName()
+ + " doesn't support nested text data.");
}
return addText;
}
@@ -889,10 +782,9 @@
throws BuildException {
Object creator = nestedCreators.get(elementName);
if (creator == null) {
- String msg = "Class " + bean.getName()
- + " doesn't support the nested \"" + elementName
- + "\" element.";
- throw new UnsupportedElementException(msg, elementName);
+ throw new UnsupportedElementException("Class "
+ + bean.getName() + " doesn't support the nested \""
+ + elementName + "\" element.", elementName);
}
return ((NestedCreator) creator).method;
}
@@ -912,9 +804,9 @@
throws BuildException {
Object setter = attributeSetters.get(attributeName);
if (setter == null) {
- String msg = "Class " + bean.getName()
- + " doesn't support the \"" + attributeName + "\" attribute.";
- throw new UnsupportedAttributeException(msg, attributeName);
+ throw new UnsupportedAttributeException("Class "
+ + bean.getName() + " doesn't support the \""
+ + attributeName + "\" attribute.", attributeName);
}
return ((AttributeSetter) setter).method;
}
@@ -949,10 +841,8 @@
* @since Ant 1.6.3
*/
public Map getAttributeMap() {
- if (attributeTypes.size() < 1) {
- return EMPTY_MAP;
- }
- return Collections.unmodifiableMap(attributeTypes);
+ return (attributeTypes.size() < 1)
+ ? EMPTY_MAP : Collections.unmodifiableMap(attributeTypes);
}
/**
@@ -976,10 +866,8 @@
* @since Ant 1.6.3
*/
public Map getNestedElementMap() {
- if (nestedTypes.size() < 1) {
- return EMPTY_MAP;
- }
- return Collections.unmodifiableMap(nestedTypes);
+ return (nestedTypes.size() < 1)
+ ? EMPTY_MAP : Collections.unmodifiableMap(nestedTypes);
}
/**
@@ -1000,10 +888,8 @@
* @since Ant 1.6.3
*/
public List getExtensionPoints() {
- if (addTypeMethods.size() < 1) {
- return Collections.EMPTY_LIST;
- }
- return Collections.unmodifiableList(addTypeMethods);
+ return (addTypeMethods.size() < 1) ? Collections.EMPTY_LIST
+ : Collections.unmodifiableList(addTypeMethods);
}
/**
@@ -1042,91 +928,81 @@
final String attrName) {
// use wrappers for primitive classes, e.g. int and
// Integer are treated identically
- final Class reflectedArg = PRIMITIVE_TYPE_MAP.containsKey (arg)
+ final Class reflectedArg = PRIMITIVE_TYPE_MAP.containsKey(arg)
? (Class) PRIMITIVE_TYPE_MAP.get(arg) : arg;
// simplest case - setAttribute expects String
if (java.lang.String.class.equals(reflectedArg)) {
return new AttributeSetter(m) {
- public void set(Project p, Object parent, String value)
+ public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException {
- m.invoke(parent, (Object[]) (new String[] {value}));
- }
- };
-
+ m.invoke(parent, (Object[]) (new String[] {value}));
+ }
+ };
// char and Character get special treatment - take the first character
} else if (java.lang.Character.class.equals(reflectedArg)) {
return new AttributeSetter(m) {
- public void set(Project p, Object parent, String value)
+ public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException {
- if (value.length() == 0) {
- throw new BuildException("The value \"\" is not a "
- + "legal value for attribute \""
- + attrName + "\"");
- }
- m.invoke(parent, (Object[])
- (new Character[] {new Character(value.charAt(0))}));
+ if (value.length() == 0) {
+ throw new BuildException("The value \"\" is not a "
+ + "legal value for attribute \"" + attrName + "\"");
}
-
- };
+ m.invoke(parent, (Object[])
+ (new Character[] {new Character(value.charAt(0))}));
+ }
+ };
// boolean and Boolean get special treatment because we
// have a nice method in Project
} else if (java.lang.Boolean.class.equals(reflectedArg)) {
return new AttributeSetter(m) {
- public void set(Project p, Object parent, String value)
+ public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException {
- m.invoke(parent, (Object[]) (
- new Boolean[] {Project.toBoolean(value)
- ? Boolean.TRUE : Boolean.FALSE}));
- }
-
- };
-
+ m.invoke(parent, (Object[]) (
+ new Boolean[] {Project.toBoolean(value)
+ ? Boolean.TRUE : Boolean.FALSE}));
+ }
+ };
// Class doesn't have a String constructor but a decent factory method
} else if (java.lang.Class.class.equals(reflectedArg)) {
return new AttributeSetter(m) {
- public void set(Project p, Object parent, String value)
+ public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException, BuildException {
- try {
- m.invoke(parent, new Object[] {Class.forName(value)});
- } catch (ClassNotFoundException ce) {
- throw new BuildException(ce);
- }
+ try {
+ m.invoke(parent, new Object[] {Class.forName(value)});
+ } catch (ClassNotFoundException ce) {
+ throw new BuildException(ce);
}
- };
-
+ }
+ };
// resolve relative paths through Project
} else if (java.io.File.class.equals(reflectedArg)) {
return new AttributeSetter(m) {
- public void set(Project p, Object parent, String value)
+ public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException {
- m.invoke(parent, new Object[] {p.resolveFile(value)});
- }
-
- };
-
+ m.invoke(parent, new Object[] {p.resolveFile(value)});
+ }
+ };
// EnumeratedAttributes have their own helper class
} else if (EnumeratedAttribute.class.isAssignableFrom(reflectedArg)) {
return new AttributeSetter(m) {
- public void set(Project p, Object parent, String value)
+ public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException, BuildException {
- try {
- EnumeratedAttribute ea =
- (EnumeratedAttribute) reflectedArg.newInstance();
- ea.setValue(value);
- m.invoke(parent, new Object[] {ea});
- } catch (InstantiationException ie) {
- throw new BuildException(ie);
- }
+ try {
+ EnumeratedAttribute ea =
+ (EnumeratedAttribute) reflectedArg.newInstance();
+ ea.setValue(value);
+ m.invoke(parent, new Object[] {ea});
+ } catch (InstantiationException ie) {
+ throw new BuildException(ie);
}
- };
-
+ }
+ };
// worst case. look for a public String constructor and use it
// also supports new Whatever(Project, String) as for Path or Reference
// This is used (deliberately) for all primitives/wrappers other than
// char and boolean
} else {
-
boolean includeProject;
Constructor c;
try {
@@ -1150,12 +1026,9 @@
public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException, BuildException {
try {
- Object[] args;
- if (finalIncludeProject) {
- args = new Object[] {p, value};
- } else {
- args = new Object[] {value};
- }
+ Object[] args = (finalIncludeProject)
+ ? new Object[] {p, value} : new Object[] {value};
+
Object attribute = finalConstructor.newInstance(args);
if (p != null) {
p.setProjectReference(attribute);
@@ -1166,7 +1039,6 @@
}
}
};
-
}
}
@@ -1202,8 +1074,7 @@
* @return the lower-cased method name with the prefix removed.
*/
private String getPropertyName(String methodName, String prefix) {
- int start = prefix.length();
- return methodName.substring(start).toLowerCase(Locale.US);
+ return methodName.substring(prefix.length()).toLowerCase(Locale.US);
}
/**
@@ -1298,7 +1169,7 @@
/**
* @return the real object (used currently only
- * for preset def)
+ * for preset def).
*/
public Object getRealObject() {
return nestedCreator.getRealObject();
@@ -1363,6 +1234,75 @@
}
}
+ private class CreateNestedCreator extends NestedCreator {
+ CreateNestedCreator(Method m) {
+ super(m);
+ }
+
+ Object create(Project project, Object parent, Object ignore)
+ throws InvocationTargetException, IllegalAccessException {
+ return method.invoke(parent, new Object[] {});
+ }
+ }
+
+ /** Version to use for addXXX and addConfiguredXXX */
+ private class AddNestedCreator extends NestedCreator {
+
+ static final int ADD = 1;
+ static final int ADD_CONFIGURED = 2;
+
+ protected Constructor constructor;
+ protected int behavior;
+
+ AddNestedCreator(Method m, Constructor c, int behavior) {
+ super(m);
+ this.constructor = c;
+ this.behavior = behavior;
+ }
+
+ boolean isPolyMorphic() {
+ return true;
+ }
+
+ Class getElementClass() {
+ return constructor.getDeclaringClass();
+ }
+
+ Object create(Project project, Object parent, Object child)
+ throws InvocationTargetException,
+ IllegalAccessException, InstantiationException {
+ if (child != null) {
+ // Empty
+ } else {
+ child = constructor.newInstance(
+ (constructor.getParameterTypes().length == 0)
+ ? new Object[] {} : new Object[] {project});
+ }
+ if (child instanceof PreSetDef.PreSetDefinition) {
+ child = ((PreSetDef.PreSetDefinition) child)
+ .createObject(project);
+ }
+ if (behavior == ADD) {
+ istore(parent, child);
+ }
+ return child;
+ }
+
+ void store(Object parent, Object child)
+ throws InvocationTargetException,
+ IllegalAccessException, InstantiationException {
+ if (behavior == ADD_CONFIGURED) {
+ istore(parent, child);
+ }
+ }
+
+ private void istore(Object parent, Object child)
+ throws InvocationTargetException,
+ IllegalAccessException, InstantiationException {
+ method.invoke(parent, new Object[] {child});
+ }
+ }
+
/**
* Internal interface used to setting element attributes. Not documented
* in detail for reasons of source code readability.
@@ -1475,7 +1415,7 @@
return new NestedCreator(addMethod) {
Object create(Project project, Object parent, Object ignore)
- throws InvocationTargetException, IllegalAccessException {
+ throws InvocationTargetException, IllegalAccessException {
if (!method.getName().endsWith("Configured")) {
method.invoke(parent, new Object[]{realObject});
}
@@ -1487,8 +1427,8 @@
}
void store(Object parent, Object child)
- throws InvocationTargetException, IllegalAccessException,
- InstantiationException {
+ throws InvocationTargetException, IllegalAccessException,
+ InstantiationException {
if (method.getName().endsWith("Configured")) {
method.invoke(parent, new Object[]{realObject});
}
@@ -1501,6 +1441,7 @@
* the addTypeMethods array. The array is
* ordered so that the more derived classes
* are first.
+ * @param method the <code>Method</code> to insert.
*/
private void insertAddTypeMethod(Method method) {
Class argClass = method.getParameterTypes()[0];
@@ -1521,6 +1462,9 @@
/**
* Search the list of methods to find the first method
* that has a parameter that accepts the nested element object.
+ * @param paramClass the <code>Class</code> type to search for.
+ * @param methods the <code>List</code> of methods to search.
+ * @return a matching <code>Method</code>; null if none found.
*/
private Method findMatchingMethod(Class paramClass, List methods) {
Class matchedClass = null;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org