📄 introspectionhelper.java
字号:
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; } if (element instanceof DynamicAttribute) { DynamicAttribute dc = (DynamicAttribute) element; dc.setDynamicAttribute(attributeName.toLowerCase(Locale.US), value); return; } 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) { throw extractBuildException(ite); } } /** * Adds PCDATA to an element, using the element's * <code>void addText(String)</code> method, if it has one. If no * such method is present, a BuildException is thrown if the * given text contains non-whitespace. * * @param project The project which the element is part of. * Must not be <code>null</code>. * @param element The element to add the text to. * Must not be <code>null</code>. * @param text The text to add. * Must not be <code>null</code>. * * @exception BuildException if non-whitespace text is provided and no * method is available to handle it, or if * the handling method fails. */ public void addText(Project project, Object element, String text) throws BuildException { if (addText == null) { text = text.trim(); // Element doesn't handle text content if (text.length() == 0) { // Only whitespace - ignore return; } // Not whitespace - fail throw new BuildException(project.getElementName(element) + " doesn't support nested text data (\"" + condenseText(text) + "\")."); } 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) { throw extractBuildException(ite); } } /** * Utility method to throw a NotSupported exception * * @param project the Project instance. * @param parent the object which doesn't support a requested element * @param elementName the name of the Element which is trying to be created. */ public void throwNotSupported(Project project, Object parent, String elementName) { String msg = project.getElementName(parent) + " doesn't support the nested \"" + elementName + "\" element."; throw new UnsupportedElementException(msg, elementName); } /** * Get the specific NestedCreator for a given project/parent/element combination * @param project ant project * @param parentUri URI of the parent. * @param parent the parent class * @param elementName element to work with. This can contain * a URI,localname tuple of of the form uri:localname * @param child the bit of XML to work with * @return a nested creator that can handle the child elements. * @throws BuildException if the parent does not support child elements of that name */ private NestedCreator getNestedCreator( Project project, String parentUri, Object parent, String elementName, UnknownElement child) throws BuildException { 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.length() == 0) { 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; } /** * 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. * * @param project Project to which the parent object belongs. * Must not be <code>null</code>. If the resulting * object is an instance of ProjectComponent, its * Project reference is set to this parameter value. * @param parent Parent object used to create the instance. * Must not be <code>null</code>. * @param elementName Name of the element to create an instance of. * Must not be <code>null</code>. * * @return an instance of the specified element type * @deprecated since 1.6.x. * This is not a namespace aware method. * * @exception BuildException if no method is available to create the * element instance, or if the creating method fails. */ public Object createElement(Project project, Object parent, String elementName) throws BuildException { 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) { throw extractBuildException(ite); } } /** * returns an object that creates and stores an object * for an element of a parent. * * @param project Project to which the parent object belongs. * @param parentUri The namespace uri of the parent object. * @param parent Parent object used to create the creator object to * create and store and instance of a subelement. * @param elementName Name of the element to create an instance of. * @param ue The unknown element associated with the element. * @return a creator object to create and store the element instance. */ public Creator getElementCreator( Project project, String parentUri, Object parent, String elementName, UnknownElement ue) { NestedCreator nc = getNestedCreator(project, parentUri, parent, elementName, ue); return new Creator(project, parent, nc); } /** * Indicates whether the introspected class is a dynamic one, * supporting arbitrary nested elements and/or attributes. * * @return <code>true<code> if the introspected class is dynamic; * <code>false<code> otherwise. * @since Ant 1.6.3 * * @see DynamicElement * @see DynamicElementNS */ public boolean isDynamic() { return DynamicElement.class.isAssignableFrom(bean) || DynamicElementNS.class.isAssignableFrom(bean); } /** * Indicates whether the introspected class is a task container, * supporting arbitrary nested tasks/types. * * @return <code>true<code> if the introspected class is a container; * <code>false<code> otherwise. * @since Ant 1.6.3 * * @see TaskContainer */ public boolean isContainer() { return TaskContainer.class.isAssignableFrom(bean); } /** * Indicates if this element supports a nested element of the * given name. * * @param elementName the name of the nested element being checked * * @return true if the given nested element is supported */ public boolean supportsNestedElement(String elementName) { return supportsNestedElement("", elementName); } /** * Indicate if this element supports a nested element of the * given name. * * @param parentUri the uri of the parent * @param elementName the name of the nested element being checked * * @return true if the given nested element is supported */ public boolean supportsNestedElement(String parentUri, String elementName) { if (isDynamic() || addTypeMethods.size() > 0) { return true; } String name = ProjectHelper.extractNameFromComponentName(elementName); if (!nestedCreators.containsKey(name.toLowerCase(Locale.US))) { return false; } String uri = ProjectHelper.extractUriFromComponentName(elementName); if (uri.equals(ProjectHelper.ANT_CORE_URI)) { uri = ""; } if ("".equals(uri)) { return true; } if (parentUri.equals(ProjectHelper.ANT_CORE_URI)) { parentUri = ""; } return uri.equals(parentUri); } /** * 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. * * @param project Ignored in this implementation. * May be <code>null</code>. * * @param parent Parent instance to store the child in. * Must not be <code>null</code>. * * @param child Child instance to store in the parent. * Should not be <code>null</code>. * * @param elementName Name of the child element to store. * May be <code>null</code>, in which case * this method returns immediately. * * @exception BuildException if the storage method fails. */ public void storeElement(Project project, Object parent, Object child, String elementName) throws BuildException { 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) { throw extractBuildException(ite); } } /** * Helper method to extract the inner fault from an {@link InvocationTargetException}, and turn * it into a BuildException. If it is already a BuildException, it is type cast and returned; if * not a new BuildException is created containing the child as nested text. * @param ite * @return the nested exception */ private static BuildException extractBuildException(InvocationTargetException ite) { Throwable t = ite.getTargetException(); if (t instanceof BuildException) { return (BuildException) t; } return new BuildException(t); } /** * Returns the type of a named nested element. * * @param elementName The name of the element to find the type of. * Must not be <code>null</code>. * * @return the type of the nested element with the specified name. * This will never be <code>null</code>. * * @exception BuildException if the introspected class does not * support the named nested element. */ public Class getElementType(String elementName) throws BuildException { 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; } /** * Returns the type of a named attribute. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -