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

📄 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 element The element to describe. Must not be <code>null</code>.     *     * @return a description of the element type     */    private String getElementName(Project project, Object element) {        return project.getElementName(element);    }    /**     * 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.     *     * @param methodName The name of the method in question. Must not be <code>null</code>.     * @param prefix     The prefix to remove. Must not be <code>null</code>.     *     * @return the lower-cased method name with the prefix removed.     */    private static String getPropertyName(String methodName, String prefix) {        return methodName.substring(prefix.length()).toLowerCase(Locale.US);    }    /**     * creator - allows use of create/store external     * to IntrospectionHelper.     * The class is final as it has a private constructor.     */    public static final class Creator {        private NestedCreator nestedCreator;        private Object parent;        private Project project;        private Object nestedObject;        private String polyType;        /**         * Creates a new Creator instance.         * This object is given to the UnknownElement to create         * objects for sub-elements. UnknownElement calls         * create to create an object, the object then gets         * configured and then UnknownElement calls store.         * SetPolyType may be used to override the type used         * to create the object with. SetPolyType gets called before create.         *         * @param project the current project         * @param parent  the parent object to create the object in         * @param nestedCreator the nested creator object to use         */        private Creator(Project project, Object parent, NestedCreator nestedCreator) {            this.project = project;            this.parent = parent;            this.nestedCreator = nestedCreator;        }        /**         * Used to override the class used to create the object.         *         * @param polyType a ant component type name         */        public void setPolyType(String polyType) {            this.polyType = polyType;        }        /**         * Create an object using this creator, which is determined by introspection.         *         * @return the created object         */        public Object create() {            if (polyType != null) {                if (!nestedCreator.isPolyMorphic()) {                    throw new BuildException(                            "Not allowed to use the polymorphic form for this element");                }                ComponentHelper helper = ComponentHelper.getComponentHelper(project);                nestedObject = helper.createComponent(polyType);                if (nestedObject == null) {                    throw new BuildException("Unable to create object of type " + polyType);                }            }            try {                nestedObject = nestedCreator.create(project, parent, nestedObject);                if (project != null) {                    project.setProjectReference(nestedObject);                }                return nestedObject;            } catch (IllegalAccessException ex) {                throw new BuildException(ex);            } catch (InstantiationException ex) {                throw new BuildException(ex);            } catch (IllegalArgumentException ex) {                if (polyType == null) {                    throw ex;                }                throw new BuildException("Invalid type used " + polyType);            } catch (InvocationTargetException ex) {                throw extractBuildException(ex);            }        }        /**         * @return the real object (used currently only for presetdef).         */        public Object getRealObject() {            return nestedCreator.getRealObject();        }        /**         * Stores the nested element object using a storage method determined by introspection.         *         */        public void store() {            try {                nestedCreator.store(parent, nestedObject);            } catch (IllegalAccessException ex) {                throw new BuildException(ex);            } catch (InstantiationException ex) {                throw new BuildException(ex);            } catch (IllegalArgumentException ex) {                if (polyType == null) {                    throw ex;                }                throw new BuildException("Invalid type used " + polyType);            } catch (InvocationTargetException ex) {                throw extractBuildException(ex);            }        }    }    /**     * Internal interface used to create nested elements. Not documented     * in detail for reasons of source code readability.     */    private abstract static class NestedCreator {        private Method method; // the method called to add/create the nested element        protected NestedCreator(Method m) {            method = m;        }        Method getMethod() {            return method;        }        boolean isPolyMorphic() {            return false;        }        Object getRealObject() {            return null;        }        abstract Object create(Project project, Object parent, Object child)                throws InvocationTargetException, IllegalAccessException, InstantiationException;        void store(Object parent, Object child)                 throws InvocationTargetException, IllegalAccessException, InstantiationException {            // DO NOTHING        }    }    private static class CreateNestedCreator extends NestedCreator {        CreateNestedCreator(Method m) {            super(m);        }        Object create(Project project, Object parent, Object ignore)                throws InvocationTargetException, IllegalAccessException {            return getMethod().invoke(parent, new Object[] {});        }    }    /** Version to use for addXXX and addConfiguredXXX */    private static class AddNestedCreator extends NestedCreator {        static final int ADD = 1;        static final int ADD_CONFIGURED = 2;        private Constructor constructor;        private int behavior; // ADD or ADD_CONFIGURED        AddNestedCreator(Method m, Constructor c, int behavior) {            super(m);            this.constructor = c;            this.behavior = behavior;        }        boolean isPolyMorphic() {            return true;        }        Object create(Project project, Object parent, Object child)                throws InvocationTargetException, IllegalAccessException, InstantiationException {            if (child == null) {                child = constructor.newInstance(                        constructor.getParameterTypes().length == 0                                ? new Object[] {} : new Object[] {project});            }            if (child instanceof PreSetDef.PreSetDefinition) {                child = ((PreSetDef.PreSetDefinition) child).createObject(project);            }            if (behavior == ADD) {                istore(parent, child);            }            return child;        }        void store(Object parent, Object child)                throws InvocationTargetException, IllegalAccessException, InstantiationException {            if (behavior == ADD_CONFIGURED) {                istore(parent, child);            }        }        private void istore(Object parent, Object child)                throws InvocationTargetException, IllegalAccessException, InstantiationException {            getMethod().invoke(parent, new Object[] {child});        }    }    /**     * Internal interface used to setting element attributes. Not documented     * in detail for reasons of source code readability.     */    private abstract static class AttributeSetter {        private Method method; // the method called to set the attribute        protected AttributeSetter(Method m) {            method = m;        }        abstract void set(Project p, Object parent, String value)                throws InvocationTargetException, IllegalAccessException, BuildException;    }    /**     * Clears the static cache of on build finished.     */    public static void clearCache() {        HELPERS.clear();    }    /**     * Create a NestedCreator for the given element.     * @param project owning project     * @param parent Parent object used to create the instance.     * @param elementName name of the element     * @return a nested creator, or null if there is no component of the given name, or it     *        has no matching add type methods     * @throws BuildException     */    private NestedCreator createAddTypeCreator(            Project project, Object parent, String elementName) throws BuildException {        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});                }            }        };    }    /**     * 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.     * @param method the <code>Method</code> to insert.     */    private void insertAddTypeMethod(Method method) {        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);    }    /**     * Search the list of methods to find the first method     * that has a parameter that accepts the nested element object.     * @param paramClass the <code>Class</code> type to search for.     * @param methods the <code>List</code> of methods to search.     * @return a matching <code>Method</code>; null if none found.     */    private Method findMatchingMethod(Class paramClass, List methods) {        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;    }    private String condenseText(final 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();    }}

⌨️ 快捷键说明

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