📄 mappingdefinition.java
字号:
return m_extensions != null && m_extensions.size() > 0; } public void addExtension(MappingDefinition mdef) throws JiBXException { if (m_extensions == null) { m_extensions = new ArrayList(); } if (!m_extensions.contains(mdef)) { m_extensions.add(mdef); } ClassFile cf = mdef.getBoundClass().getClassFile(); if (!cf.isSuperclass(m_referenceType) && !cf.isImplements(m_referenceType)) { m_referenceType = "java.lang.Object"; } } public IComponent buildRef(IContainer parent, IContextObj objc, String type, PropertyDefinition prop) throws JiBXException { if (prop.isThis()) { // directly incorporate base mapping definition return new BaseMappingWrapper(m_thisBinding); } else if (m_isAbstract && m_extensions == null) { // create reference to use mapping definition directly ComponentProperty comp = new ComponentProperty(prop, m_component, false); if (!hasAttribute() && !hasContent()) { comp.setForceUnmarshal(true); } return comp; } else { // create link to mapping definition DirectObject dobj = new DirectObject(m_container, null, m_class.getClassFile(), m_isAbstract || m_extensions != null, m_marshaller, m_unmarshaller, getIndex(), null); return new DirectProperty(prop, dobj); } } public ArrayList getNamespaces() { return m_defContext.getNamespaces(); } /** * Add abstract marshaller interface to handler class. This adds the * interface and generates the {@link * org.jibx.runtime.IAbstractMarshaller#baseMarshal(Object, * org.jibx.runtime.IMarshallingContext)} method responsible for passing * handling on to the appropriate extension class. * * @param cf hanlder class * @throws JiBXException */ private void generateAbstractMarshaller(ClassFile cf) throws JiBXException { // build the implementation method ContextMethodBuilder mb = new ContextMethodBuilder(BASEMARSHAL_METHODNAME, Type.VOID, MARSHAL_METHOD_ARGS, cf, Constants.ACC_PUBLIC|Constants.ACC_FINAL, 1, "java.lang.Object", 2, MARSHALCONTEXT_INTERFACE); mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS); // TODO: optionally check for null value on object mb.loadContext(); mb.loadObject(IMARSHALLABLE_INTERFACE); mb.appendCallInterface(GETINDEX_METHOD, GETINDEX_SIGNATURE); mb.loadObject(); mb.appendCallVirtual("java.lang.Object.getClass", "()Ljava/lang/Class;"); mb.appendCallVirtual("java.lang.Class.getName", "()Ljava/lang/String;"); mb.appendCallInterface(GETMARSHALLER_METHOD, GETMARSHALLER_SIGNATURE); mb.appendDUP(); mb.appendLoadConstant(getIndex()); mb.appendCallInterface(CHECKEXTENDS_METHOD, CHECKEXTENDS_SIGNATURE); BranchWrapper ifvalid = mb.appendIFNE(this); // generate and throw exception describing the problem mb.appendCreateNew("java.lang.StringBuffer"); mb.appendDUP(); mb.appendLoadConstant("Mapping for type "); mb.appendCallInit("java.lang.StringBuffer", "(Ljava/lang/String;)V"); mb.appendDUP(); mb.loadObject(); mb.appendCallVirtual("java.lang.Object.getClass", "()Ljava/lang/Class;"); mb.appendCallVirtual("java.lang.Class.getName", "()Ljava/lang/String;"); mb.appendCallVirtual("java.lang.StringBuffer.append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); mb.appendDUP(); mb.appendLoadConstant(" must extend abstract mapping for " + "type " + m_class.getClassName()); mb.appendCallVirtual("java.lang.StringBuffer.append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); mb.appendCallVirtual("java.lang.StringBuffer.toString", "()Ljava/lang/String;"); mb.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS); mb.appendDUP_X1(); mb.appendSWAP(); mb.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS, MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1); mb.appendThrow(); // for valid extension mapping, just call the marshaller mb.targetNext(ifvalid); mb.loadObject(); mb.loadContext(); mb.appendCallInterface(MARSHALLERMARSHAL_METHOD, MARSHALLERMARSHAL_SIGNATURE); mb.appendReturn(); mb.codeComplete(false); mb.addMethod(); // add extended interface to constructed class cf.addInterface(ABSTRACTMARSHALLER_INTERFACE); } /** * Generate the {@link org.jibx.runtime.IMarshaller#isExtension(int)} * method to check if this mapping is extending a particular abstract * mapping. * * @param cf * @param hasname * @throws JiBXException */ private void generateIfExtendingCheck(ClassFile cf, boolean hasname) throws JiBXException { // build the method ExceptionMethodBuilder xb = new ExceptionMethodBuilder (CHECKEXTENDS_METHODNAME, CHECKEXTENDS_SIGNATURE, cf, Constants.ACC_PUBLIC|Constants.ACC_FINAL); xb.appendLoadLocal(1); xb.appendLoadConstant(getIndex()); xb.appendISUB(); ArrayList ifeqs = new ArrayList(); ifeqs.add(xb.appendIFEQ(this)); IMapping base = m_baseMapping; while (base != null) { xb.appendLoadLocal(1); xb.appendLoadConstant(base.getIndex()); xb.appendISUB(); ifeqs.add(xb.appendIFEQ(this)); if (base instanceof MappingDefinition) { base = ((MappingDefinition)base).m_baseMapping; } else { break; } } xb.appendICONST_0(); xb.appendReturn("int"); for (int i = 0; i < ifeqs.size(); i++) { xb.targetNext((BranchWrapper)ifeqs.get(i)); } xb.appendICONST_1(); xb.appendReturn("int"); xb.codeComplete(false); xb.addMethod(); } /** * Generate the {@link org.jibx.runtime.IUnmarshaller#unmarshal(Object, * org.jibx.runtime.IUnmarshallingContext)} method implementation. * * @param cf class to receive method * @param hasattr attribute definition present flag * @param hascont content definition present flag * @param hasname element name defined by this mapping flag * @throws JiBXException */ private void generateUnmarshalImplementation(ClassFile cf, boolean hasattr, boolean hascont, boolean hasname) throws JiBXException { // build the unmarshal method for item; this just generates code // to unmarshal attributes and content, first creating an // instance of the class if one was not passed in, then // returning the unmarshalled instance as the value of the call String type = m_class.getClassName(); ContextMethodBuilder mb = new ContextMethodBuilder(UNMARSHAL_METHODNAME, Type.OBJECT, UNMARSHAL_METHOD_ARGS, cf, Constants.ACC_PUBLIC|Constants.ACC_FINAL, 1, type, 2, UNMARSHALCONTEXT_INTERFACE); mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS); // first part of generated code just checks if an object has // been supplied; if it has, this can just go direct to // unmarshalling mb.loadObject(); BranchWrapper ifnnull = mb.appendIFNONNULL(this); // check for extension mapping handling required if (m_extensions != null) { // generate name comparison unless an abstract mapping BranchWrapper ifthis = null; if (hasname) { // test if at defined element name mb.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS); mb.loadContext(); m_name.genPushUriPair(mb); mb.appendCallInterface(UNMARSHAL_ISATMETHOD, UNMARSHAL_ISATSIGNATURE); ifthis = mb.appendIFNE(this); } // build code to check each extension mapping in turn, // keeping an instance of the unmarshaller for the matching // extension BranchWrapper[] iffounds = new BranchWrapper[m_extensions.size()]; for (int i = 0; i < iffounds.length; i++) { IMapping map = (IMapping)m_extensions.get(i); mb.loadContext(); mb.appendLoadConstant(map.getIndex()); mb.appendCallInterface(GETUNMARSHALLER_METHOD, GETUNMARSHALLER_SIGNATURE); mb.appendDUP(); mb.loadContext(); mb.appendCallInterface(UNMARSHALLERPRESENT_METHOD, UNMARSHALLERPRESENT_SIGNATURE); iffounds[i] = mb.appendIFNE(this); mb.appendPOP(); } // generate code to throw exception if no matching extension // found mb.appendCreateNew("java.lang.StringBuffer"); mb.appendDUP(); mb.appendLoadConstant("Element "); mb.appendCallInit("java.lang.StringBuffer", "(Ljava/lang/String;)V"); mb.appendDUP(); mb.loadContext(UNMARSHALCONTEXT_CLASS); mb.appendCallVirtual(CURRENTELEMENT_METHOD, CURRENTELEMENT_SIGNATURE); mb.appendCallVirtual("java.lang.StringBuffer.append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); mb.appendDUP(); mb.appendLoadConstant(" has no mapping that extends " + m_class.getClassName()); mb.appendCallVirtual("java.lang.StringBuffer.append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); mb.appendCallVirtual("java.lang.StringBuffer.toString", "()Ljava/lang/String;"); mb.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS); mb.appendDUP_X1(); mb.appendSWAP(); mb.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS, MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1); mb.appendThrow(); if (iffounds.length > 0) { // finish by calling unmarshaller for extension mapping // found and returning the result with no further // processing mb.initStackState(iffounds[0]); BranchTarget found = mb.appendTargetACONST_NULL(); for (int i = 0; i < iffounds.length; i++) { iffounds[i].setTarget(found, mb); } mb.loadContext(); mb.appendCallInterface(UNMARSHALLERUNMARSHAL_METHOD, UNMARSHALLERUNMARSHAL_SIGNATURE); mb.appendReturn("java.lang.Object"); } // fall into instance creation if this mapping reference if (ifthis != null) { mb.targetNext(ifthis); } } else if (m_isAbstract) { // throw an exception when no instance supplied mb.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS); mb.appendDUP(); mb.appendLoadConstant("Abstract mapping requires instance to " + "be supplied for class " + m_class.getClassName()); mb.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS, MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1); mb.appendThrow(); } if (hasname) { // just create an instance of the (non-abstract) mapped class genNewInstance(mb); mb.storeObject(); } // define unmarshallings for child mappings of this mapping mb.targetNext(ifnnull); ArrayList maps = m_defContext.getMappings(); if (maps != null && maps.size() > 0) { for (int i = 0; i < maps.size(); i++) { IMapping map = (IMapping)maps.get(i); if (!map.isAbstract() || map.isBase()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -