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 + -
显示快捷键?