nestedcollection.java
来自「JiBX是一个为Java提供的XML数据绑定框架。它可以和现存的类一起运行」· Java 代码 · 共 845 行 · 第 1/3 页
JAVA
845 行
// start by setting target for branch from last component mb.targetNext(link); // if multiple types are included in content, append code to // check if item type matches this component IComponent child = (IComponent)m_contents.get(i); String type = child.getType(); if (count > 1 || (!"java.lang.Object".equals(type) && !ClassItem.isPrimitive(type))) { mb.appendDUP(); mb.appendInstanceOf(type); link = mb.appendIFEQ(this); mb.appendCreateCast(type); } // finish with code to marshal the component, branching back // to start of loop child.genContentMarshal(mb); mb.appendUnconditionalBranch(this).setTarget(start, mb); } } // patch final test failure branch to generate an exception if (link != null) { // instruction sequence for exception is create new exception // object, build message in StringBuffer using type of item // from stack, convert StringBuffer to String, invoke the // exeception constructor with the String, and finally throw // the exception mb.targetNext(link); mb.appendCreateNew("java.lang.StringBuffer"); mb.appendDUP(); mb.appendLoadConstant("Collection item of type "); mb.appendCallInit("java.lang.StringBuffer", "(Ljava/lang/String;)V"); mb.appendSWAP(); mb.appendDUP(); BranchWrapper ifnull = mb.appendIFNULL(this); mb.appendCallVirtual("java.lang.Object.getClass", "()Ljava/lang/Class;"); mb.appendCallVirtual("java.lang.Class.getName", "()Ljava/lang/String;"); BranchWrapper toend = mb.appendUnconditionalBranch(this); mb.targetNext(ifnull); mb.appendPOP(); mb.appendLoadConstant("NULL"); mb.targetNext(toend); mb.appendCallVirtual("java.lang.StringBuffer.append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); mb.appendLoadConstant(" has no binding defined"); 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(); } // finish by setting target for collection empty case(s) m_loadStrategy.genLoadDone(mb); mb.targetNext(ifempties); } else { throw new IllegalStateException ("Internal error - no content present"); } } public boolean hasId() { return false; } public void genLoadId(ContextMethodBuilder mb) throws JiBXException { throw new IllegalStateException("No ID child"); } public NameDefinition getWrapperName() { return null; } public boolean isOptional() { return m_isOptional; } public void setLinkages() throws JiBXException { for (int i = 0; i < m_contents.size(); i++) { ((IComponent)m_contents.get(i)).setLinkages(); } } // DEBUG public void print(int depth) { BindingDefinition.indent(depth); System.out.print("collection " + (m_isOrdered ? "ordered" : "unordered")); if (m_itemType != null) { System.out.print(" (" + m_itemType + ")"); } if (isFlexible()) { System.out.print(", flexible"); } System.out.println(); for (int i = 0; i < m_contents.size(); i++) { IComponent comp = (IComponent)m_contents.get(i); comp.print(depth+1); } } /** * Base class for collection item load strategy. The implementation class * must handle the appropriate form of code generation for the type of * collection being used. */ /*package*/ static abstract class CollectionLoad { /** * Generate code to initialize collection for loading items. This * generates the necessary code for handling the initialization. It * must be called before attempting to call the {@link #genLoadItem} * method. The base class implementation does nothing. * * @param mb method builder * @throws JiBXException if error in configuration */ protected void genLoadInit(ContextMethodBuilder mb) throws JiBXException {} /** * Generate code to load next item from collection. This generates the * necessary code for handling the load operation, leaving the item on * the stack. The {@link #genLoadInit} method must be called before * calling this method, and the {@link #genLoadDone} method must be * called after the last call to this method. This method must be * overridden by each subclass. * * @param mb method builder * @return branch wrapper for case of done with collection * @throws JiBXException if error in configuration */ protected abstract BranchWrapper genLoadItem(ContextMethodBuilder mb) throws JiBXException; /** * Generate code to clean up after loading items from collection. This * generates the necessary code for handling the clean up. It must be * called after the last call to {@link #genLoadItem}. The base class * implementation does nothing. * * @param mb method builder * @throws JiBXException if error in configuration */ protected void genLoadDone(ContextMethodBuilder mb) throws JiBXException {} } /** * Base class for collection item store strategy. The implementation class * must handle the appropriate form of code generation for the type of * collection being used. */ /*package*/ static abstract class CollectionStore { /** * Generate code to initialize collection for storing items. This * generates the necessary code for handling the initialization, * including creating the collection object if appropriate. It must be * called before attempting to call the {@link #genStoreItem} method. * The base class implementation does nothing. * * @param mb method builder * @throws JiBXException if error in configuration */ protected void genStoreInit(ContextMethodBuilder mb) throws JiBXException {} /** * Generate code to store next item to collection. This generates the * necessary code for handling the store operation, removing the item * from the stack. The {@link #genStoreInit} method must be called * before calling this method, and the {@link #genStoreDone} method must * be called after the last call to this method. This method must be * overridden by each subclass. * * @param mb method builder * @throws JiBXException if error in configuration */ protected abstract void genStoreItem(ContextMethodBuilder mb) throws JiBXException; /** * Generate code to clean up after storing items to collection. This * generates the necessary code for handling the clean up. It must be * called after the last call to {@link #genStoreItem}. The base class * implementation does nothing. * * @param mb method builder * @throws JiBXException if error in configuration */ protected void genStoreDone(ContextMethodBuilder mb) throws JiBXException {} } /** * Collection item load strategy for collection with items accessed by * index number. */ /*package*/ static class IndexedLoad extends CollectionLoad { /** Method used to get count of items in collection. */ private final ClassItem m_sizeMethod; /** Method used to get items by index from collection. */ private final ClassItem m_getMethod; /** * Constructor. * * @param size method used to get count of items in collection * @param get method used to retrieve items by index from collection */ /*package*/ IndexedLoad(ClassItem size, ClassItem get) { m_sizeMethod = size; m_getMethod = get; } protected void genLoadInit(ContextMethodBuilder mb) throws JiBXException { // create index local with appended code to set initial value mb.appendLoadConstant(-1); mb.defineSlot(m_getMethod, Type.INT); // create size local with appended code to set initial value from // collection method call if (!m_sizeMethod.isStatic()) { mb.loadObject(); } mb.appendCall(m_sizeMethod); mb.defineSlot(m_sizeMethod, Type.INT); } protected BranchWrapper genLoadItem(ContextMethodBuilder mb) throws JiBXException { // start by getting local variable slots for the index and size int islot = mb.getSlot(m_getMethod); int sslot = mb.getSlot(m_sizeMethod); // append code to first increment index, then check for end of // collection reached mb.appendIncrementLocal(1, islot); mb.appendLoadLocal(islot); mb.appendLoadLocal(sslot); mb.appendISUB(); BranchWrapper ifempty = mb.appendIFGE(this); // finish by calling collection method to load item at current index // position if (!m_getMethod.isStatic()) { mb.loadObject(); } mb.appendLoadLocal(islot); mb.appendCall(m_getMethod); return ifempty; } protected void genLoadDone(ContextMethodBuilder mb) throws JiBXException { mb.freeSlot(m_getMethod); mb.freeSlot(m_sizeMethod); } } /** * Collection item store strategy for collection with items set by
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?