📄 valuechild.java
字号:
CHECK_ATTRIBUTE_NAME : CHECK_ELEMENT_NAME; mb.appendCallVirtual(name, CHECK_SIGNATURE); BranchWrapper ifpres = mb.appendIFNE(this); // push a null value to be stored as result for missing case mb.appendACONST_NULL(); ifmiss = mb.appendUnconditionalBranch(this); // reload context reference and name information for use by actual // unmarshalling call mb.targetNext(ifpres); mb.loadContext(); m_name.genPushUriPair(mb); } // find index of target class ID map int index = m_container.getBindingRoot(). getIdClassIndex(m_property.getTypeName()); // check if forward references allowed if (m_container.getBindingRoot().isForwards()) { // generate call to unmarshal with forward allowed mb.appendLoadConstant(index); String name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ? UNMARSHAL_FWDREF_ATTR_NAME : UNMARSHAL_FWDREF_ELEM_NAME; mb.appendCallVirtual(name, UNMARSHAL_DEFREF_SIGNATURE); // check for null result returned mb.appendDUP(); BranchWrapper ifdef = mb.appendIFNONNULL(this); // build and register backfill handler; start by loading the // unmarshalling context, then load the index number of the target // class and create an instance of the backfill handler ClassFile backclas = createBackfillClass(); mb.loadContext(); mb.appendLoadConstant(index); mb.appendCreateNew(backclas.getName()); // duplicate the backfill handler reference, then load a reference // to the owning object and call the initializer before calling // the unmarshalling context to register the handler mb.appendDUP(); mb.loadObject(); mb.appendCallInit(backclas.getName(), "(" + m_objContext.getBoundClass().getClassFile().getSignature() + ")V"); mb.appendCallVirtual(REGISTER_BACKFILL_NAME, REGISTER_BACKFILL_SIGNATURE); // set branch target for case where already defined mb.targetNext(ifdef); } else { // generate call to unmarshal with predefined ID required mb.appendLoadConstant(index); String name = m_valueStyle == ValueChild.ATTRIBUTE_STYLE ? UNMARSHAL_DEFREF_ATTR_NAME : UNMARSHAL_DEFREF_ELEM_NAME; mb.appendCallVirtual(name, UNMARSHAL_DEFREF_SIGNATURE); } // handle object type conversion if needed mb.appendCreateCast(m_property.getSetValueType()); // store returned reference to property if (ifmiss != null) { mb.targetNext(ifmiss); } m_property.genStore(mb); } /** * Generate test if present code. This generates code that tests if the * child is present, leaving the result of the test (zero if missing, * nonzero if present) on the stack. * * @param mb unmarshal method builder * @throws JiBXException if configuration error */ public void genIfPresentTest(UnmarshalBuilder mb) throws JiBXException { // make sure this is an appropriate call if (m_name == null) { throw new JiBXException("Method call on invalid value"); } // load the unmarshalling context and name information, then call the // appropriate method to test for item present mb.loadContext(); m_name.genPushUriPair(mb); String name = (m_valueStyle == ValueChild.ATTRIBUTE_STYLE) ? CHECK_ATTRIBUTE_NAME : CHECK_ELEMENT_NAME; mb.appendCallVirtual(name, CHECK_SIGNATURE); } /** * Generate unmarshalling code. This internal method generates the * necessary code for handling the unmarshalling operation. The code * generated by this method restores the stack to the original state * when done. * * @param mb method builder * @throws JiBXException if error in configuration */ private void genUnmarshal(ContextMethodBuilder mb) throws JiBXException { // first part of generated instruction sequence is to preload object // reference for later use, then load the unmarshalling context and // the name information if (m_constantValue == null && !m_property.isImplicit()) { mb.loadObject(); } // prepare for parsing the element name mb.loadContext(); if (m_name != null) { m_name.genPushUriPair(mb); } // check if this is an identifier for object boolean isatt = (m_valueStyle == ValueChild.ATTRIBUTE_STYLE); if (m_identType == DEF_IDENT || m_identType == AUTO_IDENT) { // always unmarshal identifier value as text, then duplicate for use // if storing BindingDefinition.s_stringConversion.genParseRequired(isatt, mb); if (m_identType != AUTO_IDENT) { mb.appendDUP(); } // load the context and swap to reorder, load the index for the // class, and finally the ID'ed object, then call ID definition // method mb.loadContext(); mb.appendSWAP(); int index = m_container.getBindingRoot(). getIdClassIndex(m_property.getTypeName()); mb.appendLoadConstant(index); mb.loadObject(); mb.appendCallVirtual(DEFINE_ID_NAME, DEFINE_ID_SIGNATURE); // convert from text and store result using object reference loaded // earlier if (m_identType != AUTO_IDENT) { m_conversion.genFromText(mb); m_property.genStore(mb); } } else if (m_identType == REF_IDENT) { // generate code for unmarshalling object ID genParseIdRef(mb); } else if (m_constantValue == null) { // unmarshal and convert value if (m_isNillable) { // first check for element present at all BranchWrapper ifmiss = null; if (m_property.isOptional()) { mb.appendCallVirtual(UNMARSHAL_PARSE_IF_START_NAME, UNMARSHAL_PARSE_IF_START_SIGNATURE); ifmiss = mb.appendIFEQ(this); } else { mb.appendCallVirtual(UNMARSHAL_PARSE_TO_START_NAME, UNMARSHAL_PARSE_TO_START_SIGNATURE); } // check for xsi:nil="true" mb.loadContext(); mb.appendLoadConstant("http://www.w3.org/2001/XMLSchema-instance"); mb.appendLoadConstant("nil"); mb.appendICONST_0(); mb.appendCallVirtual(UNMARSHAL_ATTRIBUTE_BOOLEAN_NAME, UNMARSHAL_ATTRIBUTE_BOOLEAN_SIGNATURE); BranchWrapper notnil = mb.appendIFEQ(this); // code to handle nil case just parses past end mb.loadContext(); m_name.genPushUriPair(mb); mb.appendCallVirtual(UNMARSHAL_PARSE_PAST_END_NAME, UNMARSHAL_PARSE_PAST_END_SIGNATURE); // merge path with element not present, which just loads null mb.targetNext(ifmiss); mb.appendACONST_NULL(); BranchWrapper ifnil = mb.appendUnconditionalBranch(this); // read element text and process for not-nil case mb.targetNext(notnil); mb.loadContext(); m_name.genPushUriPair(mb); mb.appendCallVirtual(UNMARSHAL_ELEMENT_TEXT_NAME, UNMARSHAL_ELEMENT_TEXT_SIGNATURE); m_conversion.genFromText(mb); mb.targetNext(ifnil); } else if (m_valueStyle == ValueChild.TEXT_STYLE || m_valueStyle == ValueChild.CDATA_STYLE) { // unmarshal text value directly and let handler convert mb.appendCallVirtual(UNMARSHAL_TEXT_NAME, UNMARSHAL_TEXT_SIGNATURE); m_conversion.genFromText(mb); } else if (m_property.isOptional() && (isatt || m_container.isContentOrdered())) { // parse value with possible default in ordered container m_conversion.genParseOptional(isatt, mb); } else { // parse required value, or value in unordered container m_conversion.genParseRequired(isatt, mb); } // handle object type conversion if needed if (!m_conversion.isPrimitive() && m_property != null) { String stype = m_conversion.getTypeName(); String dtype = m_property.getSetValueType(); mb.appendCreateCast(stype, dtype); } // store result using object reference loaded earlier m_property.genStore(mb); } else { // unmarshal and compare value BranchWrapper ifmiss = null; if (m_valueStyle == ValueChild.TEXT_STYLE || m_valueStyle == ValueChild.CDATA_STYLE) { // unmarshal text value directly and let handler convert mb.appendCallVirtual(UNMARSHAL_TEXT_NAME, UNMARSHAL_TEXT_SIGNATURE); } else if (m_property.isOptional() && (isatt || m_container.isContentOrdered())) { // parse optional attribute or element value m_conversion.genParseOptional(isatt, mb); mb.appendDUP(); ifmiss = mb.appendIFNULL(this); } else { // parse required attribute or element value m_conversion.genParseRequired(isatt, mb); } // compare unmarshalled value with required constant mb.appendDUP(); mb.appendLoadConstant(m_constantValue); mb.appendCallVirtual("java.lang.String.equals", "(Ljava/lang/Object;)Z"); BranchWrapper ifmatch = mb.appendIFNE(this); // throw exception on comparison error mb.appendCreateNew("java.lang.StringBuffer"); mb.appendDUP(); mb.appendLoadConstant("Expected constant value \"" + m_constantValue + "\", found \""); mb.appendCallInit("java.lang.StringBuffer", "(Ljava/lang/String;)V"); mb.appendSWAP(); mb.appendCallVirtual("java.lang.StringBuffer.append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); mb.appendLoadConstant("\""); mb.appendCallVirtual("java.lang.StringBuffer.append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); mb.appendCallVirtual("java.lang.StringBuffer.toString", "()Ljava/lang/String;"); mb.loadContext(); mb.appendSWAP(); mb.appendCallVirtual(UNMARSHALLING_THROWEXCEPTION_METHOD, UNMARSHALLING_THROWEXCEPTION_SIGNATURE); mb.appendACONST_NULL(); // finish by setting target for branch mb.targetNext(ifmatch); mb.targetNext(ifmiss); mb.appendPOP(); } } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -