[jboss-svn-commits] JBoss Common SVN: r2213 - in jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling: . impl/runtime

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Dec 11 11:17:27 EST 2006


Author: alex.loubyansky at jboss.com
Date: 2006-12-11 11:17:21 -0500 (Mon, 11 Dec 2006)
New Revision: 2213

Modified:
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
Log:
JBXB-94 made type.pushInterceptor(...) create a local interceptor stack that would be invoked before the stack from the ElementBinding in start startElement and after it in the endElement

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2006-12-10 17:58:18 UTC (rev 2212)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2006-12-11 16:17:21 UTC (rev 2213)
@@ -23,6 +23,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.ListIterator;
 import javax.xml.namespace.QName;
@@ -170,6 +171,7 @@
       QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
       ParticleBinding particle = null;
       ParticleHandler handler = null;
+      TypeBinding parentType = null;
       boolean repeated = false;
       boolean repeatedParticle = false;
       StackItem item = null;
@@ -214,6 +216,7 @@
                   if(element.getQName().equals(startName))
                   {
                      particle = item.particle;
+                     parentType = item.parentType;
                      repeated = true;
                      item.reset();
 
@@ -234,10 +237,9 @@
                }
                else
                {
-                  ParticleBinding typeParticle = element.getType().getParticle();
-                  ModelGroupBinding modelGroup = typeParticle == null ?
-                     null :
-                     (ModelGroupBinding)typeParticle.getTerm();
+                  parentType = element.getType();
+                  ParticleBinding typeParticle = parentType.getParticle();
+                  ModelGroupBinding modelGroup = typeParticle == null ? null : (ModelGroupBinding)typeParticle.getTerm();
                   if(modelGroup == null)
                   {
                      if(startName.equals(Constants.QNAME_XOP_INCLUDE))
@@ -251,7 +253,7 @@
                         TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
                         xopIncludeType.setSchemaBinding(schema);
                         xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
-                        xopIncludeType.setHandler(new XOPIncludeHandler(element.getType(), schema.getXopUnmarshaller()));
+                        xopIncludeType.setHandler(new XOPIncludeHandler(parentType, schema.getXopUnmarshaller()));
 
                         ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
 
@@ -266,7 +268,7 @@
                         break;
                      }
 
-                     QName typeName = element.getType().getQName();
+                     QName typeName = parentType.getQName();
                      throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
                         " type of element " +
                         element.getQName() +
@@ -299,7 +301,7 @@
 
                         handler = getHandler(modelGroupParticle);
                         o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                        push(cursor, o, handler);
+                        push(cursor, o, handler, parentType);
                      }
                      particle = cursor.getCurrentParticle();
                   }
@@ -369,6 +371,7 @@
                   }
 
                   // push all except the last one
+                  parentType = item.parentType;
                   Object o = item.o;
                   for(int i = newCursors.size() - 2; i >= 0; --i)
                   {
@@ -377,7 +380,7 @@
                      ParticleBinding modelGroupParticle = cursor.getParticle();
                      handler = getHandler(modelGroupParticle);
                      o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                     push(cursor, o, handler);
+                     push(cursor, o, handler, parentType);
                   }
                   cursor = (ModelGroupBinding.Cursor)newCursors.get(0);
                   particle = cursor.getCurrentParticle();
@@ -476,19 +479,28 @@
             handler = defParticleHandler;
          }
 
+         List localInterceptors = parentType == null ? Collections.EMPTY_LIST : parentType.getInterceptors(startName);         
          List interceptors = element.getInterceptors();
-         if(!interceptors.isEmpty())
+         if(interceptors.size() + localInterceptors.size() > 0)
          {
             if (repeated)
             {
                pop();
             }
 
+            for (int i = 0; i < localInterceptors.size(); ++i)
+            {
+               ElementInterceptor interceptor = (ElementInterceptor) localInterceptors.get(i);
+               parent = interceptor.startElement(parent, startName, type);
+               push(particle, parent, handler, parentType);
+               interceptor.attributes(parent, startName, type, atts, nsRegistry);
+            }
+
             for (int i = 0; i < interceptors.size(); ++i)
             {
                ElementInterceptor interceptor = (ElementInterceptor) interceptors.get(i);
                parent = interceptor.startElement(parent, startName, type);
-               push(startName, particle, parent, handler);
+               push(particle, parent, handler, parentType);
                interceptor.attributes(parent, startName, type, atts, nsRegistry);
             }
 
@@ -546,7 +558,7 @@
       }
       else
       {
-         push(startName, particle, o, handler);
+         push(particle, o, handler, parentType);
       }
    }
 
@@ -816,6 +828,9 @@
       List interceptors = element.getInterceptors();
       int interceptorsTotal = interceptors.size();
 
+      List localInterceptors = item.parentType == null ? Collections.EMPTY_LIST : item.parentType.getInterceptors(endName);
+      int localInterceptorsTotal = localInterceptors.size();
+
       if(o != NIL)
       {
          //
@@ -945,10 +960,18 @@
             for(int i = interceptorsTotal - 1; i >= 0; --i)
             {
                ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-               interceptor.characters(((StackItem)stack.peek(interceptorsTotal - i)).o,
+               interceptor.characters(((StackItem)stack.peek(interceptorsTotal + localInterceptorsTotal - i)).o,
                   endName, type, nsRegistry, dataContent
                );
             }
+
+            for(int i = localInterceptorsTotal - 1; i >= 0; --i)
+            {
+               ElementInterceptor interceptor = (ElementInterceptor)localInterceptors.get(i);
+               interceptor.characters(((StackItem)stack.peek(localInterceptorsTotal - i)).o,
+                  endName, type, nsRegistry, dataContent
+               );
+            }
          }
       }
       else
@@ -988,7 +1011,7 @@
       // setParent
       //
 
-      if(interceptorsTotal == 0)
+      if(localInterceptorsTotal + interceptorsTotal == 0)
       {
          ParticleBinding parentParticle = getParentParticle();
          boolean hasWildcard = false;
@@ -1045,6 +1068,7 @@
       else
       {
          StackItem popped = pop();
+
          for(int i = interceptorsTotal - 1; i >= 0; --i)
          {
             ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
@@ -1052,6 +1076,15 @@
             interceptor.add(parent, o, endName);
             o = parent;
          }
+
+         for(int i = localInterceptorsTotal - 1; i >= 0; --i)
+         {
+            ElementInterceptor interceptor = (ElementInterceptor)localInterceptors.get(i);
+            parent = pop().o;
+            interceptor.add(parent, o, endName);
+            o = parent;
+         }
+
          // need to have correst endRepeatableParticle events
          stack.push(popped);
       }
@@ -1095,9 +1128,12 @@
       }
    }
 
-   private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler)
+   private void push(ParticleBinding particle, Object o, ParticleHandler handler, TypeBinding parentType)
    {
-      StackItem item = new StackItem(particle, o, handler);
+      StackItem item = new StackItem(particle);
+      item.o = o;
+      item.handler = handler;
+      item.parentType = parentType;      
       stack.push(item);
       if(trace)
       {
@@ -1106,13 +1142,16 @@
          {
             binding = particle.getTerm();
          }
-         log.trace("pushed " + qName + "=" + o + ", binding=" + binding);
+         log.trace("pushed " + ((ElementBinding)particle.getTerm()).getQName() + "=" + o + ", binding=" + binding);
       }
    }
 
-   private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
+   private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler, TypeBinding parentType)
    {
-      StackItem item = new StackItem(cursor, o, handler);
+      StackItem item = new StackItem(cursor);
+      item.o = o;
+      item.handler = handler;
+      item.parentType = parentType;
       stack.push(item);
       if(trace)
       {
@@ -1144,32 +1183,29 @@
       final ModelGroupBinding.Cursor cursor;
       final ParticleBinding particle;
       ParticleHandler handler;
+      TypeBinding parentType;
       boolean ignoreCharacters;
       Object o;
       ValueList repeatableParticleValue;
       StringBuffer textContent;
       boolean ended;
 
-      public StackItem(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
+      public StackItem(ModelGroupBinding.Cursor cursor)
       {
          if (cursor == null)
             throw new IllegalArgumentException("Null cursor");
          // this is modelgroup particle
          this.cursor = cursor;
          this.particle = cursor.getParticle();
-         this.o = o;
-         this.handler = handler;
       }
 
-      public StackItem(ParticleBinding particle, Object o, ParticleHandler handler)
+      public StackItem(ParticleBinding particle)
       {
          if (particle == null)
             throw new IllegalArgumentException("Null particle");
          // this is element particle
          this.cursor = null;
          this.particle = particle;
-         this.o = o;
-         this.handler = handler;
       }
 
       void reset()

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	2006-12-10 17:58:18 UTC (rev 2212)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	2006-12-11 16:17:21 UTC (rev 2213)
@@ -54,7 +54,6 @@
    /** Map<QName, AttributeBinding>  */
    private Map attrs = Collections.EMPTY_MAP;
    private ParticleHandler handler;//todo default handler is now in SundayContentHandler.
-   //private ParticleHandler handler = DefaultHandlers.ELEMENT_HANDLER;
    private CharactersHandler charactersHandler;
    private ClassMetaData classMetaData;
    private ValueMetaData valueMetaData;
@@ -83,6 +82,11 @@
    private XOPUnmarshaller xopUnmarshaller;
    private XOPMarshaller xopMarshaller;
 
+   /** Map<QName, List<ElementInterceptor>>
+    * these are local element interceptors that are "added" to the interceptor stack
+    * defined in the element binding */
+   private Map interceptors = Collections.EMPTY_MAP;
+   
    public TypeBinding()
    {
       this.qName = null;
@@ -322,6 +326,19 @@
       return handler;
    }
 
+   /**
+    * Pushes a new interceptor for the specified element.
+    * If the element has a global scope in the schema,
+    * this interceptor will invoked only when the element is found to be a child
+    * of this type. This is the difference between the local interceptors
+    * added with this method and the interceptors added directly to the
+    * element binding.
+    * When element is started, local interceptors are invoked before the interceptors
+    * from the element binding. In the endElement the order is reversed.
+    * 
+    * @param qName
+    * @param interceptor
+    */
    public void pushInterceptor(QName qName, ElementInterceptor interceptor)
    {
       ElementBinding el = getElement(qName);
@@ -329,9 +346,48 @@
       {
          el = addElement(qName, new TypeBinding());
       }
-      el.pushInterceptor(interceptor);
+      //el.pushInterceptor(interceptor);
+      
+      List intList = (List) interceptors.get(qName);
+      if(intList == null)
+      {
+         intList = Collections.singletonList(interceptor);
+         switch(interceptors.size())
+         {
+            case 0:
+               interceptors = Collections.singletonMap(qName, intList);
+               break;
+            case 1:
+               interceptors = new HashMap(interceptors);
+            default:
+               interceptors.put(qName, intList);
+         }
+      }
+      else
+      {
+         if(intList.size() == 1)
+         {
+            intList = new ArrayList(intList);
+            interceptors.put(qName, intList);
+         }
+         intList.add(interceptor);
+      }
    }
 
+   /**
+    * Returns a list of local interceptors for the element.
+    * If there are no local interceptors for the element then
+    * an empty list is returned.
+    * 
+    * @param qName
+    * @return
+    */
+   public List getInterceptors(QName qName)
+   {
+      List list = (List) interceptors.get(qName);
+      return list == null ? Collections.EMPTY_LIST : list;
+   }
+   
    public TypeBinding getBaseType()
    {
       return baseType;

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java	2006-12-10 17:58:18 UTC (rev 2212)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java	2006-12-11 16:17:21 UTC (rev 2213)
@@ -515,7 +515,8 @@
                      fieldType = fieldType.getComponentType();
                   }
                }
-               else if(arrayItem.getInterceptors().isEmpty())
+               else if(((ElementBinding)term).getType().getInterceptors(arrayItem.getQName()).isEmpty() &&
+                     arrayItem.getInterceptors().isEmpty())
                {
                   QName typeName = ((ElementBinding)term).getType().getQName();
                   throw new JBossXBRuntimeException(




More information about the jboss-svn-commits mailing list