IntrospectionHelperpublic final class IntrospectionHelper extends Object Helper class that collects the methods a task or nested element
holds to set attributes, create nested elements or hold PCDATA
elements.
The class is final as it has a private constructor. |
Fields Summary |
---|
private static final Map | EMPTY_MAPEMPTY_MAP was added in java 1.3 (EMPTY_SET and EMPTY_LIST
is in java 1.2!) | private static final Map | HELPERSHelper instances we've already created (Class.getName() to IntrospectionHelper). | private static final Map | PRIMITIVE_TYPE_MAPMap 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
- this way we only need to test for the wrapper class. | private static final int | MAX_REPORT_NESTED_TEXT | private static final String | ELLIPSIS | private Hashtable | attributeTypesMap from attribute names to attribute types
(String to Class). | private Hashtable | attributeSettersMap from attribute names to attribute setter methods
(String to AttributeSetter). | private Hashtable | nestedTypesMap from attribute names to nested types
(String to Class). | private Hashtable | nestedCreatorsMap from attribute names to methods to create nested types
(String to NestedCreator). | private List | addTypeMethodsVector of methods matching add[Configured](Class) pattern. | private Method | addTextThe method to invoke to add PCDATA. | private Class | beanThe class introspected by this instance. |
Constructors Summary |
---|
private IntrospectionHelper(Class bean)Sole constructor, which is private to ensure that all
IntrospectionHelpers are created via {@link #getHelper(Class) getHelper}.
Introspects the given class for bean-like methods.
Each method is examined in turn, and the following rules are applied:
- If the method is
Task.setLocation(Location) ,
Task.setTaskType(String)
or TaskContainer.addTask(Task) , it is ignored. These
methods are handled differently elsewhere.
void addText(String) is recognised as the method for
adding PCDATA to a bean.
void setFoo(Bar) is recognised as a method for
setting the value of attribute foo , so long as
Bar is non-void and is not an array type. Non-String
parameter types always overload String parameter types, but that is
the only guarantee made in terms of priority.
Foo createBar() is recognised as a method for
creating a nested element called bar of type
Foo , so long as Foo is not a primitive or
array type.
void addConfiguredFoo(Bar) is recognised as a
method for storing a pre-configured element called
foo and of type Bar , so long as
Bar is not an array, primitive or String type.
Bar must have an accessible constructor taking no
arguments.
void addFoo(Bar) is recognised as a method for storing
an element called foo and of type Bar , so
long as Bar is not an array, primitive or String type.
Bar must have an accessible constructor taking no
arguments. This is distinct from the 'addConfigured' idiom in that
the nested element is added to the parent immediately after it is
constructed; in practice this means that addFoo(Bar) should
do little or nothing with its argument besides storing it for later use.
Note that only one method is retained to create/set/addConfigured/add
any element or attribute.
this.bean = bean;
Method[] methods = bean.getMethods();
for (int i = 0; i < methods.length; i++) {
final Method m = methods[i];
final String name = m.getName();
Class returnType = m.getReturnType();
Class[] args = m.getParameterTypes();
// check of add[Configured](Class) pattern
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/project components
if (org.apache.tools.ant.ProjectComponent.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])) {
addText = methods[i];
} else if (name.startsWith("set")
&& java.lang.Void.TYPE.equals(returnType)
&& args.length == 1 && !args[0].isArray()) {
String propName = getPropertyName(name, "set");
if (attributeSetters.get(propName) != null) {
if (java.lang.String.class.equals(args[0])) {
/*
Ignore method m, as there is an overloaded
form of this method that takes in a
non-string argument, which gains higher
priority.
*/
continue;
}
/*
If the argument is not a String or Location,
and if there
is an overloaded form of this method already defined,
we just override that with the new one.
This mechanism does not guarantee any specific order
in which the methods will be selected: so any code
that depends on the order in which "set" methods have
been defined, is not guaranteed to be selected in any
particular order.
*/
}
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) {
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 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()) {
try {
Constructor constructor = null;
try {
constructor = args[0].getConstructor(new Class[] {});
} catch (NoSuchMethodException ex) {
constructor =
args[0].getConstructor(new Class[] {Project.class});
}
String propName = getPropertyName(name, "addConfigured");
nestedTypes.put(propName, args[0]);
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()) {
try {
Constructor constructor = null;
try {
constructor = args[0].getConstructor(new Class[] {});
} catch (NoSuchMethodException ex) {
constructor =
args[0].getConstructor(new Class[] {Project.class});
}
String propName = getPropertyName(name, "add");
if (nestedTypes.get(propName) != null) {
/*
* Ignore this method as there is an addConfigured
* form of this method that has a higher
* priority
*/
continue;
}
nestedTypes.put(propName, args[0]);
nestedCreators.put(propName, new AddNestedCreator(m,
constructor, AddNestedCreator.ADD));
} catch (NoSuchMethodException nse) {
// ignore
}
}
}
|
Methods Summary |
---|
public void | addText(Project project, java.lang.Object element, java.lang.String text)Adds PCDATA to an element, using the element's
void addText(String) method, if it has one. If no
such method is present, a BuildException is thrown if the
given text contains non-whitespace.
if (addText == null) {
text = text.trim();
// Element doesn't handle text content
if (text.length() == 0) {
// Only whitespace - ignore
return;
} else {
// Not whitespace - fail
String msg = project.getElementName(element)
+ " doesn't support nested text data (\""
+ condenseText(text) + "\").";
throw new BuildException(msg);
}
}
try {
addText.invoke(element, new Object[] {text});
} catch (IllegalAccessException ie) {
// impossible as getMethods should only return public methods
throw new BuildException(ie);
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
if (t instanceof BuildException) {
throw (BuildException) t;
}
throw new BuildException(t);
}
| public static void | clearCache()Clears the static cache of on build finished.
HELPERS.clear();
| private java.lang.String | condenseText(java.lang.String text)
if (text.length() <= MAX_REPORT_NESTED_TEXT) {
return text;
}
int ends = (MAX_REPORT_NESTED_TEXT - ELLIPSIS.length()) / 2;
return new StringBuffer(text).replace(ends, text.length() - ends,
ELLIPSIS).toString();
| private org.apache.tools.ant.IntrospectionHelper$NestedCreator | createAddTypeCreator(Project project, java.lang.Object parent, java.lang.String elementName)
if (addTypeMethods.size() == 0) {
return null;
}
ComponentHelper helper = ComponentHelper.getComponentHelper(project);
Object addedObject = null;
Method addMethod = null;
Class clazz = helper.getComponentClass(elementName);
if (clazz == null) {
return null;
}
addMethod = findMatchingMethod(clazz, addTypeMethods);
if (addMethod == null) {
return null;
}
addedObject = helper.createComponent(elementName);
if (addedObject == null) {
return null;
}
Object rObject = addedObject;
if (addedObject instanceof PreSetDef.PreSetDefinition) {
rObject = ((PreSetDef.PreSetDefinition) addedObject).createObject(
project);
}
final Object nestedObject = addedObject;
final Object realObject = rObject;
return new NestedCreator(addMethod) {
Object create(Project project, Object parent, Object ignore)
throws InvocationTargetException, IllegalAccessException {
if (!getMethod().getName().endsWith("Configured")) {
getMethod().invoke(parent, new Object[] {realObject});
}
return nestedObject;
}
Object getRealObject() {
return realObject;
}
void store(Object parent, Object child)
throws InvocationTargetException, IllegalAccessException,
InstantiationException {
if (getMethod().getName().endsWith("Configured")) {
getMethod().invoke(parent, new Object[] {realObject});
}
}
};
| private org.apache.tools.ant.IntrospectionHelper$AttributeSetter | createAttributeSetter(java.lang.reflect.Method m, java.lang.Class arg, java.lang.String attrName)Creates an implementation of AttributeSetter for the given
attribute type. Conversions (where necessary) are automatically
made for the following types:
- String (left as it is)
- Character/char (first character is used)
- Boolean/boolean
({@link Project#toBoolean(String) Project.toBoolean(String)} is used)
- Class (Class.forName is used)
- File (resolved relative to the appropriate project)
- Path (resolve relative to the appropriate project)
- EnumeratedAttribute (uses its own
{@link EnumeratedAttribute#setValue(String) setValue} method)
- Other primitive types (wrapper classes are used with constructors
taking String)
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.
// use wrappers for primitive classes, e.g. int and
// Integer are treated identically
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)
throws InvocationTargetException, IllegalAccessException {
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)
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))}));
}
};
// 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)
throws InvocationTargetException, IllegalAccessException {
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)
throws InvocationTargetException, IllegalAccessException, BuildException {
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)
throws InvocationTargetException, IllegalAccessException {
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)
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);
}
}
};
} else if (reflectedArg.getSuperclass() != null
&& reflectedArg.getSuperclass().getName().equals("java.lang.Enum")) {
return new AttributeSetter(m) {
public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException, BuildException {
try {
m.invoke(parent, new Object[] {
reflectedArg.getMethod("valueOf", new Class[] {String.class}).
invoke(null, new Object[] {value})});
} catch (InvocationTargetException x) {
if (x.getTargetException() instanceof IllegalArgumentException) {
throw new BuildException(
"'" + value + "' is not a permitted value for "
+ reflectedArg.getName());
} else {
throw new BuildException(x.getTargetException());
}
} catch (Exception x) {
throw new BuildException(x);
}
}
};
// 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 {
// First try with Project.
c = reflectedArg.getConstructor(new Class[] {Project.class, String.class});
includeProject = true;
} catch (NoSuchMethodException nme) {
// OK, try without.
try {
c = reflectedArg.getConstructor(new Class[] {String.class});
includeProject = false;
} catch (NoSuchMethodException nme2) {
// Well, no matching constructor.
return null;
}
}
final boolean finalIncludeProject = includeProject;
final Constructor finalConstructor = c;
return new AttributeSetter(m) {
public void set(Project p, Object parent, String value)
throws InvocationTargetException, IllegalAccessException, BuildException {
try {
Object[] args = (finalIncludeProject)
? new Object[] {p, value} : new Object[] {value};
Object attribute = finalConstructor.newInstance(args);
if (p != null) {
p.setProjectReference(attribute);
}
m.invoke(parent, new Object[] {attribute});
} catch (InstantiationException ie) {
throw new BuildException(ie);
}
}
};
}
| public java.lang.Object | createElement(Project project, java.lang.Object parent, java.lang.String elementName)Creates a named nested element. Depending on the results of the
initial introspection, either a method in the given parent instance
or a simple no-arg constructor is used to create an instance of the
specified element type.
NestedCreator nc = getNestedCreator(project, "", parent, elementName, null);
try {
Object nestedElement = nc.create(project, parent, null);
if (project != null) {
project.setProjectReference(nestedElement);
}
return nestedElement;
} 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);
}
| private java.lang.reflect.Method | findMatchingMethod(java.lang.Class paramClass, java.util.List methods)Search the list of methods to find the first method
that has a parameter that accepts the nested element object.
Class matchedClass = null;
Method matchedMethod = null;
for (int i = 0; i < methods.size(); ++i) {
Method method = (Method) methods.get(i);
Class methodClass = method.getParameterTypes()[0];
if (methodClass.isAssignableFrom(paramClass)) {
if (matchedClass == null) {
matchedClass = methodClass;
matchedMethod = method;
} else {
if (!methodClass.isAssignableFrom(matchedClass)) {
throw new BuildException("ambiguous: types "
+ matchedClass.getName() + " and "
+ methodClass.getName() + " match "
+ paramClass.getName());
}
}
}
}
return matchedMethod;
| public java.lang.reflect.Method | getAddTextMethod()Returns the addText method when the introspected
class supports nested text.
if (!supportsCharacters()) {
throw new BuildException("Class " + bean.getName()
+ " doesn't support nested text data.");
}
return addText;
| public java.util.Map | getAttributeMap()Returns a read-only map of attributes supported
by the introspected class.
return (attributeTypes.size() < 1)
? EMPTY_MAP : Collections.unmodifiableMap(attributeTypes);
| public java.lang.reflect.Method | getAttributeMethod(java.lang.String attributeName)Returns the setter method of a named attribute.
Object setter = attributeSetters.get(attributeName);
if (setter == null) {
throw new UnsupportedAttributeException("Class "
+ bean.getName() + " doesn't support the \""
+ attributeName + "\" attribute.", attributeName);
}
return ((AttributeSetter) setter).method;
| public java.lang.Class | getAttributeType(java.lang.String attributeName)Returns the type of a named attribute.
Class at = (Class) attributeTypes.get(attributeName);
if (at == null) {
throw new UnsupportedAttributeException("Class "
+ bean.getName() + " doesn't support the \""
+ attributeName + "\" attribute.", attributeName);
}
return at;
| public java.util.Enumeration | getAttributes()Returns an enumeration of the names of the attributes supported
by the introspected class.
return attributeSetters.keys();
| public org.apache.tools.ant.IntrospectionHelper$Creator | getElementCreator(Project project, java.lang.String parentUri, java.lang.Object parent, java.lang.String elementName, UnknownElement ue)returns an object that creates and stores an object
for an element of a parent.
NestedCreator nc = getNestedCreator(
project, parentUri, parent, elementName, ue);
return new Creator(project, parent, nc);
| public java.lang.reflect.Method | getElementMethod(java.lang.String elementName)Returns the adder or creator method of a named nested element.
Object creator = nestedCreators.get(elementName);
if (creator == null) {
throw new UnsupportedElementException("Class "
+ bean.getName() + " doesn't support the nested \""
+ elementName + "\" element.", elementName);
}
return ((NestedCreator) creator).method;
| protected java.lang.String | getElementName(Project project, java.lang.Object element)Returns a description of the type of the given element in
relation to a given project. This is used for logging purposes
when the element is asked to cope with some data it has no
way of handling.
return project.getElementName(element);
| public java.lang.Class | getElementType(java.lang.String elementName)Returns the type of a named nested element.
Class nt = (Class) nestedTypes.get(elementName);
if (nt == null) {
throw new UnsupportedElementException("Class "
+ bean.getName() + " doesn't support the nested \""
+ elementName + "\" element.", elementName);
}
return nt;
| public java.util.List | getExtensionPoints()Returns a read-only list of extension points supported
by the introspected class.
A task/type or nested element with void methods named add()
or addConfigured() , taking a single class or interface
argument, supports extensions point. This method returns the list of
all these void add[Configured](type) methods.
return (addTypeMethods.size() < 1) ? Collections.EMPTY_LIST
: Collections.unmodifiableList(addTypeMethods);
| public static synchronized org.apache.tools.ant.IntrospectionHelper | getHelper(java.lang.Class c)Returns a helper for the given class, either from the cache
or by creating a new instance.
return getHelper(null, c);
| public static org.apache.tools.ant.IntrospectionHelper | getHelper(Project p, java.lang.Class c)Returns a helper for the given class, either from the cache
or by creating a new instance.
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.
IntrospectionHelper ih = (IntrospectionHelper) HELPERS.get(c.getName());
// If a helper cannot be found, or if the helper is for another
// classloader, create a new IH
if (ih == null || ih.bean != c) {
ih = new IntrospectionHelper(c);
if (p != null) {
// #30162: do *not* cache this if there is no project, as we
// cannot guarantee that the cache will be cleared.
HELPERS.put(c.getName(), ih);
}
}
return ih;
| private org.apache.tools.ant.IntrospectionHelper$NestedCreator | getNestedCreator(Project project, java.lang.String parentUri, java.lang.Object parent, java.lang.String elementName, UnknownElement child)
String uri = ProjectHelper.extractUriFromComponentName(elementName);
String name = ProjectHelper.extractNameFromComponentName(elementName);
if (uri.equals(ProjectHelper.ANT_CORE_URI)) {
uri = "";
}
if (parentUri.equals(ProjectHelper.ANT_CORE_URI)) {
parentUri = "";
}
NestedCreator nc = null;
if (uri.equals(parentUri) || uri.equals("")) {
nc = (NestedCreator) nestedCreators.get(
name.toLowerCase(Locale.US));
}
if (nc == null) {
nc = createAddTypeCreator(project, parent, elementName);
}
if (nc == null && parent instanceof DynamicElementNS) {
DynamicElementNS dc = (DynamicElementNS) parent;
String qName = (child == null ? name : child.getQName());
final Object nestedElement =
dc.createDynamicElement(
(child == null ? "" : child.getNamespace()),
name, qName);
if (nestedElement != null) {
nc = new NestedCreator(null) {
Object create(
Project project, Object parent, Object ignore) {
return nestedElement;
}
};
}
}
if (nc == null && parent instanceof DynamicElement) {
DynamicElement dc = (DynamicElement) parent;
final Object nestedElement =
dc.createDynamicElement(name.toLowerCase(Locale.US));
if (nestedElement != null) {
nc = new NestedCreator(null) {
Object create(
Project project, Object parent, Object ignore) {
return nestedElement;
}
};
}
}
if (nc == null) {
throwNotSupported(project, parent, elementName);
}
return nc;
| public java.util.Map | getNestedElementMap()Returns a read-only map of nested elements supported
by the introspected class.
return (nestedTypes.size() < 1)
? EMPTY_MAP : Collections.unmodifiableMap(nestedTypes);
| public java.util.Enumeration | getNestedElements()Returns an enumeration of the names of the nested elements supported
by the introspected class.
return nestedTypes.keys();
| private java.lang.String | getPropertyName(java.lang.String methodName, java.lang.String prefix)Extracts the name of a property from a method name by subtracting
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
specified prefix - no checking is done in this method.
return methodName.substring(prefix.length()).toLowerCase(Locale.US);
| private void | insertAddTypeMethod(java.lang.reflect.Method method)Inserts an add or addConfigured method into
the addTypeMethods array. The array is
ordered so that the more derived classes
are first.
If both add and addConfigured are present, the addConfigured
will take priority.
Class argClass = method.getParameterTypes()[0];
for (int c = 0; c < addTypeMethods.size(); ++c) {
Method current = (Method) addTypeMethods.get(c);
if (current.getParameterTypes()[0].equals(argClass)) {
if (method.getName().equals("addConfigured")) {
// add configured replaces the add method
addTypeMethods.set(c, method);
}
return; // Already present
}
if (current.getParameterTypes()[0].isAssignableFrom(
argClass)) {
addTypeMethods.add(c, method);
return; // higher derived
}
}
addTypeMethods.add(method);
| public boolean | isContainer()Indicates whether the introspected class is a task container,
supporting arbitrary nested tasks/types.
return TaskContainer.class.isAssignableFrom(bean);
| public boolean | isDynamic()Indicates whether the introspected class is a dynamic one,
supporting arbitrary nested elements and/or attributes.
return DynamicElement.class.isAssignableFrom(bean)
|| DynamicElementNS.class.isAssignableFrom(bean);
| private boolean | isHiddenSetMethod(java.lang.String name, java.lang.Class type)Certain set methods are part of the Ant core interface to tasks and
therefore not to be considered for introspection
if ("setLocation".equals(name)
&& org.apache.tools.ant.Location.class.equals(type)) {
return true;
}
if ("setTaskType".equals(name)
&& java.lang.String.class.equals(type)) {
return true;
}
return false;
| public void | setAttribute(Project p, java.lang.Object element, java.lang.String attributeName, java.lang.String value)Sets the named attribute in the given element, which is part of the
given project.
AttributeSetter as
= (AttributeSetter) attributeSetters.get(
attributeName.toLowerCase(Locale.US));
if (as == null) {
if (element instanceof DynamicAttributeNS) {
DynamicAttributeNS dc = (DynamicAttributeNS) element;
String uriPlusPrefix =
ProjectHelper.extractUriFromComponentName(attributeName);
String uri =
ProjectHelper.extractUriFromComponentName(uriPlusPrefix);
String localName =
ProjectHelper.extractNameFromComponentName(attributeName);
String qName = ("".equals(uri)
? localName : (uri + ":" + localName));
dc.setDynamicAttribute(uri, localName, qName, value);
return;
} else if (element instanceof DynamicAttribute) {
DynamicAttribute dc = (DynamicAttribute) element;
dc.setDynamicAttribute(attributeName.toLowerCase(Locale.US), value);
return;
} else {
if (attributeName.indexOf(':") != -1) {
return; // Ignore attribute from unknown uri's
}
String msg = getElementName(p, element)
+ " doesn't support the \"" + attributeName
+ "\" attribute.";
throw new UnsupportedAttributeException(msg, attributeName);
}
}
try {
as.set(p, element, value);
} catch (IllegalAccessException ie) {
// impossible as getMethods should only return public methods
throw new BuildException(ie);
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
if (t instanceof BuildException) {
throw (BuildException) t;
}
throw new BuildException(t);
}
| public void | storeElement(Project project, java.lang.Object parent, java.lang.Object child, java.lang.String elementName)Stores a named nested element using a storage method determined
by the initial introspection. If no appropriate storage method
is available, this method returns immediately.
if (elementName == null) {
return;
}
NestedCreator ns = (NestedCreator) nestedCreators.get(
elementName.toLowerCase(Locale.US));
if (ns == null) {
return;
}
try {
ns.store(parent, 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);
}
| public boolean | supportsCharacters()Returns whether or not the introspected class supports PCDATA.
return addText != null;
| public boolean | supportsNestedElement(java.lang.String elementName)Indicates if this element supports a nested element of the
given name.
return nestedCreators.containsKey(elementName.toLowerCase(Locale.US))
|| isDynamic()
|| addTypeMethods.size() != 0;
| public boolean | supportsNestedElement(java.lang.String parentUri, java.lang.String elementName)Indicate if this element supports a nested element of the
given name.
if (parentUri.equals(ProjectHelper.ANT_CORE_URI)) {
parentUri = "";
}
String uri = ProjectHelper.extractUriFromComponentName(elementName);
if (uri.equals(ProjectHelper.ANT_CORE_URI)) {
uri = "";
}
String name = ProjectHelper.extractNameFromComponentName(elementName);
return (
nestedCreators.containsKey(name.toLowerCase(Locale.US))
&& (uri.equals(parentUri) || "".equals(uri)))
|| isDynamic() || addTypeMethods.size() != 0;
| public void | throwNotSupported(Project project, java.lang.Object parent, java.lang.String elementName)Utility method to throw a NotSupported exception
String msg = project.getElementName(parent)
+ " doesn't support the nested \"" + elementName + "\" element.";
throw new UnsupportedElementException(msg, elementName);
|
|