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

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Sep 25 11:37:22 EDT 2006


Author: alex.loubyansky at jboss.com
Date: 2006-09-25 11:37:19 -0400 (Mon, 25 Sep 2006)
New Revision: 2063

Removed:
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/JBXB76ContentHandler.java
Modified:
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/UnmarshallerImpl.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
Log:
merged JBXB76ContentHandler into the default SundayContentHandler

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/UnmarshallerImpl.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/UnmarshallerImpl.java	2006-09-25 15:18:16 UTC (rev 2062)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/UnmarshallerImpl.java	2006-09-25 15:37:19 UTC (rev 2063)
@@ -28,8 +28,7 @@
 import org.jboss.xb.binding.parser.sax.SaxJBossXBParser;
 import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
 import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
-//import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler;
-import org.jboss.xb.binding.sunday.unmarshalling.JBXB76ContentHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler;
 import org.jboss.xb.binding.metadata.unmarshalling.DocumentBinding;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.ErrorHandler;
@@ -109,42 +108,42 @@
 
    public Object unmarshal(String xml, SchemaBinding schemaBinding) throws JBossXBException
    {
-      JBossXBParser.ContentHandler cHandler = new JBXB76ContentHandler(schemaBinding);
+      JBossXBParser.ContentHandler cHandler = new SundayContentHandler(schemaBinding);
       parser.parse(xml, cHandler);
       return cHandler.getRoot();
    }
 
    public Object unmarshal(Reader xmlReader, SchemaBinding schemaBinding) throws JBossXBException
    {
-      JBossXBParser.ContentHandler cHandler = new JBXB76ContentHandler(schemaBinding);
+      JBossXBParser.ContentHandler cHandler = new SundayContentHandler(schemaBinding);
       parser.parse(xmlReader, cHandler);
       return cHandler.getRoot();
    }
 
    public Object unmarshal(InputStream xmlStream, SchemaBinding schemaBinding) throws JBossXBException
    {
-      JBossXBParser.ContentHandler cHandler = new JBXB76ContentHandler(schemaBinding);
+      JBossXBParser.ContentHandler cHandler = new SundayContentHandler(schemaBinding);
       parser.parse(xmlStream, cHandler);
       return cHandler.getRoot();
    }
 
    public Object unmarshal(String xml, SchemaBindingResolver schemaResolver) throws JBossXBException
    {
-      JBossXBParser.ContentHandler cHandler = new JBXB76ContentHandler(schemaResolver);
+      JBossXBParser.ContentHandler cHandler = new SundayContentHandler(schemaResolver);
       parser.parse(xml, cHandler);
       return cHandler.getRoot();
    }
 
    public Object unmarshal(Reader xmlReader, SchemaBindingResolver schemaResolver) throws JBossXBException
    {
-      JBossXBParser.ContentHandler cHandler = new JBXB76ContentHandler(schemaResolver);
+      JBossXBParser.ContentHandler cHandler = new SundayContentHandler(schemaResolver);
       parser.parse(xmlReader, cHandler);
       return cHandler.getRoot();
    }
 
    public Object unmarshal(InputStream xmlStream, SchemaBindingResolver schemaResolver) throws JBossXBException
    {
-      JBossXBParser.ContentHandler cHandler = new JBXB76ContentHandler(schemaResolver);
+      JBossXBParser.ContentHandler cHandler = new SundayContentHandler(schemaResolver);
       parser.parse(xmlStream, cHandler);
       return cHandler.getRoot();
    }

Deleted: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/JBXB76ContentHandler.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/JBXB76ContentHandler.java	2006-09-25 15:18:16 UTC (rev 2062)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/JBXB76ContentHandler.java	2006-09-25 15:37:19 UTC (rev 2063)
@@ -1,1178 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.sunday.unmarshalling;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.ListIterator;
-import javax.xml.namespace.QName;
-import org.apache.xerces.xs.XSTypeDefinition;
-import org.jboss.logging.Logger;
-import org.jboss.util.StringPropertyReplacer;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.GenericValueContainer;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.NamespaceRegistry;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.group.ValueList;
-import org.jboss.xb.binding.group.ValueListHandler;
-import org.jboss.xb.binding.group.ValueListInitializer;
-import org.jboss.xb.binding.metadata.CharactersMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.parser.JBossXBParser;
-import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
-import org.xml.sax.Attributes;
-
-/**
- * ContentHandler that is used as a sandbox for JBXB-76
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision: 1883 $</tt>
- */
-public class JBXB76ContentHandler
-   implements JBossXBParser.ContentHandler
-{
-   private final static Logger log = Logger.getLogger(JBXB76ContentHandler.class);
-
-   private final static Object NIL = new Object();
-
-   private final SchemaBinding schema;
-   private final SchemaBindingResolver schemaResolver;
-
-   private final StackImpl stack = new StackImpl();
-
-   private Object root;
-   private NamespaceRegistry nsRegistry = new NamespaceRegistry();
-
-   private ParticleHandler defParticleHandler = DefaultHandlers.ELEMENT_HANDLER;
-
-   private final boolean trace = log.isTraceEnabled();
-
-   public JBXB76ContentHandler(SchemaBinding schema)
-   {
-      this.schema = schema;
-      this.schemaResolver = null;
-   }
-
-   public JBXB76ContentHandler(SchemaBindingResolver schemaResolver)
-   {
-      this.schemaResolver = schemaResolver;
-      this.schema = null;
-   }
-
-   public void characters(char[] ch, int start, int length)
-   {
-      StackItem stackItem = stack.peek();
-      if(stackItem.cursor == null)
-      {
-         if(stackItem.textContent == null)
-         {
-            stackItem.textContent = new StringBuffer();
-         }
-         stackItem.textContent.append(ch, start, length);
-      }
-   }
-
-   public void endElement(String namespaceURI, String localName, String qName)
-   {
-      ElementBinding elementBinding = null;
-      QName endName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
-      StackItem item;
-      while(true)
-      {
-         item = stack.peek();
-         if(item.cursor == null)
-         {
-            if(item.ended)
-            {
-               pop();
-               if(item.particle.isRepeatable())
-               {
-                  endRepeatableParticle(item.particle);
-               }
-            }
-            else
-            {
-               elementBinding = (ElementBinding)item.particle.getTerm();
-               item.ended = true;
-               break;
-            }
-         }
-         else
-         {
-            if(!item.ended) // could be ended if it's a choice
-            {
-               endParticle(item, endName, 1);
-            }
-
-            ParticleBinding currentParticle = item.cursor.getCurrentParticle();
-            TermBinding term = currentParticle.getTerm();
-            if(term.isWildcard() && currentParticle.isRepeatable())
-            {
-               endRepeatableParticle(currentParticle);
-            }
-
-            pop();
-            if(item.particle.isRepeatable())
-            {
-               endRepeatableParticle(item.particle);
-            }
-         }
-      }
-
-      if(elementBinding == null)
-      {
-         throw new JBossXBRuntimeException("Failed to endElement " + qName + ": binding not found");
-      }
-
-      if(!elementBinding.getQName().equals(endName))
-      {
-         throw new JBossXBRuntimeException("Failed to end element " +
-            new QName(namespaceURI, localName) +
-            ": element on the stack is " + elementBinding.getQName()
-         );
-      }
-
-      endElement();
-   }
-
-   public void startElement(String namespaceURI,
-                            String localName,
-                            String qName,
-                            Attributes atts,
-                            XSTypeDefinition xercesType)
-   {
-      QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
-      ParticleBinding particle = null;
-      ParticleHandler handler = null;
-      boolean repeated = false;
-      boolean repeatedParticle = false;
-      StackItem item = null;
-      ModelGroupBinding.Cursor cursor = null; // used only when particle is a wildcard
-      SchemaBinding schemaBinding = schema;
-
-      if(stack.isEmpty())
-      {
-         if(schemaBinding != null)
-         {
-            particle = schemaBinding.getElementParticle(startName);
-         }
-         else if(schemaResolver != null)
-         {
-            String schemaLocation = atts == null ? null : Util.getSchemaLocation(atts, namespaceURI);
-            schemaBinding = schemaResolver.resolve(namespaceURI, null, schemaLocation);
-            if(schemaBinding != null)
-            {
-               particle = schemaBinding.getElementParticle(startName);
-            }
-         }
-         else
-         {
-            throw new JBossXBRuntimeException("Neither schema binding nor schema binding resolver is available!");
-         }
-      }
-      else
-      {
-         while(!stack.isEmpty())
-         {
-            item = stack.peek();
-            if(item.cursor == null)
-            {
-               TermBinding term = item.particle.getTerm();
-               ElementBinding element = (ElementBinding)term;
-               if(item.ended)
-               {
-                  if(element.getQName().equals(startName))
-                  {
-                     particle = item.particle;
-                     repeated = true;
-                     item.reset();
-
-                     if(!particle.isRepeatable())
-                     {
-                        endRepeatableParent(startName);
-                     }
-                  }
-                  else
-                  {
-                     pop();                     
-                     if(item.particle.isRepeatable())
-                     {
-                        endRepeatableParticle(item.particle);
-                     }
-                     continue;
-                  }
-               }
-               else
-               {
-                  ParticleBinding typeParticle = element.getType().getParticle();
-                  ModelGroupBinding modelGroup = typeParticle == null ?
-                     null :
-                     (ModelGroupBinding)typeParticle.getTerm();
-                  if(modelGroup == null)
-                  {
-                     if(startName.equals(Constants.QNAME_XOP_INCLUDE))
-                     {
-                        TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
-                        if(anyUriType == null)
-                        {
-                           log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
-                        }
-
-                        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()));
-
-                        ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
-
-                        particle = new ParticleBinding(xopInclude);
-                        
-                        ElementBinding parentElement = (ElementBinding) stack.peek().particle.getTerm();
-                        parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
-                        
-                        item.handler = DefaultHandlers.XOP_HANDLER;
-                        item.cHandler = CharactersHandler.NOOP;
-                        item.o = item.handler.startParticle(stack.peek().o, startName, stack.peek().particle, null, nsRegistry);
-                        break;
-                     }
-
-                     QName typeName = element.getType().getQName();
-                     throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
-                        " type of element " +
-                        element.getQName() +
-                        " should be complex and contain " + startName + " as a child element."
-                     );
-                  }
-
-                  cursor = modelGroup.newCursor(typeParticle);
-                  List newCursors = cursor.startElement(startName, atts);
-                  if(newCursors.isEmpty())
-                  {
-                     throw new JBossXBRuntimeException(startName +
-                        " not found as a child of " +
-                        ((ElementBinding)term).getQName()
-                     );
-                  }
-                  else
-                  {
-                     Object o = item.o;
-                     // push all except the last one
-                     for(int i = newCursors.size() - 1; i >= 0; --i)
-                     {
-                        cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
-
-                        ParticleBinding modelGroupParticle = cursor.getParticle();
-                        if(modelGroupParticle.isRepeatable())
-                        {
-                           startRepeatableParticle(startName, modelGroupParticle);
-                        }
-
-                        handler = getHandler(modelGroupParticle);
-                        o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                        push(cursor, o, handler);
-                     }
-                     particle = cursor.getCurrentParticle();
-                  }
-               }
-               break;
-            }
-            else
-            {
-               cursor = item.cursor;
-               if(cursor == null)
-               {
-                  throw new JBossXBRuntimeException("No cursor for " + startName);
-               }
-
-               // todo review
-               if(!item.ended && cursor.isPositioned() && cursor.getParticle().getTerm() instanceof ChoiceBinding)
-               {
-                  endParticle(item, startName, 1);
-                  if(!item.particle.isRepeatable()) // this is for repeatable choices that should stay on the stack
-                  {
-                     pop();
-                  }
-                  continue;
-               }
-
-               //int prevOccurence = cursor.getOccurence();
-               ParticleBinding prevParticle = cursor.isPositioned() ? cursor.getCurrentParticle() : null;
-               List newCursors = cursor.startElement(startName, atts);
-               if(newCursors.isEmpty())
-               {
-                  if(!item.ended) // this is for choices
-                  {
-                     endParticle(item, startName, 1);
-                  }
-                  pop();
-               }
-               else
-               {
-                  if(item.ended) // for repeatable choices
-                  {
-                     if(!item.particle.isRepeatable())
-                     {
-                        throw new JBossXBRuntimeException("The particle expected to be repeatable but it's not: " + item.particle.getTerm());
-                     }
-                     item.reset();
-                     
-                     handler = getHandler(item.particle);
-                     item.o = handler.startParticle(stack.peek(1).o, startName, item.particle, atts, nsRegistry);
-                  }
-                  
-                  ParticleBinding curParticle = cursor.getCurrentParticle();
-                  if(curParticle != prevParticle)
-                  {
-                     if(prevParticle != null && prevParticle.isRepeatable() && prevParticle.getTerm().isModelGroup())
-                     {
-                        endRepeatableParticle(prevParticle);
-                     }
-
-                     if(newCursors.size() > 1 && curParticle.isRepeatable())
-                     {
-                        startRepeatableParticle(startName, curParticle);
-                     }
-                  }
-                  else
-                  {
-                     repeatedParticle = true;
-                  }
-
-                  // push all except the last one
-                  Object o = item.o;
-                  for(int i = newCursors.size() - 2; i >= 0; --i)
-                  {
-                     cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
-
-                     ParticleBinding modelGroupParticle = cursor.getParticle();
-                     handler = getHandler(modelGroupParticle);
-                     o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                     push(cursor, o, handler);
-                  }
-                  cursor = (ModelGroupBinding.Cursor)newCursors.get(0);
-                  particle = cursor.getCurrentParticle();
-                  break;
-               }
-            }
-         }
-      }
-
-      Object o = null;
-      if(particle != null)
-      {
-         Object parent = stack.isEmpty() ? null :
-            (repeated ? stack.peek(1).o : stack.peek().o);
-         if(particle.getTerm() instanceof WildcardBinding)
-         {
-            /*
-            WildcardBinding wildcard = (WildcardBinding)particle.getTerm();
-            ElementBinding element = wildcard.getElement(startName, atts);
-            */
-            ElementBinding element = cursor.getElement();
-            if(element == null)
-            {
-               throw new JBossXBRuntimeException("Failed to resolve element " +
-                  startName + " for wildcard."
-               );
-            }
-
-            if(!repeatedParticle && particle.isRepeatable())
-            {
-               startRepeatableParticle(startName, particle);
-            }
-            particle = new ParticleBinding(element/*, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded()*/);
-         }
-
-         ElementBinding element = (ElementBinding)particle.getTerm();
-
-         // todo xsi:type support should be implemented in a better way
-         String xsiType = atts.getValue("xsi:type");
-         if(xsiType != null)
-         {
-            if(trace)
-            {
-               log.trace(element.getQName() + " uses xsi:type " + xsiType);
-            }
-
-            String xsiTypePrefix;
-            String xsiTypeLocal;
-            int colon = xsiType.indexOf(':');
-            if(colon == -1)
-            {
-               xsiTypePrefix = "";
-               xsiTypeLocal = xsiType;
-            }
-            else
-            {
-               xsiTypePrefix = xsiType.substring(0, colon);
-               xsiTypeLocal = xsiType.substring(colon + 1);
-            }
-
-            String xsiTypeNs = nsRegistry.getNamespaceURI(xsiTypePrefix);
-            QName xsiTypeQName = new QName(xsiTypeNs, xsiTypeLocal);
-
-            TypeBinding xsiTypeBinding = schemaBinding.getType(xsiTypeQName);
-            if(xsiTypeBinding == null)
-            {
-               throw new JBossXBRuntimeException("Type binding not found for type " +
-                  xsiTypeQName +
-                  " specified with xsi:type for element " + startName
-               );
-            }
-
-            element = new ElementBinding(schemaBinding, startName, xsiTypeBinding);
-            particle =
-               new ParticleBinding(element,
-                  particle.getMinOccurs(),
-                  particle.getMaxOccurs(),
-                  particle.getMaxOccursUnbounded()
-               );
-         }
-
-         if(!repeated && particle.isRepeatable())
-         {
-            startRepeatableParticle(startName, particle);
-         }
-
-         TypeBinding type = element.getType();
-         if(type == null)
-         {
-            throw new JBossXBRuntimeException("No type for element " + element);
-         }
-
-         handler = type.getHandler();
-         if(handler == null)
-         {
-            handler = defParticleHandler;
-         }
-
-         List interceptors = element.getInterceptors();
-         if(!interceptors.isEmpty())
-         {
-            if (repeated)
-            {
-               pop();
-            }
-
-            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);
-               interceptor.attributes(parent, startName, type, atts, nsRegistry);
-            }
-
-            if (repeated)
-            {
-               // to have correct endRepeatableParticle calls
-               stack.push(item);
-            }
-         }
-
-         String nil = atts.getValue("xsi:nil");
-         if(nil == null || !("1".equals(nil) || "true".equals(nil)))
-         {
-            o = handler.startParticle(parent, startName, particle, atts, nsRegistry);
-         }
-         else
-         {
-            o = NIL;
-         }
-      }
-      else
-      {
-         ElementBinding parentBinding = null;
-         if(!stack.isEmpty())
-         {
-            ParticleBinding stackParticle = repeated ? stack.peek(1).particle : stack.peek().particle;
-            if(stackParticle != null)
-            {
-               parentBinding = (ElementBinding)stackParticle.getTerm();
-            }
-         }
-
-         if(parentBinding != null && parentBinding.getSchema() != null)
-         {
-            schemaBinding = parentBinding.getSchema();
-         }
-
-         String msg = "Element " +
-            startName +
-            " is not bound " +
-            (parentBinding == null ? "as a global element." : "in type " + parentBinding.getType().getQName());
-         if(schemaBinding != null && schemaBinding.isStrictSchema())
-         {
-            throw new JBossXBRuntimeException(msg);
-         }
-         else if(trace)
-         {
-            log.trace(msg);
-         }
-      }
-
-      if(repeated)
-      {
-         item.o = o;
-      }
-      else
-      {
-         push(startName, particle, o, handler);
-      }
-   }
-
-   private ParticleHandler getHandler(ParticleBinding modelGroupParticle)
-   {
-      ParticleHandler handler = ((ModelGroupBinding)modelGroupParticle.getTerm()).getHandler();
-      return handler == null ? defParticleHandler : handler;
-   }
-
-   private void endRepeatableParent(QName startName)
-   {
-      int parentPos = 1;
-      StackItem parentItem;
-      ParticleBinding parentParticle = null;
-      while(true)
-      {
-         parentItem = stack.peek(parentPos);
-         if(parentItem.cursor == null)
-         {
-            throw new JBossXBRuntimeException(
-               "Failed to start " + startName +
-               ": the element is not repeatable, repeatable parent expected to be a model group but got element " +
-               ((ElementBinding)parentItem.particle.getTerm()).getQName()
-            );
-         }
-
-         parentParticle = parentItem.particle;
-         if(parentParticle.isRepeatable())
-         {
-            break;
-         }
-
-         endParticle(parentItem, startName, ++parentPos);
-      }
-
-      if(!parentParticle.isRepeatable())
-      {
-         StringBuffer msg = new StringBuffer();
-
-         StackItem item = stack.peek();
-         ParticleBinding currentParticle = item.particle;
-         msg.append("Failed to start ").append(startName).append(": ")
-            .append(currentParticle.getTerm())
-            .append(" is not repeatable.")
-            .append(" Its parent ")
-            .append(parentParticle.getTerm())
-            .append(" expected to be repeatable!")
-            .append("\ncurrent stack: ");
-
-         for(int i = stack.size() - 1; i >= 0; --i)
-         {
-            item = stack.peek(i);
-            ParticleBinding particle = item.particle;
-            TermBinding term = particle.getTerm();
-            if(term.isModelGroup())
-            {
-               if(term instanceof SequenceBinding)
-               {
-                  msg.append("sequence");
-               }
-               else if(term instanceof ChoiceBinding)
-               {
-                  msg.append("choice");
-               }
-               else
-               {
-                  msg.append("all");
-               }
-            }
-            else if(term.isWildcard())
-            {
-               msg.append("wildcard");
-            }
-            else
-            {
-               msg.append(((ElementBinding)term).getQName());
-            }
-            msg.append("\\");
-         }
-
-         throw new JBossXBRuntimeException(msg.toString());
-      }
-
-      // todo startName is wrong here
-      endParticle(parentItem, startName, parentPos + 1);
-
-      parentItem = stack.peek(parentPos + 1);
-      while(parentPos > 0)
-      {
-         StackItem item = stack.peek(parentPos--);
-         ParticleHandler handler = getHandler(item.particle);
-         item.reset();
-         item.o = handler.startParticle(parentItem.o, startName, item.particle, null, nsRegistry);
-         parentItem = item;
-      }
-   }
-
-   private void startRepeatableParticle(QName startName, ParticleBinding particle)
-   {
-      //System.out.println(" start repeatable (" + stack.size() + "): " + particle.getTerm());
-      
-      TermBinding term = particle.getTerm();
-      if(term.isSkip())
-      {
-         return;
-      }
-      
-      StackItem item = stack.peek();
-      if(item.o != null &&
-            !(item.o instanceof GenericValueContainer) &&
-            term.getAddMethodMetaData() == null &&
-            term.getMapEntryMetaData() == null &&
-            term.getPutMethodMetaData() == null)
-      {
-         ValueListHandler handler = ValueListHandler.FACTORY.lazy(item.o);
-         Class cls = item.o.getClass();
-         item.repeatableParticleValue = new ValueListInitializer().newValueList(handler, cls);
-      }
-   }
-
-   private void endRepeatableParticle(ParticleBinding particle)
-   {
-      //System.out.println(" end repeatable (" + stack.size() + "): " + particle.getTerm());
-
-      StackItem item = stack.peek();
-      ValueList valueList = item.repeatableParticleValue;
-      if(valueList != null)
-      {
-         item.repeatableParticleValue = null;
-         if(valueList.size() == 0)
-         {
-            return;
-         }
-            
-         if(particle.getTerm().isWildcard())
-         {
-            ParticleHandler handler = ((WildcardBinding)particle.getTerm()).getWildcardHandler();
-            if(handler == null)
-            {
-               handler = defParticleHandler;
-            }
-
-            // that's not good. some elements can be handled as "unresolved" and some as "resolved"
-            QName qName = valueList.getValue(0).qName;
-            Collection col = new ArrayList();
-            for(int i = 0; i < valueList.size(); ++i)
-            {
-               col.add(valueList.getValue(i).value);
-            }
-            StackItem parentItem = stack.peek(1);
-            handler.setParent(parentItem.o, col, qName, particle, parentItem.particle);
-         }
-         else
-         {
-            valueList.getHandler().newInstance(particle, valueList);
-         }
-      }
-   }
-
-   private void endParticle(StackItem item, QName qName, int parentStackPos)
-   {
-      if(item.ended)
-      {
-         throw new JBossXBRuntimeException(item.particle.getTerm() + " has already been ended.");
-      }
-
-      ParticleBinding modelGroupParticle = item.particle;
-      ParticleHandler handler = item.handler;//getHandler(modelGroupParticle);
-
-      Object o;
-      if(item.o instanceof ValueList && !modelGroupParticle.getTerm().isSkip())
-      {
-         if(trace)
-         {
-            log.trace("endParticle " + modelGroupParticle.getTerm() + " valueList");
-         }
-         ValueList valueList = (ValueList)item.o;
-         o = valueList.getHandler().newInstance(modelGroupParticle, valueList);
-      }
-      else
-      {
-         o = handler.endParticle(item.o, qName, modelGroupParticle);
-      }
-
-      item.ended = true;
-
-      // model group should always have parent particle
-      item = (StackItem)stack.peek(parentStackPos);
-      if(item.o != null)
-      {
-         ParticleBinding parentParticle = item.particle;
-         if(parentParticle == null)
-         {
-            parentParticle = item.particle;
-         }
-         setParent(handler,
-               item.repeatableParticleValue == null ? item.o : item.repeatableParticleValue,
-               o, qName, modelGroupParticle, parentParticle);
-      }
-   }
-
-   public void startPrefixMapping(String prefix, String uri)
-   {
-      nsRegistry.addPrefixMapping(prefix, uri);
-   }
-
-   public void endPrefixMapping(String prefix)
-   {
-      nsRegistry.removePrefixMapping(prefix);
-   }
-
-   public void processingInstruction(String target, String data)
-   {
-   }
-
-   public Object getRoot()
-   {
-      return root;
-   }
-
-   // Private
-
-   private void endElement()
-   {
-      StackItem item = stack.peek();
-      Object o = item.o;
-      ParticleBinding particle = item.particle;
-      
-      ElementBinding element = (ElementBinding)particle.getTerm();
-      QName endName = element.getQName();
-      TypeBinding type = element.getType();
-      List interceptors = element.getInterceptors();
-      int interceptorsTotal = interceptors.size();
-
-      if(o != NIL)
-      {
-         //
-         // characters
-         //
-
-         TypeBinding charType = type.getSimpleType();
-         if(charType == null)
-         {
-            charType = type;
-         }
-
-         CharactersHandler charHandler = item.cHandler == null ? charType.getCharactersHandler() : item.cHandler;
-
-         /**
-          * If there is text content then unmarshal it and set.
-          * If there is no text content and the type is simple and
-          * its characters handler is not null then unmarshal and set.
-          * If the type is complex and there is no text data then the unmarshalled value
-          * of the empty text content is assumed to be null
-          * (in case of simple types that's not always true and depends on nillable attribute).
-          */
-         String textContent = item.textContent == null ? "" : item.textContent.toString();
-         if(textContent.length() > 0 || charHandler != null && type.isSimple())
-         {
-            String dataContent;
-            SchemaBinding schema = element.getSchema();
-            if(textContent.length() == 0)
-            {
-               dataContent = null;
-            }
-            else
-            {
-               dataContent = textContent.toString();
-               if(schema != null && schema.isReplacePropertyRefs())
-               {
-                  dataContent = StringPropertyReplacer.replaceProperties(dataContent);
-               }
-            }
-
-            Object unmarshalled;
-
-            if(charHandler == null)
-            {
-               if(!type.isSimple() &&
-                  schema != null &&
-                  schema.isStrictSchema()
-                  // todo this isSkip() doesn't look nice here
-                  && !element.isSkip())
-               {
-                  throw new JBossXBRuntimeException("Element " +
-                     endName +
-                     " with type binding " +
-                     type.getQName() +
-                     " does not include text content binding: " + dataContent
-                  );
-               }
-               unmarshalled = dataContent;
-            }
-            else
-            {
-               ValueMetaData valueMetaData = element.getValueMetaData();
-               if(valueMetaData == null)
-               {
-                  CharactersMetaData charactersMetaData = type.getCharactersMetaData();
-                  if(charactersMetaData != null)
-                  {
-                     valueMetaData = charactersMetaData.getValue();
-                  }
-               }
-
-               // todo valueMetaData is available from type
-               unmarshalled = dataContent == null ?
-                  charHandler.unmarshalEmpty(endName, charType, nsRegistry, valueMetaData) :
-                  charHandler.unmarshal(endName, charType, nsRegistry, valueMetaData, dataContent);
-            }
-
-            if(unmarshalled != null)
-            {
-               // if startElement returned null, we use characters as the object for this element
-               if(o == null)
-               {
-                  o = unmarshalled;
-               }
-               else if(charHandler != null)
-               {
-                  if(o instanceof ValueList)
-                  {
-                     ValueList valueList = (ValueList)o;
-                     if(type.isSimple())
-                     {
-                        valueList.getInitializer().addTermValue(endName,
-                           particle,
-                           charHandler,
-                           valueList,
-                           unmarshalled,
-                           null
-                        );
-                     }
-                     else
-                     {
-                        valueList.getInitializer().addTextValue(endName,
-                           particle,
-                           charHandler,
-                           valueList,
-                           unmarshalled
-                        );
-                     }
-                  }
-                  else
-                  {
-                     charHandler.setValue(endName, element, o, unmarshalled);
-                  }
-               }
-            }
-
-            for(int i = interceptorsTotal - 1; i >= 0; --i)
-            {
-               ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-               interceptor.characters(((StackItem)stack.peek(interceptorsTotal - i)).o,
-                  endName, type, nsRegistry, dataContent
-               );
-            }
-         }
-      }
-      else
-      {
-         o = null;
-      }
-
-      //
-      // endElement
-      //
-
-      StackItem parentItem = stack.size() == 1 ? null : stack.peek(1);
-      Object parent = parentItem == null ? null : parentItem.o;
-      ParticleHandler handler = stack.peek().handler;
-      
-      if(o instanceof ValueList && !particle.getTerm().isSkip())
-      {
-         if(trace)
-         {
-            log.trace("endParticle " + endName + " valueList");
-         }
-         ValueList valueList = (ValueList)o;
-         o = valueList.getHandler().newInstance(particle, valueList);
-      }
-      else
-      {
-         o = handler.endParticle(o, endName, particle);
-      }
-
-      for(int i = interceptorsTotal - 1; i >= 0; --i)
-      {
-         ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-         interceptor.endElement(((StackItem)stack.peek(interceptorsTotal - i)).o, endName, type);
-      }
-
-      //
-      // setParent
-      //
-
-      if(interceptorsTotal == 0)
-      {
-         ParticleHandler wildcardHandler = null;
-
-         ParticleBinding parentParticle = null;
-         ListIterator iter = stack.prevIterator();
-         while(iter.hasPrevious())
-         {
-            StackItem prev = (StackItem)iter.previous();
-            ParticleBinding peeked = prev.particle;
-            if(peeked != null && peeked.getTerm() instanceof ElementBinding)
-            {
-               parentParticle = peeked;
-               WildcardBinding wildcard = ((ElementBinding)parentParticle.getTerm()).getType().getWildcard();
-               if(wildcard != null)
-               {
-                  wildcardHandler = wildcard.getWildcardHandler();
-               }
-               break;
-            }
-         }
-
-         if(parent != null)
-         {
-            /*if(o == null)
-            {
-               throw new JBossXBRuntimeException(endName + " is null!");
-            } */
-            if(wildcardHandler != null)
-            {
-               setParent(wildcardHandler,
-                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
-                     o, endName, particle, parentParticle);
-            }
-            else
-            {
-               setParent(handler,
-                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
-                     o, endName, particle, parentParticle);
-            }
-         }
-         else if(parentParticle != null &&
-            ((ElementBinding)parentParticle.getTerm()).getType().hasWildcard() &&
-            stack.size() > 1)
-         {
-            // the parent has anyType, so it gets the value of its child
-            iter = stack.prevIterator();
-            while(iter.hasPrevious())
-            {
-               StackItem peeked = (StackItem)iter.previous();
-               peeked.o = o;
-               if(peeked.cursor == null)
-               {
-                  break;
-               }
-            }
-
-            if(trace)
-            {
-               log.trace("Value of " + endName + " " + o + " is promoted as the value of its parent element.");
-            }
-         }
-      }
-      else
-      {
-         StackItem popped = pop();
-         for(int i = interceptorsTotal - 1; i >= 0; --i)
-         {
-            ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-            parent = pop().o;
-            interceptor.add(parent, o, endName);
-            o = parent;
-         }
-         // need to have correst endRepeatableParticle events
-         stack.push(popped);
-      }
-
-      if(stack.size() == 1)
-      {
-         root = o;
-         stack.clear();
-      }
-   }
-
-   private void setParent(ParticleHandler handler,
-                          Object parent,
-                          Object o,
-                          QName endName,
-                          ParticleBinding particle,
-                          ParticleBinding parentParticle)
-   {
-      if(parent instanceof ValueList /*&& !particle.getTerm().isSkip()*/)
-      {
-         if(parent == o)
-         {            
-            return;
-         }
-         ValueList valueList = (ValueList)parent;
-         valueList.getInitializer().addTermValue(endName, particle, handler, valueList, o, parentParticle);
-      }
-      else
-      {
-         handler.setParent(parent, o, endName, particle, parentParticle);
-      }
-   }
-
-   private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler)
-   {
-      StackItem item = new StackItem(particle, o, handler);
-      stack.push(item);
-      if(trace)
-      {
-         Object binding = null;
-         if(particle != null)
-         {
-            binding = particle.getTerm();
-         }
-         log.trace("pushed " + qName + "=" + o + ", binding=" + binding);
-      }
-   }
-
-   private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
-   {
-      StackItem item = new StackItem(cursor, o, handler);
-      stack.push(item);
-      if(trace)
-      {
-         log.trace("pushed cursor " + cursor + ", o=" + o);
-      }
-   }
-
-   private StackItem pop()
-   {
-      StackItem item = stack.pop();
-      if(trace)
-      {
-         if(item.cursor == null)
-         {
-            log.trace("poped " + ((ElementBinding)item.particle.getTerm()).getQName() + "=" + item.particle);
-         }
-         else
-         {
-            log.trace("poped " + item.cursor.getCurrentParticle().getTerm());
-         }
-      }
-      return item;
-   }
-
-   // Inner
-
-   private static class StackItem
-   {
-      final ModelGroupBinding.Cursor cursor;
-      final ParticleBinding particle;
-      ParticleHandler handler;
-      CharactersHandler cHandler;
-      Object o;
-      ValueList repeatableParticleValue;
-      StringBuffer textContent;
-      boolean ended;
-
-      public StackItem(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
-      {
-         // 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)
-      {
-         // this is element particle
-         this.cursor = null;
-         this.particle = particle;
-         this.o = o;
-         this.handler = handler;
-      }
-
-      void reset()
-      {
-         if(!ended)
-         {
-            throw new JBossXBRuntimeException(
-               "Attempt to reset a particle that has already been reset: " + particle.getTerm()
-            );
-         }
-
-         ended = false;
-         o = null;
-         if(textContent != null)
-         {
-            textContent.delete(0, textContent.length());
-         }
-      }
-   }
-
-   static class StackImpl
-   {
-      private List list = new ArrayList();
-
-      public void clear()
-      {
-         list.clear();
-      }
-
-      public void push(Object o)
-      {
-         list.add(o);
-      }
-
-      public StackItem pop()
-      {
-         return (StackItem)list.remove(list.size() - 1);
-      }
-
-      public ListIterator prevIterator()
-      {
-         return list.listIterator(list.size() - 1);
-      }
-
-      public StackItem peek()
-      {
-         return (StackItem)list.get(list.size() - 1);
-      }
-
-      public StackItem peek(int i)
-      {
-         return (StackItem)list.get(list.size() - 1 - i);
-      }
-
-      public boolean isEmpty()
-      {
-         return list.isEmpty();
-      }
-
-      public int size()
-      {
-         return list.size();
-      }
-   }
-}

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-09-25 15:18:16 UTC (rev 2062)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2006-09-25 15:37:19 UTC (rev 2063)
@@ -22,23 +22,29 @@
 package org.jboss.xb.binding.sunday.unmarshalling;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.ListIterator;
 import javax.xml.namespace.QName;
 import org.apache.xerces.xs.XSTypeDefinition;
 import org.jboss.logging.Logger;
 import org.jboss.util.StringPropertyReplacer;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.GenericValueContainer;
 import org.jboss.xb.binding.JBossXBRuntimeException;
 import org.jboss.xb.binding.NamespaceRegistry;
 import org.jboss.xb.binding.Util;
 import org.jboss.xb.binding.group.ValueList;
+import org.jboss.xb.binding.group.ValueListHandler;
+import org.jboss.xb.binding.group.ValueListInitializer;
 import org.jboss.xb.binding.metadata.CharactersMetaData;
 import org.jboss.xb.binding.metadata.ValueMetaData;
 import org.jboss.xb.binding.parser.JBossXBParser;
+import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
 import org.xml.sax.Attributes;
 
 /**
- * The default content handler.
+ * ContentHandler that is used as a sandbox for JBXB-76
  *
  * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
  * @version <tt>$Revision$</tt>
@@ -114,7 +120,18 @@
          }
          else
          {
-            endParticle(item, endName, 1);
+            if(!item.ended) // could be ended if it's a choice
+            {
+               endParticle(item, endName, 1);
+            }
+
+            ParticleBinding currentParticle = item.cursor.getCurrentParticle();
+            TermBinding term = currentParticle.getTerm();
+            if(term.isWildcard() && currentParticle.isRepeatable())
+            {
+               endRepeatableParticle(currentParticle);
+            }
+
             pop();
             if(item.particle.isRepeatable())
             {
@@ -136,7 +153,7 @@
          );
       }
 
-      endElement(item.o, item.particle, item.textContent == null ? "" : item.textContent.toString());
+      endElement();
    }
 
    public void startElement(String namespaceURI,
@@ -147,7 +164,9 @@
    {
       QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
       ParticleBinding particle = null;
+      ParticleHandler handler = null;
       boolean repeated = false;
+      boolean repeatedParticle = false;
       StackItem item = null;
       ModelGroupBinding.Cursor cursor = null; // used only when particle is a wildcard
       SchemaBinding schemaBinding = schema;
@@ -196,7 +215,7 @@
                   }
                   else
                   {
-                     pop();
+                     pop();                     
                      if(item.particle.isRepeatable())
                      {
                         endRepeatableParticle(item.particle);
@@ -212,6 +231,32 @@
                      (ModelGroupBinding)typeParticle.getTerm();
                   if(modelGroup == null)
                   {
+                     if(startName.equals(Constants.QNAME_XOP_INCLUDE))
+                     {
+                        TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
+                        if(anyUriType == null)
+                        {
+                           log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
+                        }
+
+                        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()));
+
+                        ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
+
+                        particle = new ParticleBinding(xopInclude);
+                        
+                        ElementBinding parentElement = (ElementBinding) stack.peek().particle.getTerm();
+                        parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
+                        
+                        item.handler = DefaultHandlers.XOP_HANDLER;
+                        item.cHandler = CharactersHandler.NOOP;
+                        item.o = item.handler.startParticle(stack.peek().o, startName, stack.peek().particle, null, nsRegistry);
+                        break;
+                     }
+
                      QName typeName = element.getType().getQName();
                      throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
                         " type of element " +
@@ -243,9 +288,9 @@
                            startRepeatableParticle(startName, modelGroupParticle);
                         }
 
-                        ParticleHandler handler = getHandler(modelGroupParticle);
+                        handler = getHandler(modelGroupParticle);
                         o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                        push(cursor, o);
+                        push(cursor, o, handler);
                      }
                      particle = cursor.getCurrentParticle();
                   }
@@ -261,10 +306,13 @@
                }
 
                // todo review
-               if(cursor.isPositioned() && cursor.getParticle().getTerm() instanceof ChoiceBinding)
+               if(!item.ended && cursor.isPositioned() && cursor.getParticle().getTerm() instanceof ChoiceBinding)
                {
                   endParticle(item, startName, 1);
-                  pop();
+                  if(!item.particle.isRepeatable()) // this is for repeatable choices that should stay on the stack
+                  {
+                     pop();
+                  }
                   continue;
                }
 
@@ -273,11 +321,26 @@
                List newCursors = cursor.startElement(startName, atts);
                if(newCursors.isEmpty())
                {
-                  endParticle(item, startName, 1);
+                  if(!item.ended) // this is for choices
+                  {
+                     endParticle(item, startName, 1);
+                  }
                   pop();
                }
                else
                {
+                  if(item.ended) // for repeatable choices
+                  {
+                     if(!item.particle.isRepeatable())
+                     {
+                        throw new JBossXBRuntimeException("The particle expected to be repeatable but it's not: " + item.particle.getTerm());
+                     }
+                     item.reset();
+                     
+                     handler = getHandler(item.particle);
+                     item.o = handler.startParticle(stack.peek(1).o, startName, item.particle, atts, nsRegistry);
+                  }
+                  
                   ParticleBinding curParticle = cursor.getCurrentParticle();
                   if(curParticle != prevParticle)
                   {
@@ -291,20 +354,10 @@
                         startRepeatableParticle(startName, curParticle);
                      }
                   }
-
-/*
-                  if(cursor.getOccurence() - prevOccurence > 0 || item.ended)
+                  else
                   {
-                     endParticle(item, startName, 1);
-
-                     ParticleBinding modelGroupParticle = cursor.getParticle();
-                     ParticleHandler handler = getHandler(modelGroupParticle);
-                     Object o = handler.startParticle(stack.peek(1).o, startName, modelGroupParticle, atts, nsRegistry);
-
-                     item.reset();
-                     item.o = o;
+                     repeatedParticle = true;
                   }
-*/
 
                   // push all except the last one
                   Object o = item.o;
@@ -313,9 +366,9 @@
                      cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
 
                      ParticleBinding modelGroupParticle = cursor.getParticle();
-                     ParticleHandler handler = getHandler(modelGroupParticle);
+                     handler = getHandler(modelGroupParticle);
                      o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                     push(cursor, o);
+                     push(cursor, o, handler);
                   }
                   cursor = (ModelGroupBinding.Cursor)newCursors.get(0);
                   particle = cursor.getCurrentParticle();
@@ -344,12 +397,11 @@
                );
             }
 
-            particle =
-               new ParticleBinding(element,
-                  particle.getMinOccurs(),
-                  particle.getMaxOccurs(),
-                  particle.getMaxOccursUnbounded()
-               );
+            if(!repeatedParticle && particle.isRepeatable())
+            {
+               startRepeatableParticle(startName, particle);
+            }
+            particle = new ParticleBinding(element/*, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded()*/);
          }
 
          ElementBinding element = (ElementBinding)particle.getTerm();
@@ -409,19 +461,33 @@
             throw new JBossXBRuntimeException("No type for element " + element);
          }
 
-         List interceptors = element.getInterceptors();
-         for(int i = 0; i < interceptors.size(); ++i)
+         handler = type.getHandler();
+         if(handler == null)
          {
-            ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-            parent = interceptor.startElement(parent, startName, type);
-            push(startName, particle, parent);
-            interceptor.attributes(parent, startName, type, atts, nsRegistry);
+            handler = defParticleHandler;
          }
 
-         ParticleHandler handler = type.getHandler();
-         if(handler == null)
+         List interceptors = element.getInterceptors();
+         if(!interceptors.isEmpty())
          {
-            handler = defParticleHandler;
+            if (repeated)
+            {
+               pop();
+            }
+
+            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);
+               interceptor.attributes(parent, startName, type, atts, nsRegistry);
+            }
+
+            if (repeated)
+            {
+               // to have correct endRepeatableParticle calls
+               stack.push(item);
+            }
          }
 
          String nil = atts.getValue("xsi:nil");
@@ -471,7 +537,7 @@
       }
       else
       {
-         push(startName, particle, o);
+         push(startName, particle, o, handler);
       }
    }
 
@@ -492,7 +558,8 @@
          if(parentItem.cursor == null)
          {
             throw new JBossXBRuntimeException(
-               "Repeatable parent expected to be a model group but got element: " +
+               "Failed to start " + startName +
+               ": the element is not repeatable, repeatable parent expected to be a model group but got element " +
                ((ElementBinding)parentItem.particle.getTerm()).getQName()
             );
          }
@@ -570,76 +637,64 @@
 
    private void startRepeatableParticle(QName startName, ParticleBinding particle)
    {
-      //System.out.println(" start repeatable particle: " + particle.getTerm());
-/*
-      StackItem item = stack.peek();
-
-      TermBinding parentTerm = item.particle.getTerm();
-      WildcardBinding wc = null;
-      if(parentTerm.isWildcard())
+      //System.out.println(" start repeatable (" + stack.size() + "): " + particle.getTerm());
+      
+      TermBinding term = particle.getTerm();
+      if(term.isSkip())
       {
-         wc = (WildcardBinding)parentTerm;
+         return;
       }
-      else if(!parentTerm.isModelGroup())
+      
+      StackItem item = stack.peek();
+      if(item.o != null &&
+            !(item.o instanceof GenericValueContainer) &&
+            term.getAddMethodMetaData() == null &&
+            term.getMapEntryMetaData() == null &&
+            term.getPutMethodMetaData() == null)
       {
-         ElementBinding el = (ElementBinding)parentTerm;
-         wc = el.getType().getWildcard();
-         if(wc != null && el.getType().getElement(startName) != null)
-         {
-            wc = null;
-         }
+         ValueListHandler handler = ValueListHandler.FACTORY.lazy(item.o);
+         Class cls = item.o.getClass();
+         item.repeatableParticleValue = new ValueListInitializer().newValueList(handler, cls);
       }
-
-      TermBinding term = particle.getTerm();
-      if(term.getAddMethodMetaData() != null ||
-         wc != null && wc.getAddMethodMetaData() != null ||
-         term.getPutMethodMetaData() != null ||
-         term.getMapEntryMetaData() != null)
-      {
-         return;
-      }
-
-      item.tmp = item.o;
-      item.o = new ArrayList();
-      item.repeatbleParticleName = startName;
-
-*/
    }
 
    private void endRepeatableParticle(ParticleBinding particle)
    {
-      //System.out.println(" end repeatable particle: " + particle.getTerm());
+      //System.out.println(" end repeatable (" + stack.size() + "): " + particle.getTerm());
 
-/*
       StackItem item = stack.peek();
-      if(item.repeatbleParticleName == null)
+      ValueList valueList = item.repeatableParticleValue;
+      if(valueList != null)
       {
-         return;
-      }
+         item.repeatableParticleValue = null;
+         if(valueList.size() == 0)
+         {
+            return;
+         }
+            
+         if(particle.getTerm().isWildcard())
+         {
+            ParticleHandler handler = ((WildcardBinding)particle.getTerm()).getWildcardHandler();
+            if(handler == null)
+            {
+               handler = defParticleHandler;
+            }
 
-      TermBinding term = particle.getTerm();
-      ParticleHandler handler = null;
-      if(term.isModelGroup())
-      {
-         handler = getHandler(particle);
-      }
-      else
-      {
-         ElementBinding el = (ElementBinding)term;
-         handler = el.getType().getHandler();
-         if(handler == null)
+            // that's not good. some elements can be handled as "unresolved" and some as "resolved"
+            QName qName = valueList.getValue(0).qName;
+            Collection col = new ArrayList();
+            for(int i = 0; i < valueList.size(); ++i)
+            {
+               col.add(valueList.getValue(i).value);
+            }
+            StackItem parentItem = stack.peek(1);
+            handler.setParent(parentItem.o, col, qName, particle, parentItem.particle);
+         }
+         else
          {
-            handler = defParticleHandler;
+            valueList.getHandler().newInstance(particle, valueList);
          }
-
       }
-
-      setParent(handler, item.tmp, item.o, item.repeatbleParticleName, particle, item.particle);
-
-      item.o = item.tmp;
-      item.tmp = null;
-      item.repeatbleParticleName = null;
-*/
    }
 
    private void endParticle(StackItem item, QName qName, int parentStackPos)
@@ -650,7 +705,7 @@
       }
 
       ParticleBinding modelGroupParticle = item.particle;
-      ParticleHandler handler = getHandler(modelGroupParticle);
+      ParticleHandler handler = item.handler;//getHandler(modelGroupParticle);
 
       Object o;
       if(item.o instanceof ValueList && !modelGroupParticle.getTerm().isSkip())
@@ -678,7 +733,9 @@
          {
             parentParticle = item.particle;
          }
-         setParent(handler, item.o, o, qName, modelGroupParticle, parentParticle);
+         setParent(handler,
+               item.repeatableParticleValue == null ? item.o : item.repeatableParticleValue,
+               o, qName, modelGroupParticle, parentParticle);
       }
    }
 
@@ -703,8 +760,12 @@
 
    // Private
 
-   private void endElement(Object o, ParticleBinding particle, String textContent)
+   private void endElement()
    {
+      StackItem item = stack.peek();
+      Object o = item.o;
+      ParticleBinding particle = item.particle;
+      
       ElementBinding element = (ElementBinding)particle.getTerm();
       QName endName = element.getQName();
       TypeBinding type = element.getType();
@@ -723,7 +784,7 @@
             charType = type;
          }
 
-         CharactersHandler charHandler = charType.getCharactersHandler();
+         CharactersHandler charHandler = item.cHandler == null ? charType.getCharactersHandler() : item.cHandler;
 
          /**
           * If there is text content then unmarshal it and set.
@@ -733,6 +794,7 @@
           * of the empty text content is assumed to be null
           * (in case of simple types that's not always true and depends on nillable attribute).
           */
+         String textContent = item.textContent == null ? "" : item.textContent.toString();
          if(textContent.length() > 0 || charHandler != null && type.isSimple())
          {
             String dataContent;
@@ -844,13 +906,10 @@
       // endElement
       //
 
-      Object parent = stack.size() == 1 ? null : ((StackItem)stack.peek(1)).o;
-      ParticleHandler handler = type.getHandler();
-      if(handler == null)
-      {
-         handler = defParticleHandler;
-      }
-
+      StackItem parentItem = stack.size() == 1 ? null : stack.peek(1);
+      Object parent = parentItem == null ? null : parentItem.o;
+      ParticleHandler handler = stack.peek().handler;
+      
       if(o instanceof ValueList && !particle.getTerm().isSkip())
       {
          if(trace)
@@ -883,8 +942,8 @@
          ListIterator iter = stack.prevIterator();
          while(iter.hasPrevious())
          {
-            StackItem item = (StackItem)iter.previous();
-            ParticleBinding peeked = item.particle;
+            StackItem prev = (StackItem)iter.previous();
+            ParticleBinding peeked = prev.particle;
             if(peeked != null && peeked.getTerm() instanceof ElementBinding)
             {
                parentParticle = peeked;
@@ -905,11 +964,15 @@
             } */
             if(wildcardHandler != null)
             {
-               setParent(wildcardHandler, parent, o, endName, particle, parentParticle);
+               setParent(wildcardHandler,
+                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
+                     o, endName, particle, parentParticle);
             }
             else
             {
-               setParent(handler, parent, o, endName, particle, parentParticle);
+               setParent(handler,
+                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
+                     o, endName, particle, parentParticle);
             }
          }
          else if(parentParticle != null &&
@@ -936,7 +999,7 @@
       }
       else
       {
-         pop();
+         StackItem popped = pop();
          for(int i = interceptorsTotal - 1; i >= 0; --i)
          {
             ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
@@ -944,11 +1007,14 @@
             interceptor.add(parent, o, endName);
             o = parent;
          }
+         // need to have correst endRepeatableParticle events
+         stack.push(popped);
       }
 
       if(stack.size() == 1)
       {
          root = o;
+         stack.clear();
       }
    }
 
@@ -959,8 +1025,12 @@
                           ParticleBinding particle,
                           ParticleBinding parentParticle)
    {
-      if(parent instanceof ValueList && !particle.getTerm().isSkip())
+      if(parent instanceof ValueList /*&& !particle.getTerm().isSkip()*/)
       {
+         if(parent == o)
+         {            
+            return;
+         }
          ValueList valueList = (ValueList)parent;
          valueList.getInitializer().addTermValue(endName, particle, handler, valueList, o, parentParticle);
       }
@@ -970,9 +1040,9 @@
       }
    }
 
-   private void push(QName qName, ParticleBinding particle, Object o)
+   private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler)
    {
-      StackItem item = new StackItem(particle, o);
+      StackItem item = new StackItem(particle, o, handler);
       stack.push(item);
       if(trace)
       {
@@ -985,9 +1055,9 @@
       }
    }
 
-   private void push(ModelGroupBinding.Cursor cursor, Object o)
+   private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
    {
-      StackItem item = new StackItem(cursor, o);
+      StackItem item = new StackItem(cursor, o, handler);
       stack.push(item);
       if(trace)
       {
@@ -1018,26 +1088,29 @@
    {
       final ModelGroupBinding.Cursor cursor;
       final ParticleBinding particle;
+      ParticleHandler handler;
+      CharactersHandler cHandler;
       Object o;
-      //Object tmp;
-      //QName repeatbleParticleName;
+      ValueList repeatableParticleValue;
       StringBuffer textContent;
       boolean ended;
 
-      public StackItem(ModelGroupBinding.Cursor cursor, Object o)
+      public StackItem(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
       {
          // this is modelgroup particle
          this.cursor = cursor;
          this.particle = cursor.getParticle();
          this.o = o;
+         this.handler = handler;
       }
 
-      public StackItem(ParticleBinding particle, Object o)
+      public StackItem(ParticleBinding particle, Object o, ParticleHandler handler)
       {
          // this is element particle
          this.cursor = null;
          this.particle = particle;
          this.o = o;
+         this.handler = handler;
       }
 
       void reset()




More information about the jboss-svn-commits mailing list