Browse Source

New Introspection capability. Methods which have the signature

addConfiguredXXX will be called for nested elements named XXX
but will be called only once the XXX object has been configured


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269430 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 24 years ago
parent
commit
f2bc3fe7c8
4 changed files with 96 additions and 6 deletions
  1. +75
    -1
      src/main/org/apache/tools/ant/IntrospectionHelper.java
  2. +11
    -3
      src/main/org/apache/tools/ant/ProjectHelper.java
  3. +9
    -1
      src/main/org/apache/tools/ant/RuntimeConfigurable.java
  4. +1
    -1
      src/main/org/apache/tools/ant/Task.java

+ 75
- 1
src/main/org/apache/tools/ant/IntrospectionHelper.java View File

@@ -90,6 +90,11 @@ public class IntrospectionHelper implements BuildListener {
*/
private Hashtable nestedCreators;

/**
* Holds methods to store configured nested elements.
*/
private Hashtable nestedStorers;

/**
* The method to add PCDATA stuff.
*/
@@ -110,6 +115,8 @@ public class IntrospectionHelper implements BuildListener {
attributeSetters = new Hashtable();
nestedTypes = new Hashtable();
nestedCreators = new Hashtable();
nestedStorers = new Hashtable();
this.bean = bean;

Method[] methods = bean.getMethods();
@@ -177,6 +184,39 @@ public class IntrospectionHelper implements BuildListener {

});
} 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()) {
try {
final Constructor c =
args[0].getConstructor(new Class[] {});
String propName = getPropertyName(name, "addConfigured");
nestedTypes.put(propName, args[0]);
nestedCreators.put(propName, new NestedCreator() {

public Object create(Object parent)
throws InvocationTargetException, IllegalAccessException, InstantiationException {
Object o = c.newInstance(new Object[] {});
return o;
}

});
nestedStorers.put(propName, new NestedStorer() {

public void store(Object parent, Object child)
throws InvocationTargetException, IllegalAccessException, InstantiationException {
m.invoke(parent, new Object[] {child});
}

});
} catch (NoSuchMethodException nse) {
}
} else if (name.startsWith("add")
&& java.lang.Void.TYPE.equals(returnType)
&& args.length == 1
@@ -202,7 +242,6 @@ public class IntrospectionHelper implements BuildListener {
});
} catch (NoSuchMethodException nse) {
}
}
}
}
@@ -299,6 +338,35 @@ public class IntrospectionHelper implements BuildListener {
}
}

/**
* Creates a named nested element.
*/
public void storeElement(Project project, Object element, Object child, String elementName)
throws BuildException {
if (elementName == null) {
return;
}
NestedStorer ns = (NestedStorer)nestedStorers.get(elementName);
if (ns == null) {
return;
}
try {
ns.store(element, child);
} catch (IllegalAccessException ie) {
// impossible as getMethods should only return public methods
throw new BuildException(ie);
} catch (InstantiationException ine) {
// impossible as getMethods should only return public methods
throw new BuildException(ine);
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
if (t instanceof BuildException) {
throw (BuildException) t;
}
throw new BuildException(t);
}
}

/**
* returns the type of a named nested element.
*/
@@ -555,6 +623,12 @@ public class IntrospectionHelper implements BuildListener {
public Object create(Object parent)
throws InvocationTargetException, IllegalAccessException, InstantiationException;
}
private interface NestedStorer {
public void store(Object parent, Object child)
throws InvocationTargetException, IllegalAccessException, InstantiationException;
}
private interface AttributeSetter {
public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException,


+ 11
- 3
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -552,11 +552,12 @@ public class ProjectHelper {
configureId(child, attrs);

if (parentWrapper != null) {
childWrapper = new RuntimeConfigurable(child);
childWrapper = new RuntimeConfigurable(child, propType);
childWrapper.setAttributes(attrs);
parentWrapper.addChild(childWrapper);
} else {
configure(child, attrs, project);
ih.storeElement(project, parent, child, propType.toLowerCase());
}
} catch (BuildException exc) {
throw new SAXParseException(exc.getMessage(), locator, exc);
@@ -612,7 +613,7 @@ public class ProjectHelper {
}
if (target != null) {
wrapper = new RuntimeConfigurable(element);
wrapper = new RuntimeConfigurable(element, propType);
wrapper.setAttributes(attrs);
target.addDataType(wrapper);
} else {
@@ -688,7 +689,14 @@ public class ProjectHelper {
IntrospectionHelper.getHelper(target.getClass()).addText(project, target, text);
}


/**
* Stores a configured child element into its parent object
*/
public static void storeChild(Project project, Object parent, Object child, String tag) {
IntrospectionHelper ih = IntrospectionHelper.getHelper(parent.getClass());
ih.storeElement(project, parent, child, tag);
}
/**
* Replace ${} style constructions in the given value with the string value of
* the corresponding data types.


+ 9
- 1
src/main/org/apache/tools/ant/RuntimeConfigurable.java View File

@@ -68,6 +68,7 @@ import org.xml.sax.helpers.AttributeListImpl;
*/
public class RuntimeConfigurable {

private String elementTag = null;
private Vector children = new Vector();
private Object wrappedObject = null;
private AttributeList attributes;
@@ -76,8 +77,9 @@ public class RuntimeConfigurable {
/**
* @param proxy The element to wrap.
*/
public RuntimeConfigurable(Object proxy) {
public RuntimeConfigurable(Object proxy, String elementTag) {
wrappedObject = proxy;
this.elementTag = elementTag;
}

void setProxy(Object proxy) {
@@ -126,6 +128,11 @@ public class RuntimeConfigurable {
addText(new String(buf, start, end));
}

public String getElementTag() {
return elementTag;
}
/**
* Configure the wrapped element and all children.
*/
@@ -145,6 +152,7 @@ public class RuntimeConfigurable {
while (enum.hasMoreElements()) {
RuntimeConfigurable child = (RuntimeConfigurable) enum.nextElement();
child.maybeConfigure(p);
ProjectHelper.storeChild(p, wrappedObject, child.wrappedObject, child.getElementTag().toLowerCase());
}

if (id != null) {


+ 1
- 1
src/main/org/apache/tools/ant/Task.java View File

@@ -203,7 +203,7 @@ public abstract class Task {
*/
public RuntimeConfigurable getRuntimeConfigurableWrapper() {
if (wrapper == null) {
wrapper = new RuntimeConfigurable(this);
wrapper = new RuntimeConfigurable(this, getTaskName());
}
return wrapper;
}


Loading…
Cancel
Save