Browse Source

Refactor static method into a non-static version.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274466 13f79535-47bb-0310-9956-ffa450edef68
master
Magesh Umasankar 22 years ago
parent
commit
26a9faff10
7 changed files with 198 additions and 180 deletions
  1. +11
    -5
      src/main/org/apache/tools/ant/ComponentHelper.java
  2. +125
    -119
      src/main/org/apache/tools/ant/IntrospectionHelper.java
  3. +7
    -3
      src/main/org/apache/tools/ant/Main.java
  4. +44
    -48
      src/main/org/apache/tools/ant/Project.java
  5. +3
    -3
      src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
  6. +4
    -1
      src/main/org/apache/tools/ant/types/Mapper.java
  7. +4
    -1
      src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java

+ 11
- 5
src/main/org/apache/tools/ant/ComponentHelper.java View File

@@ -65,12 +65,12 @@ import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;


/**
/**
* Component creation and configuration. * Component creation and configuration.
* *
* This is cut&paste from Project.java of everything related to * This is cut&paste from Project.java of everything related to
* task/type management. Project will just delegate. * task/type management. Project will just delegate.
*
*
* A very simple hook mechnism is provided that allows users to plug * A very simple hook mechnism is provided that allows users to plug
* in custom code. It is also possible to replace the default behavior * in custom code. It is also possible to replace the default behavior
* ( for example in an app embeding ant ) * ( for example in an app embeding ant )
@@ -407,7 +407,9 @@ public class ComponentHelper {


try { try {
Object o = c.newInstance(); Object o = c.newInstance();
Project.setProjectOnObject(project, o);
if ( project != null ) {
project.setProjectReference( o );
}
Task task = null; Task task = null;
if (o instanceof Task) { if (o instanceof Task) {
task = (Task) o; task = (Task) o;
@@ -416,7 +418,9 @@ public class ComponentHelper {
// and an Adapter // and an Adapter
TaskAdapter taskA = new TaskAdapter(); TaskAdapter taskA = new TaskAdapter();
taskA.setProxy(o); taskA.setProxy(o);
Project.setProjectOnObject(project, taskA);
if ( project != null ) {
project.setProjectReference( taskA );
}
task = taskA; task = taskA;
} }
task.setTaskType(taskType); task.setTaskType(taskType);
@@ -521,7 +525,9 @@ public class ComponentHelper {
} else { } else {
o = ctor.newInstance(new Object[] {this}); o = ctor.newInstance(new Object[] {this});
} }
Project.setProjectOnObject(project, o);
if ( project != null ) {
project.setProjectReference( o );
}
String msg = " +DataType: " + typeName; String msg = " +DataType: " + typeName;
project.log(msg, Project.MSG_DEBUG); project.log(msg, Project.MSG_DEBUG);
return o; return o;


+ 125
- 119
src/main/org/apache/tools/ant/IntrospectionHelper.java View File

@@ -74,31 +74,31 @@ import org.apache.tools.ant.types.Path;
public class IntrospectionHelper implements BuildListener { public class IntrospectionHelper implements BuildListener {


/** /**
* Map from attribute names to attribute types
* Map from attribute names to attribute types
* (String to Class). * (String to Class).
*/ */
private Hashtable attributeTypes; private Hashtable attributeTypes;


/** /**
* Map from attribute names to attribute setter methods
* Map from attribute names to attribute setter methods
* (String to AttributeSetter). * (String to AttributeSetter).
*/ */
private Hashtable attributeSetters; private Hashtable attributeSetters;


/** /**
* Map from attribute names to nested types
* Map from attribute names to nested types
* (String to Class). * (String to Class).
*/ */
private Hashtable nestedTypes; private Hashtable nestedTypes;


/** /**
* Map from attribute names to methods to create nested types
* Map from attribute names to methods to create nested types
* (String to NestedCreator). * (String to NestedCreator).
*/ */
private Hashtable nestedCreators; private Hashtable nestedCreators;


/** /**
* Map from attribute names to methods to store configured nested types
* Map from attribute names to methods to store configured nested types
* (String to NestedStorer). * (String to NestedStorer).
*/ */
private Hashtable nestedStorers; private Hashtable nestedStorers;
@@ -118,9 +118,9 @@ public class IntrospectionHelper implements BuildListener {
*/ */
private static Hashtable helpers = new Hashtable(); private static Hashtable helpers = new Hashtable();


/**
* Map from primitive types to wrapper classes for use in
* createAttributeSetter (Class to Class). Note that char
/**
* Map from primitive types to wrapper classes for use in
* createAttributeSetter (Class to Class). Note that char
* and boolean are in here even though they get special treatment * and boolean are in here even though they get special treatment
* - this way we only need to test for the wrapper class. * - this way we only need to test for the wrapper class.
*/ */
@@ -128,18 +128,18 @@ public class IntrospectionHelper implements BuildListener {


// Set up PRIMITIVE_TYPE_MAP // Set up PRIMITIVE_TYPE_MAP
static { static {
Class[] primitives = {Boolean.TYPE, Byte.TYPE, Character.TYPE,
Short.TYPE, Integer.TYPE, Long.TYPE,
Class[] primitives = {Boolean.TYPE, Byte.TYPE, Character.TYPE,
Short.TYPE, Integer.TYPE, Long.TYPE,
Float.TYPE, Double.TYPE}; Float.TYPE, Double.TYPE};
Class[] wrappers = {Boolean.class, Byte.class, Character.class,
Short.class, Integer.class, Long.class,
Class[] wrappers = {Boolean.class, Byte.class, Character.class,
Short.class, Integer.class, Long.class,
Float.class, Double.class}; Float.class, Double.class};
for (int i = 0; i < primitives.length; i++) { for (int i = 0; i < primitives.length; i++) {
PRIMITIVE_TYPE_MAP.put (primitives[i], wrappers[i]); PRIMITIVE_TYPE_MAP.put (primitives[i], wrappers[i]);
} }
} }


// XXX: (Jon Skeet) The documentation below doesn't draw a clear
// XXX: (Jon Skeet) The documentation below doesn't draw a clear
// distinction between addConfigured and add. It's obvious what the // distinction between addConfigured and add. It's obvious what the
// code *here* does (addConfigured sets both a creator method which // code *here* does (addConfigured sets both a creator method which
// calls a no-arg constructor and a storer method which calls the // calls a no-arg constructor and a storer method which calls the
@@ -148,49 +148,49 @@ public class IntrospectionHelper implements BuildListener {
// obvious what the difference in actual *effect* will be later // obvious what the difference in actual *effect* will be later
// on. I can't see any mention of addConfiguredXXX in "Developing // on. I can't see any mention of addConfiguredXXX in "Developing
// with Ant" (at least in the version on the web site). Someone // with Ant" (at least in the version on the web site). Someone
// who understands should update this documentation
// who understands should update this documentation
// (and preferably the manual too) at some stage. // (and preferably the manual too) at some stage.
/** /**
* Sole constructor, which is private to ensure that all
* Sole constructor, which is private to ensure that all
* IntrospectionHelpers are created via {@link #getHelper(Class) getHelper}. * IntrospectionHelpers are created via {@link #getHelper(Class) getHelper}.
* Introspects the given class for bean-like methods. * Introspects the given class for bean-like methods.
* Each method is examined in turn, and the following rules are applied: * Each method is examined in turn, and the following rules are applied:
* <p> * <p>
* <ul> * <ul>
* <li>If the method is <code>Task.setLocation(Location)</code>,
* <li>If the method is <code>Task.setLocation(Location)</code>,
* <code>Task.setTaskType(String)</code> * <code>Task.setTaskType(String)</code>
* or <code>TaskContainer.addTask(Task)</code>, it is ignored. These
* or <code>TaskContainer.addTask(Task)</code>, it is ignored. These
* methods are handled differently elsewhere. * methods are handled differently elsewhere.
* <li><code>void addText(String)</code> is recognised as the method for * <li><code>void addText(String)</code> is recognised as the method for
* adding PCDATA to a bean. * adding PCDATA to a bean.
* <li><code>void setFoo(Bar)</code> is recognised as a method for
* setting the value of attribute <code>foo</code>, so long as
* <code>Bar</code> is non-void and is not an array type. Non-String
* <li><code>void setFoo(Bar)</code> is recognised as a method for
* setting the value of attribute <code>foo</code>, so long as
* <code>Bar</code> is non-void and is not an array type. Non-String
* parameter types always overload String parameter types, but that is * parameter types always overload String parameter types, but that is
* the only guarantee made in terms of priority. * the only guarantee made in terms of priority.
* <li><code>Foo createBar()</code> is recognised as a method for * <li><code>Foo createBar()</code> is recognised as a method for
* creating a nested element called <code>bar</code> of type
* creating a nested element called <code>bar</code> of type
* <code>Foo</code>, so long as <code>Foo</code> is not a primitive or * <code>Foo</code>, so long as <code>Foo</code> is not a primitive or
* array type. * array type.
* <li><code>void addConfiguredFoo(Bar)</code> is recognised as a * <li><code>void addConfiguredFoo(Bar)</code> is recognised as a
* method for storing a pre-configured element called
* method for storing a pre-configured element called
* <code>foo</code> and of type <code>Bar</code>, so long as * <code>foo</code> and of type <code>Bar</code>, so long as
* <code>Bar</code> is not an array, primitive or String type.
* <code>Bar</code> must have an accessible constructor taking no
* <code>Bar</code> is not an array, primitive or String type.
* <code>Bar</code> must have an accessible constructor taking no
* arguments. * arguments.
* <li><code>void addFoo(Bar)</code> is recognised as a * <li><code>void addFoo(Bar)</code> is recognised as a
* method for storing an element called <code>foobar</code>
* method for storing an element called <code>foobar</code>
* and of type <code>Baz</code>, so long as * and of type <code>Baz</code>, so long as
* <code>Baz</code> is not an array, primitive or String type.
* <code>Baz</code> must have an accessible constructor taking no
* <code>Baz</code> is not an array, primitive or String type.
* <code>Baz</code> must have an accessible constructor taking no
* arguments. * arguments.
* </ul> * </ul>
* Note that only one method is retained to create/set/addConfigured/add
* Note that only one method is retained to create/set/addConfigured/add
* any element or attribute. * any element or attribute.
*
* @param bean The bean type to introspect.
*
* @param bean The bean type to introspect.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @see #getHelper(Class) * @see #getHelper(Class)
*/ */
private IntrospectionHelper(final Class bean) { private IntrospectionHelper(final Class bean) {
@@ -257,7 +257,7 @@ public class IntrospectionHelper implements BuildListener {
particular order. particular order.
*/ */
} }
AttributeSetter as
AttributeSetter as
= createAttributeSetter(m, args[0], propName); = createAttributeSetter(m, args[0], propName);
if (as != null) { if (as != null) {
attributeTypes.put(propName, args[0]); attributeTypes.put(propName, args[0]);
@@ -346,35 +346,35 @@ public class IntrospectionHelper implements BuildListener {
} }
} }


/**
* Certain set methods are part of the Ant core interface to tasks and
/**
* Certain set methods are part of the Ant core interface to tasks and
* therefore not to be considered for introspection * therefore not to be considered for introspection
* *
* @param name the name of the set method * @param name the name of the set method
* @param type the type of the set method's parameter
* @param type the type of the set method's parameter
* @return true if the given set method is to be hidden. * @return true if the given set method is to be hidden.
*/ */
private boolean isHiddenSetMethod(String name, Class type) { private boolean isHiddenSetMethod(String name, Class type) {
if ("setLocation".equals(name)
if ("setLocation".equals(name)
&& org.apache.tools.ant.Location.class.equals(type)) { && org.apache.tools.ant.Location.class.equals(type)) {
return true; return true;
} }
if ("setTaskType".equals(name)
if ("setTaskType".equals(name)
&& java.lang.String.class.equals(type)) { && java.lang.String.class.equals(type)) {
return true; return true;
} }
return false; return false;
} }
/** /**
* Returns a helper for the given class, either from the cache * Returns a helper for the given class, either from the cache
* or by creating a new instance. * or by creating a new instance.
*
*
* @param c The class for which a helper is required. * @param c The class for which a helper is required.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @return a helper for the specified class * @return a helper for the specified class
*/ */
public static synchronized IntrospectionHelper getHelper(Class c) { public static synchronized IntrospectionHelper getHelper(Class c) {
@@ -411,21 +411,21 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Sets the named attribute in the given element, which is part of the
* Sets the named attribute in the given element, which is part of the
* given project. * given project.
*
* @param p The project containing the element. This is used when files
*
* @param p The project containing the element. This is used when files
* need to be resolved. Must not be <code>null</code>. * need to be resolved. Must not be <code>null</code>.
* @param element The element to set the attribute in. Must not be
* @param element The element to set the attribute in. Must not be
* <code>null</code>. * <code>null</code>.
* @param attributeName The name of the attribute to set. Must not be * @param attributeName The name of the attribute to set. Must not be
* <code>null</code>. * <code>null</code>.
* @param value The value to set the attribute to. This may be interpreted * @param value The value to set the attribute to. This may be interpreted
* or converted to the necessary type if the setter method * or converted to the necessary type if the setter method
* doesn't just take a string. Must not be <code>null</code>. * doesn't just take a string. Must not be <code>null</code>.
*
* @exception BuildException if the introspected class doesn't support
* the given attribute, or if the setting
*
* @exception BuildException if the introspected class doesn't support
* the given attribute, or if the setting
* method fails. * method fails.
*/ */
public void setAttribute(Project p, Object element, String attributeName, public void setAttribute(Project p, Object element, String attributeName,
@@ -459,23 +459,23 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Adds PCDATA to an element, using the element's
* Adds PCDATA to an element, using the element's
* <code>void addText(String)</code> method, if it has one. If no * <code>void addText(String)</code> method, if it has one. If no
* such method is present, a BuildException is thrown if the
* such method is present, a BuildException is thrown if the
* given text contains non-whitespace. * given text contains non-whitespace.
*
* @param project The project which the element is part of.
*
* @param project The project which the element is part of.
* Must not be <code>null</code>. * Must not be <code>null</code>.
* @param element The element to add the text to.
* @param element The element to add the text to.
* Must not be <code>null</code>. * Must not be <code>null</code>.
* @param text The text to add. * @param text The text to add.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @exception BuildException if non-whitespace text is provided and no * @exception BuildException if non-whitespace text is provided and no
* method is available to handle it, or if * method is available to handle it, or if
* the handling method fails. * the handling method fails.
*/ */
public void addText(Project project, Object element, String text)
public void addText(Project project, Object element, String text)
throws BuildException { throws BuildException {
if (addText == null) { if (addText == null) {
// Element doesn't handle text content // Element doesn't handle text content
@@ -503,19 +503,19 @@ public class IntrospectionHelper implements BuildListener {
} }
} }


public void throwNotSupported(Project project, Object parent,
public void throwNotSupported(Project project, Object parent,
String elementName) { String elementName) {
String msg = project.getElementName(parent) + String msg = project.getElementName(parent) +
" doesn't support the nested \"" + elementName + "\" element."; " doesn't support the nested \"" + elementName + "\" element.";
throw new BuildException(msg); throw new BuildException(msg);
}
}
/** /**
* Creates a named nested element. Depending on the results of the * Creates a named nested element. Depending on the results of the
* initial introspection, either a method in the given parent instance * initial introspection, either a method in the given parent instance
* or a simple no-arg constructor is used to create an instance of the * or a simple no-arg constructor is used to create an instance of the
* specified element type. * specified element type.
*
*
* @param project Project to which the parent object belongs. * @param project Project to which the parent object belongs.
* Must not be <code>null</code>. If the resulting * Must not be <code>null</code>. If the resulting
* object is an instance of ProjectComponent, its * object is an instance of ProjectComponent, its
@@ -524,21 +524,23 @@ public class IntrospectionHelper implements BuildListener {
* Must not be <code>null</code>. * Must not be <code>null</code>.
* @param elementName Name of the element to create an instance of. * @param elementName Name of the element to create an instance of.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @return an instance of the specified element type * @return an instance of the specified element type
*
*
* @exception BuildException if no method is available to create the * @exception BuildException if no method is available to create the
* element instance, or if the creating method * element instance, or if the creating method
* fails. * fails.
*/ */
public Object createElement(Project project, Object parent,
public Object createElement(Project project, Object parent,
String elementName) throws BuildException { String elementName) throws BuildException {
NestedCreator nc = (NestedCreator) nestedCreators.get(elementName); NestedCreator nc = (NestedCreator) nestedCreators.get(elementName);
if (nc == null && parent instanceof DynamicConfigurator) { if (nc == null && parent instanceof DynamicConfigurator) {
DynamicConfigurator dc = (DynamicConfigurator) parent; DynamicConfigurator dc = (DynamicConfigurator) parent;
Object nestedElement = dc.createDynamicElement(elementName); Object nestedElement = dc.createDynamicElement(elementName);
if (nestedElement != null) { if (nestedElement != null) {
Project.setProjectOnObject(project, nestedElement);
if ( project != null ) {
project.setProjectReference( nestedElement );
}
return nestedElement; return nestedElement;
} }
} }
@@ -547,7 +549,9 @@ public class IntrospectionHelper implements BuildListener {
} }
try { try {
Object nestedElement = nc.create(parent); Object nestedElement = nc.create(parent);
Project.setProjectOnObject(project, nestedElement);
if ( project != null ) {
project.setProjectReference( nestedElement );
}
return nestedElement; return nestedElement;
} catch (IllegalAccessException ie) { } catch (IllegalAccessException ie) {
// impossible as getMethods should only return public methods // impossible as getMethods should only return public methods
@@ -565,7 +569,7 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Indicate if this element supports a nested element of the
* Indicate if this element supports a nested element of the
* given name. * given name.
* *
* @param elementName the name of the nested element being checked * @param elementName the name of the nested element being checked
@@ -576,28 +580,28 @@ public class IntrospectionHelper implements BuildListener {
return nestedCreators.containsKey(elementName) || return nestedCreators.containsKey(elementName) ||
DynamicConfigurator.class.isAssignableFrom(bean); DynamicConfigurator.class.isAssignableFrom(bean);
} }
/** /**
* Stores a named nested element using a storage method determined * Stores a named nested element using a storage method determined
* by the initial introspection. If no appropriate storage method * by the initial introspection. If no appropriate storage method
* is available, this method returns immediately. * is available, this method returns immediately.
*
* @param project Ignored in this implementation.
*
* @param project Ignored in this implementation.
* May be <code>null</code>. * May be <code>null</code>.
*
* @param parent Parent instance to store the child in.
*
* @param parent Parent instance to store the child in.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @param child Child instance to store in the parent. * @param child Child instance to store in the parent.
* Should not be <code>null</code>. * Should not be <code>null</code>.
*
* @param elementName Name of the child element to store.
*
* @param elementName Name of the child element to store.
* May be <code>null</code>, in which case * May be <code>null</code>, in which case
* this method returns immediately. * this method returns immediately.
*
*
* @exception BuildException if the storage method fails. * @exception BuildException if the storage method fails.
*/ */
public void storeElement(Project project, Object parent, Object child,
public void storeElement(Project project, Object parent, Object child,
String elementName) throws BuildException { String elementName) throws BuildException {
if (elementName == null) { if (elementName == null) {
return; return;
@@ -625,13 +629,13 @@ public class IntrospectionHelper implements BuildListener {


/** /**
* Returns the type of a named nested element. * Returns the type of a named nested element.
*
*
* @param elementName The name of the element to find the type of. * @param elementName The name of the element to find the type of.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @return the type of the nested element with the specified name. * @return the type of the nested element with the specified name.
* This will never be <code>null</code>. * This will never be <code>null</code>.
*
*
* @exception BuildException if the introspected class does not * @exception BuildException if the introspected class does not
* support the named nested element. * support the named nested element.
*/ */
@@ -648,13 +652,13 @@ public class IntrospectionHelper implements BuildListener {


/** /**
* Returns the type of a named attribute. * Returns the type of a named attribute.
*
*
* @param attributeName The name of the attribute to find the type of. * @param attributeName The name of the attribute to find the type of.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @return the type of the attribute with the specified name. * @return the type of the attribute with the specified name.
* This will never be <code>null</code>. * This will never be <code>null</code>.
*
*
* @exception BuildException if the introspected class does not * @exception BuildException if the introspected class does not
* support the named attribute. * support the named attribute.
*/ */
@@ -671,7 +675,7 @@ public class IntrospectionHelper implements BuildListener {


/** /**
* Returns whether or not the introspected class supports PCDATA. * Returns whether or not the introspected class supports PCDATA.
*
*
* @return whether or not the introspected class supports PCDATA. * @return whether or not the introspected class supports PCDATA.
*/ */
public boolean supportsCharacters() { public boolean supportsCharacters() {
@@ -679,9 +683,9 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Returns an enumeration of the names of the attributes supported
* Returns an enumeration of the names of the attributes supported
* by the introspected class. * by the introspected class.
*
*
* @return an enumeration of the names of the attributes supported * @return an enumeration of the names of the attributes supported
* by the introspected class. * by the introspected class.
*/ */
@@ -690,9 +694,9 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Returns an enumeration of the names of the nested elements supported
* Returns an enumeration of the names of the nested elements supported
* by the introspected class. * by the introspected class.
*
*
* @return an enumeration of the names of the nested elements supported * @return an enumeration of the names of the nested elements supported
* by the introspected class. * by the introspected class.
*/ */
@@ -707,36 +711,36 @@ public class IntrospectionHelper implements BuildListener {
* <ul> * <ul>
* <li>String (left as it is) * <li>String (left as it is)
* <li>Character/char (first character is used) * <li>Character/char (first character is used)
* <li>Boolean/boolean
* <li>Boolean/boolean
* ({@link Project#toBoolean(String) Project.toBoolean(String)} is used) * ({@link Project#toBoolean(String) Project.toBoolean(String)} is used)
* <li>Class (Class.forName is used) * <li>Class (Class.forName is used)
* <li>File (resolved relative to the appropriate project) * <li>File (resolved relative to the appropriate project)
* <li>Path (resolve relative to the appropriate project) * <li>Path (resolve relative to the appropriate project)
* <li>EnumeratedAttribute (uses its own
* <li>EnumeratedAttribute (uses its own
* {@link EnumeratedAttribute#setValue(String) setValue} method) * {@link EnumeratedAttribute#setValue(String) setValue} method)
* <li>Other primitive types (wrapper classes are used with constructors
* <li>Other primitive types (wrapper classes are used with constructors
* taking String) * taking String)
* </ul> * </ul>
*
* If none of the above covers the given parameters, a constructor for the
*
* If none of the above covers the given parameters, a constructor for the
* appropriate class taking a String parameter is used if it is available. * appropriate class taking a String parameter is used if it is available.
*
*
* @param m The method to invoke on the bean when the setter is invoked. * @param m The method to invoke on the bean when the setter is invoked.
* Must not be <code>null</code>. * Must not be <code>null</code>.
* @param arg The type of the single argument of the bean's method. * @param arg The type of the single argument of the bean's method.
* Must not be <code>null</code>. * Must not be <code>null</code>.
* @param attrName the name of the attribute for which the setter is being * @param attrName the name of the attribute for which the setter is being
* created. * created.
*
*
* @return an appropriate AttributeSetter instance, or <code>null</code> * @return an appropriate AttributeSetter instance, or <code>null</code>
* if no appropriate conversion is available. * if no appropriate conversion is available.
*/ */
private AttributeSetter createAttributeSetter(final Method m, private AttributeSetter createAttributeSetter(final Method m,
Class arg,
Class arg,
final String attrName) { final String attrName) {
// use wrappers for primitive classes, e.g. int and
// use wrappers for primitive classes, e.g. int and
// Integer are treated identically // 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; ? (Class) PRIMITIVE_TYPE_MAP.get(arg) : arg;


// simplest case - setAttribute expects String // simplest case - setAttribute expects String
@@ -754,15 +758,15 @@ public class IntrospectionHelper implements BuildListener {
public void set(Project p, Object parent, String value) public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException { throws InvocationTargetException, IllegalAccessException {
if (value.length() == 0) { if (value.length() == 0) {
throw new BuildException("The value \"\" is not a "
+ "legal value for attribute \""
throw new BuildException("The value \"\" is not a "
+ "legal value for attribute \""
+ attrName + "\""); + attrName + "\"");
} }
m.invoke(parent, new Character[] {new Character(value.charAt(0))}); m.invoke(parent, new Character[] {new Character(value.charAt(0))});
} }


}; };
// boolean and Boolean get special treatment because we
// boolean and Boolean get special treatment because we
// have a nice method in Project // have a nice method in Project
} else if (java.lang.Boolean.class.equals(reflectedArg)) { } else if (java.lang.Boolean.class.equals(reflectedArg)) {
return new AttributeSetter() { return new AttributeSetter() {
@@ -813,7 +817,7 @@ public class IntrospectionHelper implements BuildListener {
public void set(Project p, Object parent, String value) public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException, BuildException { throws InvocationTargetException, IllegalAccessException, BuildException {
try { try {
org.apache.tools.ant.types.EnumeratedAttribute ea =
org.apache.tools.ant.types.EnumeratedAttribute ea =
(org.apache.tools.ant.types.EnumeratedAttribute) reflectedArg.newInstance(); (org.apache.tools.ant.types.EnumeratedAttribute) reflectedArg.newInstance();
ea.setValue(value); ea.setValue(value);
m.invoke(parent, new EnumeratedAttribute[] {ea}); m.invoke(parent, new EnumeratedAttribute[] {ea});
@@ -824,7 +828,7 @@ public class IntrospectionHelper implements BuildListener {
}; };


// worst case. look for a public String constructor and use it // worst case. look for a public String constructor and use it
// This is used (deliberately) for all primitives/wrappers other than
// This is used (deliberately) for all primitives/wrappers other than
// char and boolean // char and boolean
} else { } else {


@@ -838,7 +842,9 @@ public class IntrospectionHelper implements BuildListener {
throws InvocationTargetException, IllegalAccessException, BuildException { throws InvocationTargetException, IllegalAccessException, BuildException {
try { try {
Object attribute = c.newInstance(new String[] {value}); Object attribute = c.newInstance(new String[] {value});
Project.setProjectOnObject(p, attribute);
if ( p != null ) {
p.setProjectReference( attribute );
}
m.invoke(parent, new Object[] {attribute}); m.invoke(parent, new Object[] {attribute});
} catch (InstantiationException ie) { } catch (InstantiationException ie) {
throw new BuildException(ie); throw new BuildException(ie);
@@ -858,13 +864,13 @@ public class IntrospectionHelper implements BuildListener {
* relation to a given project. This is used for logging purposes * relation to a given project. This is used for logging purposes
* when the element is asked to cope with some data it has no * when the element is asked to cope with some data it has no
* way of handling. * way of handling.
*
* @param project The project the element is defined in.
*
* @param project The project the element is defined in.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @param element The element to describe. * @param element The element to describe.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @return a description of the element type * @return a description of the element type
*/ */
protected String getElementName(Project project, Object element) { protected String getElementName(Project project, Object element) {
@@ -876,12 +882,12 @@ public class IntrospectionHelper implements BuildListener {
* a given prefix and converting into lower case. It is up to calling * a given prefix and converting into lower case. It is up to calling
* code to make sure the method name does actually begin with the * code to make sure the method name does actually begin with the
* specified prefix - no checking is done in this method. * specified prefix - no checking is done in this method.
*
*
* @param methodName The name of the method in question. * @param methodName The name of the method in question.
* Must not be <code>null</code>. * Must not be <code>null</code>.
* @param prefix The prefix to remove. * @param prefix The prefix to remove.
* Must not be <code>null</code>. * Must not be <code>null</code>.
*
*
* @return the lower-cased method name with the prefix removed. * @return the lower-cased method name with the prefix removed.
*/ */
private String getPropertyName(String methodName, String prefix) { private String getPropertyName(String methodName, String prefix) {
@@ -890,7 +896,7 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Internal interface used to create nested elements. Not documented
* Internal interface used to create nested elements. Not documented
* in detail for reasons of source code readability. * in detail for reasons of source code readability.
*/ */
private interface NestedCreator { private interface NestedCreator {
@@ -899,7 +905,7 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Internal interface used to storing nested elements. Not documented
* Internal interface used to storing nested elements. Not documented
* in detail for reasons of source code readability. * in detail for reasons of source code readability.
*/ */
private interface NestedStorer { private interface NestedStorer {
@@ -908,7 +914,7 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Internal interface used to setting element attributes. Not documented
* Internal interface used to setting element attributes. Not documented
* in detail for reasons of source code readability. * in detail for reasons of source code readability.
*/ */
private interface AttributeSetter { private interface AttributeSetter {
@@ -918,9 +924,9 @@ public class IntrospectionHelper implements BuildListener {
} }


/** /**
* Clears all storage used by this class, including the static cache of
* Clears all storage used by this class, including the static cache of
* helpers. * helpers.
*
*
* @param event Ignored in this implementation. * @param event Ignored in this implementation.
*/ */
public void buildFinished(BuildEvent event) { public void buildFinished(BuildEvent event) {
@@ -937,35 +943,35 @@ public class IntrospectionHelper implements BuildListener {
* @param event Ignored in this implementation. * @param event Ignored in this implementation.
*/ */
public void buildStarted(BuildEvent event) {} public void buildStarted(BuildEvent event) {}
/** /**
* Empty implementation to satisfy the BuildListener interface. * Empty implementation to satisfy the BuildListener interface.
* *
* @param event Ignored in this implementation. * @param event Ignored in this implementation.
*/ */
public void targetStarted(BuildEvent event) {} public void targetStarted(BuildEvent event) {}
/** /**
* Empty implementation to satisfy the BuildListener interface. * Empty implementation to satisfy the BuildListener interface.
* *
* @param event Ignored in this implementation. * @param event Ignored in this implementation.
*/ */
public void targetFinished(BuildEvent event) {} public void targetFinished(BuildEvent event) {}
/** /**
* Empty implementation to satisfy the BuildListener interface. * Empty implementation to satisfy the BuildListener interface.
* *
* @param event Ignored in this implementation. * @param event Ignored in this implementation.
*/ */
public void taskStarted(BuildEvent event) {} public void taskStarted(BuildEvent event) {}
/** /**
* Empty implementation to satisfy the BuildListener interface. * Empty implementation to satisfy the BuildListener interface.
* *
* @param event Ignored in this implementation. * @param event Ignored in this implementation.
*/ */
public void taskFinished(BuildEvent event) {} public void taskFinished(BuildEvent event) {}
/** /**
* Empty implementation to satisfy the BuildListener interface. * Empty implementation to satisfy the BuildListener interface.
* *


+ 7
- 3
src/main/org/apache/tools/ant/Main.java View File

@@ -182,7 +182,7 @@ public class Main {
printMessage(exc); printMessage(exc);
System.exit(1); System.exit(1);
} }
if (additionalUserProperties != null) { if (additionalUserProperties != null) {
for (Enumeration e = additionalUserProperties.keys(); for (Enumeration e = additionalUserProperties.keys();
e.hasMoreElements();) { e.hasMoreElements();) {
@@ -649,7 +649,9 @@ public class Main {
try { try {
BuildListener listener = BuildListener listener =
(BuildListener) Class.forName(className).newInstance(); (BuildListener) Class.forName(className).newInstance();
Project.setProjectOnObject(project, listener);
if ( project != null ) {
project.setProjectReference( listener );
}
project.addBuildListener(listener); project.addBuildListener(listener);
} catch (Throwable exc) { } catch (Throwable exc) {
throw new BuildException("Unable to instantiate listener " throw new BuildException("Unable to instantiate listener "
@@ -672,7 +674,9 @@ public class Main {
try { try {
handler = (InputHandler) handler = (InputHandler)
(Class.forName(inputHandlerClassname).newInstance()); (Class.forName(inputHandlerClassname).newInstance());
Project.setProjectOnObject(project, handler);
if ( project != null ) {
project.setProjectReference( handler );
}
} catch (ClassCastException e) { } catch (ClassCastException e) {
String msg = "The specified input handler class " String msg = "The specified input handler class "
+ inputHandlerClassname + inputHandlerClassname


+ 44
- 48
src/main/org/apache/tools/ant/Project.java View File

@@ -115,12 +115,12 @@ public class Project {
private static final String VISITED = "VISITED"; private static final String VISITED = "VISITED";


/** /**
* The class name of the Ant class loader to use for
* The class name of the Ant class loader to use for
* JDK 1.2 and above * JDK 1.2 and above
*/ */
private static final String ANTCLASSLOADER_JDK12 private static final String ANTCLASSLOADER_JDK12
= "org.apache.tools.ant.loader.AntClassLoader2"; = "org.apache.tools.ant.loader.AntClassLoader2";
/** /**
* Version constant for Java 1.0 * Version constant for Java 1.0
* *
@@ -219,10 +219,10 @@ public class Project {
* The default input stream used to read any input * The default input stream used to read any input
*/ */
private InputStream defaultInputStream = null; private InputStream defaultInputStream = null;
/** /**
* Sets the input handler * Sets the input handler
*
*
* @param handler the InputHandler instance to use for gathering input. * @param handler the InputHandler instance to use for gathering input.
*/ */
public void setInputHandler(InputHandler handler) { public void setInputHandler(InputHandler handler) {
@@ -230,11 +230,11 @@ public class Project {
} }


/** /**
* Set the default System input stream. Normally this stream is set to
* Set the default System input stream. Normally this stream is set to
* System.in. This inputStream is used when no task inptu redirection is * System.in. This inputStream is used when no task inptu redirection is
* being performed. * being performed.
* *
* @param defaultInputStream the default input stream to use when input
* @param defaultInputStream the default input stream to use when input
* is reuested. * is reuested.
* @since Ant 1.6 * @since Ant 1.6
*/ */
@@ -245,17 +245,17 @@ public class Project {
/** /**
* Get this project's input stream * Get this project's input stream
* *
* @return the InputStream instance in use by this Porject instance to
* @return the InputStream instance in use by this Porject instance to
* read input * read input
*/ */
public InputStream getDefaultInputStream() { public InputStream getDefaultInputStream() {
return defaultInputStream; return defaultInputStream;
} }
/** /**
* Retrieves the current input handler. * Retrieves the current input handler.
* *
* @return the InputHandler instance currently in place for the project
* @return the InputHandler instance currently in place for the project
* instance. * instance.
*/ */
public InputHandler getInputHandler() { public InputHandler getInputHandler() {
@@ -265,11 +265,11 @@ public class Project {
/** Instance of a utility class to use for file operations. */ /** Instance of a utility class to use for file operations. */
private FileUtils fileUtils; private FileUtils fileUtils;


/**
* Flag which catches Listeners which try to use System.out or System.err
/**
* Flag which catches Listeners which try to use System.out or System.err
*/ */
private boolean loggingMessage = false; private boolean loggingMessage = false;
/** /**
* Creates a new Ant project. * Creates a new Ant project.
*/ */
@@ -359,7 +359,7 @@ public class Project {
* a given path * a given path
* *
* @param path the path from whcih clases are to be loaded. * @param path the path from whcih clases are to be loaded.
*
*
* @return an appropriate classloader * @return an appropriate classloader
*/ */
public AntClassLoader createClassLoader(Path path) { public AntClassLoader createClassLoader(Path path) {
@@ -496,7 +496,7 @@ public class Project {
* @since 1.5 * @since 1.5
*/ */
public synchronized void setNewProperty(String name, String value) { public synchronized void setNewProperty(String name, String value) {
PropertyHelper.getPropertyHelper(this).setNewProperty(null, name,
PropertyHelper.getPropertyHelper(this).setNewProperty(null, name,
value); value);
} }


@@ -510,7 +510,7 @@ public class Project {
* @see #setProperty(String,String) * @see #setProperty(String,String)
*/ */
public synchronized void setUserProperty(String name, String value) { public synchronized void setUserProperty(String name, String value) {
PropertyHelper.getPropertyHelper(this).setUserProperty(null, name,
PropertyHelper.getPropertyHelper(this).setUserProperty(null, name,
value); value);
} }


@@ -1134,7 +1134,7 @@ public class Project {


try { try {
Object o = c.newInstance(); Object o = c.newInstance();
setProjectOnObject(this, o);
setProjectReference( o );
Task task = null; Task task = null;
if (o instanceof Task) { if (o instanceof Task) {
task = (Task) o; task = (Task) o;
@@ -1247,7 +1247,7 @@ public class Project {
} else { } else {
o = ctor.newInstance(new Object[] {this}); o = ctor.newInstance(new Object[] {this});
} }
setProjectOnObject(this, o);
setProjectReference( o );
String msg = " +DataType: " + typeName; String msg = " +DataType: " + typeName;
log (msg, MSG_DEBUG); log (msg, MSG_DEBUG);
return o; return o;
@@ -1302,19 +1302,19 @@ public class Project {
} }


/** /**
* Read data from the default input stream. If no default has been
* specified, System.in is used.
* Read data from the default input stream. If no default has been
* specified, System.in is used.
* *
* @param buffer the buffer into which data is to be read. * @param buffer the buffer into which data is to be read.
* @param offset the offset into the buffer at which data is stored. * @param offset the offset into the buffer at which data is stored.
* @param length the amount of data to read * @param length the amount of data to read
* *
* @return the number of bytes read * @return the number of bytes read
*
*
* @exception IOException if the data cannot be read * @exception IOException if the data cannot be read
* @since Ant 1.6 * @since Ant 1.6
*/ */
public int defaultInput(byte[] buffer, int offset, int length)
public int defaultInput(byte[] buffer, int offset, int length)
throws IOException { throws IOException {
if (defaultInputStream != null) { if (defaultInputStream != null) {
return defaultInputStream.read(buffer, offset, length); return defaultInputStream.read(buffer, offset, length);
@@ -1322,7 +1322,7 @@ public class Project {
throw new EOFException("No input provided for project"); throw new EOFException("No input provided for project");
} }
} }
/** /**
* Demux an input request to the correct task. * Demux an input request to the correct task.
* *
@@ -1331,11 +1331,11 @@ public class Project {
* @param length the amount of data to read * @param length the amount of data to read
* *
* @return the number of bytes read * @return the number of bytes read
*
*
* @exception IOException if the data cannot be read * @exception IOException if the data cannot be read
* @since Ant 1.6 * @since Ant 1.6
*/
public int demuxInput(byte[] buffer, int offset, int length)
*/
public int demuxInput(byte[] buffer, int offset, int length)
throws IOException { throws IOException {
Task task = getThreadTask(Thread.currentThread()); Task task = getThreadTask(Thread.currentThread());
if (task == null) { if (task == null) {
@@ -1344,7 +1344,7 @@ public class Project {
return task.handleInput(buffer, offset, length); return task.handleInput(buffer, offset, length);
} }
} }
/** /**
* Demultiplexes flush operation so that each task receives the appropriate * Demultiplexes flush operation so that each task receives the appropriate
* messages. If the current thread is not currently executing a task, * messages. If the current thread is not currently executing a task,
@@ -1369,8 +1369,8 @@ public class Project {
} }
} }


/** /**
* Executes the specified target and any targets it depends on. * Executes the specified target and any targets it depends on.
* *
@@ -2072,11 +2072,11 @@ public class Project {
Vector listeners = getBuildListeners(); Vector listeners = getBuildListeners();
synchronized (this) { synchronized (this) {
if (loggingMessage) { if (loggingMessage) {
throw new BuildException("Listener attempted to access "
+ (priority == MSG_ERR ? "System.err" : "System.out")
throw new BuildException("Listener attempted to access "
+ (priority == MSG_ERR ? "System.err" : "System.out")
+ " - infinite loop terminated"); + " - infinite loop terminated");
} }
loggingMessage = true;
loggingMessage = true;
for (int i = 0; i < listeners.size(); i++) { for (int i = 0; i < listeners.size(); i++) {
BuildListener listener = (BuildListener) listeners.elementAt(i); BuildListener listener = (BuildListener) listeners.elementAt(i);
listener.messageLogged(event); listener.messageLogged(event);
@@ -2166,7 +2166,7 @@ public class Project {
return task; return task;
} }


// Should move to a separate public class - and have API to add // Should move to a separate public class - and have API to add
// listeners, etc. // listeners, etc.
private static class AntRefTable extends Hashtable { private static class AntRefTable extends Hashtable {
@@ -2274,7 +2274,7 @@ public class Project {
return taskClass; return taskClass;
} catch (NoClassDefFoundError ncdfe) { } catch (NoClassDefFoundError ncdfe) {
project.log("Could not load a dependent class (" project.log("Could not load a dependent class ("
+ ncdfe.getMessage() + ") for task "
+ ncdfe.getMessage() + ") for task "
+ key, Project.MSG_DEBUG); + key, Project.MSG_DEBUG);
} catch (ClassNotFoundException cnfe) { } catch (ClassNotFoundException cnfe) {
project.log("Could not load class (" + value project.log("Could not load class (" + value
@@ -2292,7 +2292,7 @@ public class Project {
if (!(key instanceof String)) { if (!(key instanceof String)) {
return null; return null;
} }
project.log("Get task " + key, Project.MSG_DEBUG); project.log("Get task " + key, Project.MSG_DEBUG);
Object taskClass = getTask((String) key); Object taskClass = getTask((String) key);
if (taskClass != null) { if (taskClass != null) {
@@ -2305,27 +2305,24 @@ public class Project {
return get(key) != null; return get(key) != null;
} }
} }
/** /**
* set the project on a created object using object.setProject(project).
* Set a reference to this Project on the parameterized object.
* Need to set the project before other set/add elements * Need to set the project before other set/add elements
* are called * are called
* @param project the project object
* @param obj the object to invoke setProject(project) on
* @param obj the object to invoke setProject(this) on
*/ */
public static void setProjectOnObject(Project project, Object obj) {
if (project == null)
return;
if (obj instanceof ProjectComponent) {
((ProjectComponent) obj).setProject(project);
public final void setProjectReference( final Object obj ) {
if ( obj instanceof ProjectComponent ) {
( (ProjectComponent) obj ).setProject( this );
return; return;
} }
try { try {
Method method =
Method method =
obj.getClass().getMethod( obj.getClass().getMethod(
"setProject", new Class[] {Project.class});
if (method != null) {
method.invoke(obj, new Object[] {project});
"setProject", new Class[] {Project.class} );
if ( method != null ) {
method.invoke( obj, new Object[] { this } );
} }
} catch (Throwable e) { } catch (Throwable e) {
// ignore this if the object does not have // ignore this if the object does not have
@@ -2333,5 +2330,4 @@ public class Project {
// is private/protected. // is private/protected.
} }
} }

} }

+ 3
- 3
src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java View File

@@ -161,7 +161,7 @@ public final class ChainReaderHelper {
Object o = finalFilters.elementAt(i); Object o = finalFilters.elementAt(i);


if (o instanceof AntFilterReader) { if (o instanceof AntFilterReader) {
final AntFilterReader filter
final AntFilterReader filter
= (AntFilterReader) finalFilters.elementAt(i); = (AntFilterReader) finalFilters.elementAt(i);
final String className = filter.getClassName(); final String className = filter.getClassName();
final Path classpath = filter.getClasspath(); final Path classpath = filter.getClasspath();
@@ -235,9 +235,9 @@ public final class ChainReaderHelper {
((BaseFilterReader) obj).setProject(project); ((BaseFilterReader) obj).setProject(project);
return; return;
} }
Project.setProjectOnObject(project, obj);
project.setProjectReference( obj );
} }
/** /**
* Read data from the reader and return the * Read data from the reader and return the
* contents as a string. * contents as a string.


+ 4
- 1
src/main/org/apache/tools/ant/types/Mapper.java View File

@@ -204,7 +204,10 @@ public class Mapper extends DataType implements Cloneable {
} }


FileNameMapper m = (FileNameMapper) c.newInstance(); FileNameMapper m = (FileNameMapper) c.newInstance();
Project.setProjectOnObject(getProject(), m);
final Project project = getProject();
if ( project != null ) {
project.setProjectReference( m );
}
m.setFrom(from); m.setFrom(from);
m.setTo(to); m.setTo(to);
return m; return m;


+ 4
- 1
src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java View File

@@ -107,7 +107,10 @@ public class ExtendSelector extends BaseSelector {
AntClassLoader.initializeClass(c); AntClassLoader.initializeClass(c);
} }
dynselector = (FileSelector) c.newInstance(); dynselector = (FileSelector) c.newInstance();
Project.setProjectOnObject(getProject(), dynselector);
final Project project = getProject();
if ( project != null ) {
project.setProjectReference( dynselector );
}
} }
catch (ClassNotFoundException cnfexcept) { catch (ClassNotFoundException cnfexcept) {
setError("Selector " + classname + setError("Selector " + classname +


Loading…
Cancel
Save