classfile.java

来自「JiBX是一个为Java提供的XML数据绑定框架。它可以和现存的类一起运行」· Java 代码 · 共 1,891 行 · 第 1/5 页

JAVA
1,891
字号
                }            }                    }        return null;    }    /**     * Get all binding methods currently defined in class. Binding methods are     * generally identified by a supplied prefix, but additional methods     * can be specified the the combination of exact name and signature. This     * is a little kludgy, but necessary to handle the "marshal" method added     * to mapped classes.     *     * @param prefix identifying prefix for binding methods     * @param matches pairs of method name and signature to be matched as     * exceptions to the prefix matching     * @return existing binding methods     */    public ExistingMethod[] getBindingMethods(String prefix, String[] matches) {                // return empty array if newly created class or unloadable class        if (m_curClass == null) {            return EMPTY_METHOD_ARRAY;        }        // check for binding methods defined in class        Method[] methods = getMethods();        int count = 0;        for (int i = 0; i < methods.length; i++) {            Method method = methods[i];            String name = method.getName();            if (name.startsWith(prefix)) {                count++;            } else {                String sig = method.getSignature();                for (int j = 0; j < matches.length; j += 2) {                    if (name.equals(matches[j]) && sig.equals(matches[j+1])) {                        count++;                        break;                    }                }            }        }                // generate array of methods found        if (count == 0) {            return EMPTY_METHOD_ARRAY;        } else {            ExistingMethod[] exists = new ExistingMethod[count];            int fill = 0;            for (int i = 0; i < methods.length; i++) {                Method method = methods[i];                String name = method.getName();                boolean match = name.startsWith(prefix);                if (!match) {                    String sig = method.getSignature();                    for (int j = 0; j < matches.length; j += 2) {                        if (name.equals(matches[j]) &&                            sig.equals(matches[j+1])) {                            match = true;                            break;                        }                    }                }                if (match) {                    ClassItem item = (ClassItem)m_itemMap.get(method);                    if (item == null) {                        item = new ClassItem(name, this, method);                        m_itemMap.put(method, item);                    }                    exists[fill++] = new ExistingMethod(method, item, this);                }            }            return exists;        }    }    /**     * Check accessible method. Check if a field or method in another class is     * accessible from within this class.     *     * @param item field or method information     * @return <code>true</code> if accessible, <code>false</code> if not     */    public boolean isAccessible(ClassItem item) {        if (item.getClassFile() == this) {            return true;        } else {            int access = item.getAccessFlags();            if ((access & Constants.ACC_PUBLIC) != 0) {                return true;            } else if ((access & Constants.ACC_PRIVATE) != 0) {                return false;            } else if (getPackage().equals(item.getClassFile().getPackage())) {                return true;            } else if ((access & Constants.ACC_PROTECTED) != 0) {                ClassFile target = item.getClassFile();                ClassFile ancestor = this;                while ((ancestor = ancestor.getSuperFile()) != null) {                    if (ancestor == target) {                        return true;                    }                }                return false;            } else {                return false;            }        }    }    /**     * Get generator for modifying class.     *     * @return generator for class     * @throws JiBXException if class not modifiable     */    private ClassGen getClassGen() throws JiBXException {        if (m_genClass == null) {            if (m_isWritable) {                m_genClass = new ClassGen(m_curClass);                m_genPool = m_genClass.getConstantPool();                m_instBuilder = new InstructionBuilder(m_genClass, m_genPool);                m_isHashCurrent = false;            } else {                throw new JiBXException("Cannot modify class " + m_name);            }        }        return m_genClass;    }    /**     * Get constant pool generator for modifying class.     *     * @return constant pool generator for class     * @throws JiBXException if class not modifiable     */    public ConstantPoolGen getConstPoolGen() throws JiBXException {        if (m_genPool == null) {            getClassGen();        }        return m_genPool;    }    /**     * Get instruction builder for modifying class.     *     * @return instruction builder for class     * @throws JiBXException if class not modifiable     */    public InstructionBuilder getInstructionBuilder() throws JiBXException {        if (m_instBuilder == null) {            getClassGen();        }        return m_instBuilder;    }    /**     * Add method to class.     *      * @param method method to be added     * @return added method information     * @throws JiBXException on error in adding method     */    public ClassItem addMethod(Method method) throws JiBXException {        getClassGen().addMethod(method);        setModified();        String mname = method.getName();        if (m_suffixMap != null && isSuffixName(mname)) {            m_suffixMap.put(mname, method);         }        return new ClassItem(mname, this, method);    }    /**     * Remove method from class.     *      * @param method method to be removed     * @throws JiBXException on error in removing method     */    public void removeMethod(Method method) throws JiBXException {        getClassGen().removeMethod(method);        setModified();        String mname = method.getName();        if (m_suffixMap != null && isSuffixName(mname)) {            m_suffixMap.remove(mname);         }    }    /**     * Add field to class with initial <code>String</code> value. If a field     * with the same name already exists, it is overwritten.     *     * @param type fully qualified class name of field type     * @param name field name     * @param access access flags for field     * @param init initial value for field     * @return field information     * @throws JiBXException if unable to add field     */    public ClassItem addField(String type, String name, int access, String init)        throws JiBXException {        deleteField(name);        FieldGen fgen = new FieldGen(access,            Type.getType(Utility.getSignature(type)), name, getConstPoolGen());        fgen.setInitValue(init);        Field field = fgen.getField();        getClassGen().addField(field);        m_isModified = true;        m_isHashCurrent = false;        return new ClassItem(name, this, field);    }    /**     * Update class field with initial <code>String</code> value. If the field     * already exists with the same characteristics it is left unchanged;     * otherwise any existing field with the same name is overwritten.     *     * @param type fully qualified class name of field type     * @param name field name     * @param access access flags for field     * @param init initial value for field     * @return field information     * @throws JiBXException if unable to add field     */    public ClassItem updateField(String type, String name, int access,        String init) throws JiBXException {                // first check for match with existing field        Field[] fields = m_curClass.getFields();        for (int i = 0; i < fields.length; i++) {            Field field = fields[i];            if (field.getName().equals(name) &&                field.getAccessFlags() == access) {                String sig = field.getSignature();                if (type.equals(Utility.signatureToString(sig, false))) {                    ConstantValue cval = field.getConstantValue();                    if (cval != null) {                        int index = cval.getConstantValueIndex();                        ConstantPool cp = m_curClass.getConstantPool();                        Constant cnst = cp.getConstant(index);                        if (cnst instanceof ConstantString) {                            Object value = ((ConstantString)cnst).                                getConstantValue(cp);                            if (init.equals(value)) {                                return new ClassItem(name,this, field);                            }                        }                    }                }            }        }                // no exact match, so replace any existing field with same name        deleteField(name);        FieldGen fgen = new FieldGen(access,            Type.getType(Utility.getSignature(type)), name, getConstPoolGen());        fgen.setInitValue(init);        Field field = fgen.getField();        getClassGen().addField(field);        m_isModified = true;        m_isHashCurrent = false;        return new ClassItem(name, this, field);    }    /**     * Add field to class without initialization. If a field with the same name     * already exists, it is overwritten.     *     * @param type fully qualified class name of field type     * @param name field name     * @param access access flags for field     * @return field information     * @throws JiBXException if unable to add field     */    public ClassItem addField(String type, String name, int access)        throws JiBXException {        deleteField(name);        FieldGen fgen = new FieldGen(access,            Type.getType(Utility.getSignature(type)), name, getConstPoolGen());        Field field = fgen.getField();        getClassGen().addField(field);        m_isModified = true;        m_isHashCurrent = false;        return new ClassItem(name, this, field);    }    /**     * Add private field to class without initialization. If a field     * with the same name already exists, it is overwritten.     *     * @param type fully qualified class name of field type     * @param name field name     * @return field information     * @throws JiBXException if unable to add field     */    public ClassItem addPrivateField(String type, String name)        throws JiBXException {        return addField(type, name, PRIVATEFIELD_ACCESS);    }    /**     * Add default constructor to a class. Just calls the default constructor     * for the parent class (which must exist).     *     * @return constructor information     * @throws JiBXException if unable to add constructor     */    public ClassItem addDefaultConstructor() throws JiBXException {        if (m_defaultConstructor == null) {                        // add the public constructor method            ExceptionMethodBuilder mb = new ExceptionMethodBuilder("<init>",                Type.VOID, new Type[0], this, Constants.ACC_PUBLIC);                    // call the superclass constructor            mb.appendLoadLocal(0);            mb.appendCallInit(m_superClass.getName(), "()V");                        // finish with return            mb.appendReturn();            mb.codeComplete(false);            m_defaultConstructor = mb.addMethod();                    }        return m_defaultConstructor;    }    /**     * Check if a method name matches the pattern for a generated unique suffix.     *     * @param name method name to be checked     * @return <code>true</code> if name matches suffix pattern,     * <code>false</code> if not     */    private static boolean isSuffixName(String name) {        int last = name.length() - 1;        for (int i = last; i > 0; i--) {            char chr = name.charAt(i);            if (chr == '_') {                return i < last;            } else if (!Character.isDigit(chr)) {                break;            }        }        return false;    }    /**     * Make method name unique with generated suffix. The suffixed method name     * is tracked so that it will not be used again.     *     * @param name base name before suffix is appended     * @return name with unique suffix appended     */    public String makeUniqueMethodName(String name) {                // check if map creation is needed        if (m_suffixMap == null) {            m_suffixMap = new HashMap();            if (m_curClass != null) {                Method[] methods = getMethods();                for (int i = 0; i < methods.length; i++) {                    Method method = methods[i];                    String mname = method.getName();

⌨️ 快捷键说明

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