⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 introspectionhelper.java

📁 Use the links below to download a source distribution of Ant from one of our mirrors. It is good pra
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
     * @param attributeName The name of the attribute to find the type of.     *                      Must not be <code>null</code>.     *     * @return the type of the attribute with the specified name.     *         This will never be <code>null</code>.     *     * @exception BuildException if the introspected class does not     *                           support the named attribute.     */    public Class getAttributeType(String attributeName) throws BuildException {        Class at = (Class) attributeTypes.get(attributeName);        if (at == null) {            throw new UnsupportedAttributeException("Class "                    + bean.getName() + " doesn't support the \""                    + attributeName + "\" attribute.", attributeName);        }        return at;    }    /**     * Returns the addText method when the introspected     * class supports nested text.     *     * @return the method on this introspected class that adds nested text.     *         Cannot be <code>null</code>.     * @throws BuildException if the introspected class does not     *         support the nested text.     * @since Ant 1.6.3     */    public Method getAddTextMethod() throws BuildException {        if (!supportsCharacters()) {            throw new BuildException("Class " + bean.getName()                    + " doesn't support nested text data.");        }        return addText;    }    /**     * Returns the adder or creator method of a named nested element.     *     * @param  elementName The name of the attribute to find the setter     *         method of. Must not be <code>null</code>.     * @return the method on this introspected class that adds or creates this     *         nested element. Can be <code>null</code> when the introspected     *         class is a dynamic configurator!     * @throws BuildException if the introspected class does not     *         support the named nested element.     * @since Ant 1.6.3     */    public Method getElementMethod(String elementName) throws BuildException {        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;    }    /**     * Returns the setter method of a named attribute.     *     * @param  attributeName The name of the attribute to find the setter     *         method of. Must not be <code>null</code>.     * @return the method on this introspected class that sets this attribute.     *         This will never be <code>null</code>.     * @throws BuildException if the introspected class does not     *         support the named attribute.     * @since Ant 1.6.3     */    public Method getAttributeMethod(String attributeName) throws BuildException {        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;    }    /**     * Returns whether or not the introspected class supports PCDATA.     *     * @return whether or not the introspected class supports PCDATA.     */    public boolean supportsCharacters() {        return addText != null;    }    /**     * Returns an enumeration of the names of the attributes supported by the introspected class.     *     * @return an enumeration of the names of the attributes supported by the introspected class.     * @see #getAttributeMap     */    public Enumeration getAttributes() {        return attributeSetters.keys();    }    /**     * Returns a read-only map of attributes supported by the introspected class.     *     * @return an attribute name to attribute <code>Class</code>     *         unmodifiable map. Can be empty, but never <code>null</code>.     * @since Ant 1.6.3     */    public Map getAttributeMap() {        return attributeTypes.isEmpty()            ? Collections.EMPTY_MAP : Collections.unmodifiableMap(attributeTypes);    }    /**     * Returns an enumeration of the names of the nested elements supported     * by the introspected class.     *     * @return an enumeration of the names of the nested elements supported     *         by the introspected class.     * @see #getNestedElementMap     */    public Enumeration getNestedElements() {        return nestedTypes.keys();    }    /**     * Returns a read-only map of nested elements supported     * by the introspected class.     *     * @return a nested-element name to nested-element <code>Class</code>     *         unmodifiable map. Can be empty, but never <code>null</code>.     * @since Ant 1.6.3     */    public Map getNestedElementMap() {        return nestedTypes.isEmpty()            ? Collections.EMPTY_MAP : Collections.unmodifiableMap(nestedTypes);    }    /**     * Returns a read-only list of extension points supported     * by the introspected class.     * <p>     * A task/type or nested element with void methods named <code>add()<code>     * or <code>addConfigured()</code>, taking a single class or interface     * argument, supports extensions point. This method returns the list of     * all these <em>void add[Configured](type)</em> methods.     *     * @return a list of void, single argument add() or addConfigured()     *         <code>Method<code>s of all supported extension points.     *         These methods are sorted such that if the argument type of a     *         method derives from another type also an argument of a method     *         of this list, the method with the most derived argument will     *         always appear first. Can be empty, but never <code>null</code>.     * @since Ant 1.6.3     */    public List getExtensionPoints() {        return addTypeMethods.isEmpty()                ? Collections.EMPTY_LIST : Collections.unmodifiableList(addTypeMethods);    }    /**     * Creates an implementation of AttributeSetter for the given     * attribute type. Conversions (where necessary) are automatically     * made for the following types:     * <ul>     * <li>String (left as it is)     * <li>Character/char (first character is used)     * <li>Boolean/boolean     * ({@link Project#toBoolean(String) Project.toBoolean(String)} is used)     * <li>Class (Class.forName is used)     * <li>File (resolved relative to the appropriate project)     * <li>Path (resolve relative to the appropriate project)     * <li>EnumeratedAttribute (uses its own     * {@link EnumeratedAttribute#setValue(String) setValue} method)     * <li>Other primitive types (wrapper classes are used with constructors     * taking String)     * </ul>     *     * 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.     *     * @param m The method to invoke on the bean when the setter is invoked.     *          Must not be <code>null</code>.     * @param arg The type of the single argument of the bean's method.     *            Must not be <code>null</code>.     * @param attrName the name of the attribute for which the setter is being     *                 created.     *     * @return an appropriate AttributeSetter instance, or <code>null</code>     *         if no appropriate conversion is available.     */    private AttributeSetter createAttributeSetter(final Method m,                                                  Class arg,                                                  final String attrName) {        // 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        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        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        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        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        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);                    }                }            };        }        Class enumClass = null;        try {            enumClass = Class.forName("java.lang.Enum");        } catch (ClassNotFoundException e) {            //ignore        }        if (enumClass != null && enumClass.isAssignableFrom(reflectedArg)) {            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) {                        //there is specific logic here for the value being out of the allowed                        //set of enumerations.                        if (x.getTargetException() instanceof IllegalArgumentException) {                            throw new BuildException("'" + value + "' is not a permitted value for "                                    + reflectedArg.getName());                        }                        //only if the exception is not an IllegalArgument do we request the                        //BuildException via extractBuildException():                        throw extractBuildException(x);                    } catch (Exception x) {                        //any other failure of invoke() to work.                        throw new BuildException(x);                    }                }            };        }        if (java.lang.Long.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[] {                                new Long(StringUtils.parseHumanSizes(value)) });                    } catch (InvocationTargetException e) {                        throw e;                    } catch (IllegalAccessException e) {                        throw e;                    } catch (Exception e) {                        throw new BuildException(e);                    }                }            };        }        // 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, boolean, and long.        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);                }            }        };    }    /**     * 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.     *     * @param project The project the element is defined in. Must not be <code>null</code>.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -