[jboss-svn-commits] JBoss Common SVN: r3842 - in jbossxb/trunk: src/main/java/org/jboss/xb/binding/sunday/unmarshalling and 6 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Dec 11 06:24:25 EST 2009
Author: alex.loubyansky at jboss.com
Date: 2009-12-11 06:24:24 -0500 (Fri, 11 Dec 2009)
New Revision: 3842
Added:
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/PositionStack.java
jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/support/MyObject.java
jbossxb/trunk/src/test/resources/org/jboss/test/xb/builder/object/mc/test/DeploymentWithArrayOfJavaBeans.xml
Modified:
jbossxb/trunk/pom.xml
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/AbstractPosition.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/ElementPosition.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/NonElementPosition.java
jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/Position.java
jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/test/DeploymentTestCase.java
jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/repeatableterms/test/RepeatableTermsUnitTestCase.java
jbossxb/trunk/src/test/resources/org/jboss/test/xml/choiceresolution/test/Foo2BarSequenceOrBarUnitTestCase.xsd
Log:
move repeatableParticleValue from parent position to the actually repeatable position, move more position handling logic into specific position impl
Modified: jbossxb/trunk/pom.xml
===================================================================
--- jbossxb/trunk/pom.xml 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/pom.xml 2009-12-11 11:24:24 UTC (rev 3842)
@@ -57,6 +57,7 @@
<exclude>org/jboss/test/xml/RepeatedElementsUnitTestCase.java</exclude> <!-- JBXB-88 -->
<exclude>org/jboss/test/xb/builder/object/type/jbossxmlmodelgroup/test/RepeatablePropertyAllUnmarshallingTestCase.java</exclude> <!-- JBXB-193 -->
<exclude>org/jboss/test/xb/builder/object/type/jbossxmlmodelgroup/test/RepeatablePropertySequenceUnmarshallingTestCase.java</exclude> <!-- unordered sequence makes it JBXB-193 -->
+ <exclude>org/jboss/test/xb/builder/repeatableterms/test/RepeatableTermsUnitTestCase.java</exclude>
<!-- below are the tests that don't depend on the setting -->
<exclude>org/jboss/test/xb/validator/test/BasicBindingValidatorUnitTestCase.java</exclude>
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -106,16 +106,45 @@
protected Position startElement(QName qName, Attributes atts, boolean required)
{
- if(currentParticle != null && repeatTerm(qName, atts))
- throw new IllegalStateException("maxOccurs in all model group can only be 1: " + qName);
+ next = null;
- next = null;
+/* if(currentParticle != null)
+ {
+ if(particle.getMaxOccursUnbounded() ||
+ occurrence < particle.getMinOccurs() ||
+ occurrence < particle.getMaxOccurs())
+ {
+ ParticleBinding particle = elements.get(qName);
+ if(particle != null)
+ {
+ next = particle.getTerm().newPosition(qName, atts, particle);
+ ++occurrence;
+ currentParticle = particle;
+
+ endParticle();
+ o = initValue(stack.parent().getValue(), atts);
+ ended = false;
+
+ return this;
+ }
+ }
+
+ endParticle();
+ if(particle.isRepeatable() && repeatableParticleValue != null)
+ endRepeatableParticle(stack.parent());
+
+ currentParticle = null;
+ occurrence = 0;
+
+ return null;
+ }
+*/
ParticleBinding particle = elements.get(qName);
if(particle != null)
{
next = particle.getTerm().newPosition(qName, atts, particle);
+ ++occurrence;
currentParticle = particle;
- occurrence = 1;
return this;
}
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -93,11 +93,6 @@
private final class ChoicePosition extends NonElementPosition
{
- private ChoicePosition(QName name, ParticleBinding particle, ParticleBinding currentParticle)
- {
- super(name, particle, currentParticle);
- }
-
private ChoicePosition(QName name, ParticleBinding particle, ParticleBinding currentParticle, Position next)
{
super(name, particle, currentParticle, next);
@@ -116,10 +111,40 @@
if(currentParticle != null)
{
- if(repeatTerm(qName, atts))
- return this;
- else
- return null;
+ if(particle.getMaxOccursUnbounded() ||
+ occurrence < particle.getMinOccurs() ||
+ occurrence < particle.getMaxOccurs())
+ {
+ for(int i = 0; i < choices.size(); ++i)
+ {
+ ParticleBinding choice = (ParticleBinding)choices.get(i);
+ TermBinding term = choice.getTerm();
+ next = term.newPosition(qName, atts, choice);
+
+ if(next != null)
+ {
+ ++occurrence;
+ currentParticle = choice;
+
+ endParticle();
+ o = initValue(stack.parent().getValue(), atts);
+ ended = false;
+
+ if(trace)
+ log.trace("found " + qName + " in " + ChoiceBinding.this + ", term=" + currentParticle.getTerm());
+ return this;
+ }
+ }
+ }
+
+ endParticle();
+ if(particle.isRepeatable() && repeatableParticleValue != null)
+ endRepeatableParticle(stack.parent());
+
+ currentParticle = null;
+ occurrence = 0;
+
+ return null;
}
for(int i = 0; i < choices.size(); ++i)
Added: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/PositionStack.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/PositionStack.java (rev 0)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/PositionStack.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -0,0 +1,63 @@
+/*
+ * 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 javax.xml.namespace.QName;
+
+import org.jboss.xb.binding.NamespaceRegistry;
+import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.UnmarshallingContextImpl;
+import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: 3823 $</tt>
+ */
+public interface PositionStack
+{
+ void push(Position o);
+
+ void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler, TypeBinding parentType);
+
+ Position pop();
+
+ Position current();
+
+ Position parent();
+
+ Position parent(int i);
+
+ Position notSkippedParent();
+
+ Position notSkippedParent(int i);
+
+ boolean isEmpty();
+
+ int size();
+
+ void clear();
+
+ // TODO not realle stack methods
+
+ NamespaceRegistry getNamespaceRegistry();
+
+ UnmarshallingContextImpl getContext();
+}
\ No newline at end of file
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -26,6 +26,7 @@
import java.util.List;
import java.util.Collection;
import javax.xml.namespace.QName;
+
import org.jboss.xb.binding.JBossXBRuntimeException;
import org.jboss.xb.binding.sunday.unmarshalling.position.NonElementPosition;
import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
@@ -113,12 +114,6 @@
{
private int pos = -1;
- protected SequencePosition(QName qName, ParticleBinding particle, int pos, ParticleBinding currentParticle)
- {
- super(qName, particle, currentParticle);
- this.pos = pos;
- }
-
protected SequencePosition(QName qName, ParticleBinding particle, int pos, ParticleBinding currentParticle, Position next)
{
super(qName, particle, currentParticle, next);
@@ -136,12 +131,6 @@
next = null;
- // if positioned try repeating
- if(currentParticle != null && repeatTerm(qName, atts))
- return this;
-
- // this will be the first occurrence
-
int i = pos;
while(i < sequence.size() - 1)
{
@@ -151,27 +140,70 @@
if (next != null)
{
pos = i;
- occurrence = 1;
currentParticle = particle;
+ if(occurrence == 0)
+ occurrence = 1;
return this;
}
if (particle.isRequired())
{
if (required)
- {
throw new JBossXBRuntimeException("Requested element " + qName
+ " is not allowed in this position in the sequence. A model group with minOccurs="
+ particle.getMinOccurs() + " that doesn't contain this element must follow.");
- }
else
+ return null;
+ }
+ }
+
+ if(pos >= 0 && (particle.getMaxOccursUnbounded() ||
+ occurrence < particle.getMinOccurs() ||
+ occurrence < particle.getMaxOccurs()))
+ {
+ for(i = 0; i < sequence.size(); ++i)
+ {
+ ParticleBinding item = sequence.get(i);
+ TermBinding term = item.getTerm();
+ next = term.newPosition(qName, atts, item);
+
+ if(next != null)
{
- break;
+ pos = i;
+ ++occurrence;
+ currentParticle = item;
+
+ endParticle();
+ o = initValue(stack.parent().getValue(), atts);
+ ended = false;
+
+ if(trace)
+ log.trace("found " + qName + " in " + SequenceBinding.this);
+
+ return this;
}
+
+ if (particle.isRequired())
+ {
+ if (required)
+ throw new JBossXBRuntimeException("Requested element " + qName
+ + " is not allowed in this position in the sequence. A model group with minOccurs="
+ + particle.getMinOccurs() + " that doesn't contain this element must follow.");
+ else
+ return null;
+ }
}
}
- if(trace && i == sequence.size())
+ endParticle();
+ if(particle.isRepeatable() && repeatableParticleValue != null)
+ endRepeatableParticle(stack.parent());
+
+ currentParticle = null;
+ occurrence = 0;
+ pos = -1;
+
+ if(trace)
log.trace(qName + " not found in " + SequenceBinding.this);
return null;
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 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -23,7 +23,6 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import javax.xml.namespace.QName;
@@ -38,6 +37,7 @@
import org.jboss.xb.binding.metadata.PropertyMetaData;
import org.jboss.xb.binding.parser.JBossXBParser;
import org.jboss.xb.binding.resolver.MutableSchemaResolver;
+import org.jboss.xb.binding.sunday.unmarshalling.position.AbstractPosition;
import org.jboss.xb.binding.sunday.unmarshalling.position.ElementPosition;
import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
import org.xml.sax.Attributes;
@@ -56,6 +56,7 @@
public final static Object NIL = new Object();
private final SchemaBindingResolver schemaResolver;
+ private final SchemaBinding schema;
private final StackImpl stack = new StackImpl();
@@ -67,18 +68,23 @@
private String dtdSystemId;
private boolean sawDTD;
- private final boolean trace = log.isTraceEnabled();
+ private boolean trace = log.isTraceEnabled();
+ private UnmarshallingContextImpl ctx = new UnmarshallingContextImpl();
+ private NamespaceRegistry nsRegistry = new NamespaceRegistry();
+
public SundayContentHandler(SchemaBinding schema)
{
- this.stack.schema = schema;
+ this.schema = schema;
this.schemaResolver = null;
+ AbstractPosition.resetTrace();
}
public SundayContentHandler(SchemaBindingResolver schemaResolver)
{
this.schemaResolver = schemaResolver;
- this.stack.schema = null;
+ this.schema = null;
+ AbstractPosition.resetTrace();
}
@@ -95,19 +101,19 @@
public void characters(char[] ch, int start, int length)
{
- Position position = stack.peek();
+ Position position = stack.current();
if(!position.isElement())
return;
// if current is ended the characters belong to its parent
if(position.isEnded())
{
- position = stack.peek1();
+ position = stack.parent();
if(!position.isElement())
{
for(int i = stack.size() - 3; i >= 0; --i)
{
- position = stack.peek(i);
+ position = stack.parent(i);
if(position.isElement())
break;
}
@@ -123,17 +129,13 @@
Position position = null;
while(elementBinding == null && !stack.isEmpty())
{
- position = stack.peek();
+ position = stack.current();
if(position.isElement())
{
if(position.isEnded())
{
- if(position.getParticle().isRepeatable())
- {
- Position parentPosition = stack.peek1();
- if(parentPosition.getRepeatableParticleValue() != null)
- stack.endRepeatableParticle(parentPosition, position.getQName(), position.getParticle(), parentPosition.getParticle());
- }
+ if(position.getRepeatableParticleValue() != null)
+ position.endRepeatableParticle(stack.parent());
stack.pop();
}
else
@@ -155,13 +157,8 @@
else
{
position.endParticle();
-
- if(position.getParticle().isRepeatable())
- {
- Position parentPosition = stack.peek1();
- if(parentPosition.getRepeatableParticleValue() != null)
- stack.endRepeatableParticle(parentPosition, position.getQName(), position.getParticle(), parentPosition.getParticle());
- }
+ if(position.getRepeatableParticleValue() != null)
+ position.endRepeatableParticle(stack.parent());
stack.pop();
}
}
@@ -202,7 +199,7 @@
QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
boolean repeated = false;
Position position = null;
- SchemaBinding schemaBinding = stack.schema;
+ SchemaBinding schemaBinding = schema;
atts = preprocessAttributes(atts);
@@ -249,128 +246,28 @@
{
while(!stack.isEmpty())
{
- Position peek = stack.peek();
+ Position peek = stack.current();
position = peek.startParticle(startName, atts);
- if(position.isEnded())
+ if(!position.isEnded())
{
- stack.pop();
- }
- else
- {
repeated = position == peek;
break;
}
- }
- }
-
- ElementBinding element = (ElementBinding) position.getParticle().getTerm();
-
- // TODO xsi:type support should be implemented in a better way
- String xsiType = atts.getValue(Constants.NS_XML_SCHEMA_INSTANCE, "type");
- if (xsiType != null)
- {
- if (trace)
- log.trace(element.getQName() + " uses xsi:type " + xsiType);
-
- ElementPosition ep = (ElementPosition) position;
- if (ep != null && ep.getNonXsiParticle() == null)
- ep.setNonXsiParticle(position.getParticle());
-
- 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 = stack.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);
- }
-
- ElementBinding xsiElement = new ElementBinding(schemaBinding, startName, xsiTypeBinding);
- xsiElement.setRepeatableHandler(element.getRepeatableHandler());
-
- position.setParticle(
- new ParticleBinding(xsiElement, position.getParticle().getMinOccurs(),
- position.getParticle().getMaxOccurs(), position.getParticle().getMaxOccursUnbounded()));
- }
-
- Object parent = stack.isEmpty() ? null : (repeated ? stack.peek1().getValue() : stack.peek().getValue());
- if (!repeated && position.getParticle().isRepeatable())
- stack.startRepeatableParticle(stack.peek(), parent, startName, position.getParticle());
-
- TypeBinding type = element.getType();
- if (type == null)
- throw new JBossXBRuntimeException("No type for element " + element);
-
- ParticleHandler handler = type.getHandler();
- if (handler == null)
- handler = DefaultHandlers.ELEMENT_HANDLER;
- position.setHandler(handler);
-
- List<ElementInterceptor> localInterceptors = position.getParentType() == null
- ? Collections.EMPTY_LIST
- : position.getParentType().getInterceptors(startName);
- List<ElementInterceptor> interceptors = element.getInterceptors();
- if (interceptors.size() + localInterceptors.size() > 0)
- {
- if (repeated)
stack.pop();
-
- for (int i = 0; i < localInterceptors.size(); ++i)
- {
- ElementInterceptor interceptor = localInterceptors.get(i);
- parent = interceptor.startElement(parent, startName, type);
- push(startName, position.getParticle(), parent, position.getHandler(), position.getParentType());
- interceptor.attributes(parent, startName, type, atts, stack.nsRegistry);
}
-
- for (int i = 0; i < interceptors.size(); ++i)
- {
- ElementInterceptor interceptor = interceptors.get(i);
- parent = interceptor.startElement(parent, startName, type);
- push(startName, position.getParticle(), parent, position.getHandler(), position.getParentType());
- interceptor.attributes(parent, startName, type, atts, stack.nsRegistry);
- }
-
- if (repeated)
- {
- // to have correct endRepeatableParticle calls
- stack.push(position);
- }
}
- if (!repeated)
- stack.push(position);
-
- String nil = atts.getValue(Constants.NS_XML_SCHEMA_INSTANCE, "nil");
- if (nil == null || !("1".equals(nil) || "true".equals(nil)))
- position.initValue(parent, atts);
- else
- position.setValue(NIL);
+ ((ElementPosition)position).push(stack, atts, repeated);
}
public void startPrefixMapping(String prefix, String uri)
{
- stack.nsRegistry.addPrefixMapping(prefix, uri);
+ nsRegistry.addPrefixMapping(prefix, uri);
}
public void endPrefixMapping(String prefix)
{
- stack.nsRegistry.removePrefixMapping(prefix);
+ nsRegistry.removePrefixMapping(prefix);
}
public void processingInstruction(String target, String data)
@@ -386,7 +283,7 @@
private Attributes preprocessAttributes(Attributes attrs)
{
- SchemaBindingResolver resolver = schemaResolver == null ? stack.schema.getSchemaResolver() : schemaResolver;
+ SchemaBindingResolver resolver = schemaResolver == null ? schema.getSchemaResolver() : schemaResolver;
if(resolver == null || !(resolver instanceof MutableSchemaResolver))
return attrs;
@@ -423,31 +320,14 @@
return attrs;
}
- private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler, TypeBinding parentType)
- {
- ElementPosition position = new ElementPosition(qName, particle);
- position.setValue(o);
- position.setHandler(handler);
- position.setParentType(parentType);
- stack.push(position);
- if(trace)
- log.trace("pushed[" + (stack.size() - 1) + "] " + particle.getTerm().getQName() + "=" + o);
- }
-
// Inner
- public static class StackImpl
+ public class StackImpl implements PositionStack
{
- protected boolean trace = log.isTraceEnabled();
-
private List<Position> list = new ArrayList<Position>();
private Position head;
private Position peek1;
- public SchemaBinding schema;
- public UnmarshallingContextImpl ctx = new UnmarshallingContextImpl();
- public NamespaceRegistry nsRegistry = new NamespaceRegistry();
-
public void clear()
{
list.clear();
@@ -461,27 +341,39 @@
peek1 = head;
head = o;
o.setStack(this);
+ if(trace)
+ log.trace("pushed " + o.getParticle().getTerm());
}
+ public void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler, TypeBinding parentType)
+ {
+ ElementPosition position = new ElementPosition(qName, particle, o, handler, parentType);
+ push(position);
+ }
+
public Position pop()
{
head = peek1;
int index = list.size() - 1;
peek1 = index > 1 ? list.get(index - 2) : null;
- return list.remove(index);
+
+ Position popped = list.remove(index);
+ if(trace)
+ log.trace("popped " + popped.getParticle().getTerm());
+ return popped;
}
- public Position peek()
+ public Position current()
{
return head;
}
- public Position peek1()
+ public Position parent()
{
return peek1;
}
- public Position peek(int i)
+ public Position parent(int i)
{
return list.get(i);
}
@@ -496,7 +388,7 @@
return list.size();
}
- public Position getNotSkippedParent()
+ public Position notSkippedParent()
{
Position position = peek1;
if(position == null)
@@ -525,7 +417,7 @@
return wildcardPosition;
}
- public Position getNotSkippedParent(int i)
+ public Position notSkippedParent(int i)
{
Position position = null;
while(i >= 0)
@@ -538,32 +430,14 @@
return null;
}
- public void startRepeatableParticle(Position parentPosition, Object parent, QName startName, ParticleBinding particle)
+ public UnmarshallingContextImpl getContext()
{
- if(trace)
- log.trace(" start repeatable (" + size() + "): " + particle.getTerm());
-
- RepeatableParticleHandler repeatableHandler = particle.getTerm().getRepeatableHandler();
- // the way it is now it's never null
- Object repeatableContainer = repeatableHandler.startRepeatableParticle(parent, startName, particle);
- if(repeatableContainer != null)
- {
- if(parentPosition.getRepeatableParticleValue() != null)
- throw new IllegalStateException("Previous repeatable particle hasn't been ended yet!");
- parentPosition.setRepeatableParticleValue(repeatableContainer);
- parentPosition.setRepeatableHandler(repeatableHandler);
- }
+ return ctx;
}
- public void endRepeatableParticle(Position parentPosition, QName elementName, ParticleBinding particle, ParticleBinding parentParticle)
+ public NamespaceRegistry getNamespaceRegistry()
{
- if (trace)
- log.trace(" end repeatable (" + size() + "): " + particle.getTerm());
- RepeatableParticleHandler repeatableHandler = parentPosition.getRepeatableHandler();
- // the way it is now it's never null
- repeatableHandler.endRepeatableParticle(parentPosition.getValue(), parentPosition.getRepeatableParticleValue(), elementName, particle, parentParticle);
- parentPosition.setRepeatableParticleValue(null);
- parentPosition.setRepeatableHandler(null);
+ return nsRegistry;
}
}
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -133,11 +133,6 @@
private final class UnorderedSequencePosition extends NonElementPosition
{
- private UnorderedSequencePosition(QName name, ParticleBinding particle, ParticleBinding currentParticle)
- {
- super(name, particle, currentParticle);
- }
-
private UnorderedSequencePosition(QName name, ParticleBinding particle, ParticleBinding currentParticle, Position next)
{
super(name, particle, currentParticle, next);
@@ -153,16 +148,17 @@
log.trace(sb.toString());
}
+ boolean repeating = currentParticle != null;
+
next = null;
-
- if(currentParticle != null && repeatTerm(qName, atts))
- return this;
-
currentParticle = elementParticles.get(qName);
if (currentParticle != null)
{
next = currentParticle.getTerm().newPosition(qName, atts, currentParticle);
- occurrence = 1;
+ if(repeating)
+ ++occurrence;
+ else
+ occurrence = 1;
if (trace)
log.trace("found " + qName + " in " + UnorderedSequenceBinding.this);
return this;
@@ -174,7 +170,10 @@
if (next != null)
{
- occurrence = 1;
+ if(repeating)
+ ++occurrence;
+ else
+ occurrence = 1;
currentParticle = particle;
return this;
}
@@ -186,12 +185,25 @@
if (next != null)
{
- occurrence = 1;
+ if(repeating)
+ ++occurrence;
+ else
+ occurrence = 1;
currentParticle = particle;
return this;
}
}
+ if(repeating)
+ {
+ endParticle();
+ if(particle.isRepeatable() && repeatableParticleValue != null)
+ endRepeatableParticle(stack.parent());
+
+ currentParticle = null;
+ occurrence = 0;
+ }
+
return null;
}
}
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -308,9 +308,37 @@
protected Position startElement(QName name, Attributes atts, boolean required)
{
// if positioned try repeating
- if(currentParticle != null && repeatTerm(qName, atts))
- return this;
+ if(currentParticle != null)
+ {
+ if(particle.getMaxOccursUnbounded() ||
+ occurrence < particle.getMinOccurs() ||
+ occurrence < particle.getMaxOccurs())
+ {
+ ElementBinding wildcardContent = getElement(name, atts);
+ if(wildcardContent != null)
+ {
+ currentParticle = new ParticleBinding(wildcardContent);
+ next = wildcardContent.newPosition(name, atts, currentParticle);
+ ++occurrence;
+
+ endParticle();
+ //o = initValue(stack.parent().getValue(), atts);
+ ended = false;
+ return this;
+ }
+ }
+
+ endParticle();
+ if(particle.isRepeatable() && repeatableParticleValue != null)
+ endRepeatableParticle(stack.parent());
+
+ currentParticle = null;
+ occurrence = 0;
+
+ return null;
+ }
+
next = null;
ElementBinding wildcardContent = getElement(name, atts);
if(wildcardContent != null)
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/AbstractPosition.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/AbstractPosition.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/AbstractPosition.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -31,10 +31,10 @@
import org.jboss.xb.binding.sunday.unmarshalling.NoopParticleHandler;
import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ParticleHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.PositionStack;
import org.jboss.xb.binding.sunday.unmarshalling.RepeatableParticleHandler;
import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.StackImpl;
import org.xml.sax.Attributes;
/**
@@ -45,10 +45,15 @@
*/
public abstract class AbstractPosition implements Position
{
- protected final Logger log = Logger.getLogger(getClass());
- protected boolean trace;
-
- protected StackImpl stack;
+ protected static Logger log = Logger.getLogger(AbstractPosition.class);
+ protected static boolean trace;
+
+ public static void resetTrace()
+ {
+ trace = log.isTraceEnabled();
+ }
+
+ protected PositionStack stack;
protected final QName qName;
protected ParticleBinding particle;
protected ParticleHandler handler;
@@ -74,66 +79,31 @@
this.occurrence = 1;
}
- public void setStack(StackImpl stack)
+ public void setStack(PositionStack stack)
{
this.stack = stack;
}
-
- public QName getQName()
- {
- return qName;
- }
public ParticleBinding getParticle()
{
return particle;
}
- public void setParticle(ParticleBinding particle)
- {
- this.particle = particle;
- }
-
public Position getNext()
{
return next;
}
- public void setNext(Position next)
- {
- this.next = next;
- }
-
- public ParticleHandler getHandler()
- {
- return handler;
- }
-
- public void setHandler(ParticleHandler handler)
- {
- this.handler = handler;
- }
-
public RepeatableParticleHandler getRepeatableHandler()
{
return repeatableHandler;
}
- public void setRepeatableHandler(RepeatableParticleHandler repeatableHandler)
- {
- this.repeatableHandler = repeatableHandler;
- }
-
public Object getRepeatableParticleValue()
{
return repeatableParticleValue;
}
- public void setRepeatableParticleValue(Object repeatableParticleValue)
- {
- this.repeatableParticleValue = repeatableParticleValue;
- }
-
public Object getValue()
{
return o;
@@ -149,16 +119,6 @@
return ended;
}
- public void setEnded(boolean ended)
- {
- this.ended = ended;
- }
-
- public TypeBinding getParentType()
- {
- return parentType;
- }
-
public void setParentType(TypeBinding parentType)
{
this.parentType = parentType;
@@ -169,11 +129,6 @@
return false;
}
- public boolean isModelGroup()
- {
- return false;
- }
-
public void setCurrentParticle(ParticleBinding currentParticle)
{
this.particle = currentParticle;
@@ -223,7 +178,7 @@
public Position nextPosition(QName qName, Attributes attrs)
{
- return startElement(qName, attrs, true);
+ return startElement(qName, attrs, false);
}
protected Position startElement(QName qName, Attributes atts, boolean required)
@@ -235,7 +190,7 @@
{
if(handler == null)
handler = getHandler(particle.getTerm());
- o = handler.startParticle(parent, qName, particle, atts, stack.nsRegistry);
+ o = handler.startParticle(parent, qName, particle, atts, stack.getNamespaceRegistry());
return o;
}
@@ -247,10 +202,35 @@
o = null;
}
- public void flushIgnorableCharacters()
+ public void startRepeatableParticle(Object parent)
{
+ if(trace)
+ log.trace(" start repeatable " + particle.getTerm());
+
+ RepeatableParticleHandler repeatableHandler = particle.getTerm().getRepeatableHandler();
+ // the way it is now it's never null
+ Object repeatableContainer = repeatableHandler.startRepeatableParticle(parent, qName, particle);
+ if(repeatableContainer != null)
+ {
+ if(this.repeatableParticleValue != null)
+ throw new IllegalStateException("Previous repeatable particle hasn't been ended yet!");
+ this.repeatableParticleValue = repeatableContainer;
+ this.repeatableHandler = repeatableHandler;
+ }
}
-
+
+ public void endRepeatableParticle(Position parentPosition)
+ {
+ if (trace)
+ log.trace(" end repeatable " + particle.getTerm());
+
+ if(repeatableParticleValue == null)
+ throw new IllegalStateException("handler is null");
+ repeatableHandler.endRepeatableParticle(parentPosition.getValue(), repeatableParticleValue, qName, particle, parentPosition.getParticle());
+ repeatableParticleValue = null;
+ this.repeatableHandler = null;
+ }
+
private ParticleHandler getHandler(TermBinding term)
{
ParticleHandler handler = null;
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/ElementPosition.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/ElementPosition.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/ElementPosition.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -29,6 +29,7 @@
import org.jboss.util.StringPropertyReplacer;
import org.jboss.xb.binding.Constants;
import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.NamespaceRegistry;
import org.jboss.xb.binding.metadata.CharactersMetaData;
import org.jboss.xb.binding.metadata.ValueMetaData;
import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler;
@@ -38,12 +39,14 @@
import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ParticleHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.PositionStack;
import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler;
import org.jboss.xb.binding.sunday.unmarshalling.TermBeforeSetParentCallback;
import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.UnmarshallingContextImpl;
import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
import org.xml.sax.Attributes;
@@ -66,25 +69,20 @@
super(qName, particle);
}
+ public ElementPosition(QName qName, ParticleBinding particle, Object o, ParticleHandler handler, TypeBinding parentType)
+ {
+ super(qName, particle);
+ this.particle = particle;
+ this.o = o;
+ this.handler = handler;
+ this.parentType = parentType;
+ }
+
public boolean isElement()
{
return true;
}
- public void flushIgnorableCharacters()
- {
- if(textContent == null)
- return;
-
- if(indentation == Boolean.TRUE || ignorableCharacters)
- {
- if(trace)
- log.trace("ignored characters: " + ((ElementBinding) particle.getTerm()).getQName() + " '" + textContent + "'");
- textContent = null;
- indentation = null;
- }
- }
-
public void reset()
{
super.reset();
@@ -252,8 +250,8 @@
// todo valueMetaData is available from type
unmarshalled = dataContent == null ?
- charHandler.unmarshalEmpty(qName, charType, stack.nsRegistry, valueMetaData) :
- charHandler.unmarshal(qName, charType, stack.nsRegistry, valueMetaData, dataContent);
+ charHandler.unmarshalEmpty(qName, charType, stack.getNamespaceRegistry(), valueMetaData) :
+ charHandler.unmarshal(qName, charType, stack.getNamespaceRegistry(), valueMetaData, dataContent);
}
if(unmarshalled != null)
@@ -268,11 +266,12 @@
TermBeforeSetParentCallback beforeSetParent = charType.getBeforeSetParentCallback();
if(beforeSetParent != null)
{
- stack.ctx.parent = o;
- stack.ctx.particle = particle;
- stack.ctx.parentParticle = stack.getNotSkippedParent().getParticle();
- unmarshalled = beforeSetParent.beforeSetParent(unmarshalled, stack.ctx);
- stack.ctx.clear();
+ UnmarshallingContextImpl ctx = stack.getContext();
+ ctx.parent = o;
+ ctx.particle = particle;
+ ctx.parentParticle = stack.notSkippedParent().getParticle();
+ unmarshalled = beforeSetParent.beforeSetParent(unmarshalled, ctx);
+ ctx.clear();
}
charHandler.setValue(qName, element, o, unmarshalled);
@@ -281,17 +280,18 @@
if(allInterceptors > 0)
{
+ NamespaceRegistry nsRegistry = stack.getNamespaceRegistry();
int interceptorIndex = stack.size() - 1 - allInterceptors;
for (int i = interceptors.size() - 1; i >= 0; --i)
{
ElementInterceptor interceptor = interceptors.get(i);
- interceptor.characters(stack.peek(interceptorIndex++).getValue(), qName, type, stack.nsRegistry, dataContent);
+ interceptor.characters(stack.parent(interceptorIndex++).getValue(), qName, type, nsRegistry, dataContent);
}
for (int i = localInterceptors.size() - 1; i >= 0; --i)
{
ElementInterceptor interceptor = localInterceptors.get(i);
- interceptor.characters(stack.peek(interceptorIndex++).getValue(), qName, type, stack.nsRegistry, dataContent);
+ interceptor.characters(stack.parent(interceptorIndex++).getValue(), qName, type, nsRegistry, dataContent);
}
}
}
@@ -313,7 +313,7 @@
for (int i = interceptors.size() - 1; i >= 0; --i)
{
ElementInterceptor interceptor = interceptors.get(i);
- interceptor.endElement(stack.peek(interceptorIndex++).getValue(), qName, type);
+ interceptor.endElement(stack.parent(interceptorIndex++).getValue(), qName, type);
}
}
@@ -323,7 +323,7 @@
if(allInterceptors == 0)
{
- Position notSkippedParent = stack.getNotSkippedParent();
+ Position notSkippedParent = stack.notSkippedParent();
if (notSkippedParent != null)
{
ParticleBinding parentParticle = notSkippedParent.getParticle();
@@ -339,16 +339,21 @@
handler = wh;
}
- if(notSkippedParent.getRepeatableParticleValue() == null)
+ if(repeatableParticleValue != null)
{
+ repeatableHandler.addTermValue(repeatableParticleValue, o, qName, particle, notSkippedParent.getParticle(), handler);
+ }
+ else if(notSkippedParent.getRepeatableParticleValue() == null || !notSkippedParent.getParticle().getTerm().isSkip())
+ {
TermBeforeSetParentCallback beforeSetParent = particle.getTerm().getBeforeSetParentCallback();
if(beforeSetParent != null)
{
- stack.ctx.parent = notSkippedParent.getValue();
- stack.ctx.particle = particle;
- stack.ctx.parentParticle = stack.getNotSkippedParent().getParticle();
- o = beforeSetParent.beforeSetParent(o, stack.ctx);
- stack.ctx.clear();
+ UnmarshallingContextImpl ctx = stack.getContext();
+ ctx.parent = notSkippedParent.getValue();
+ ctx.particle = particle;
+ ctx.parentParticle = stack.notSkippedParent().getParticle();
+ o = beforeSetParent.beforeSetParent(o, ctx);
+ ctx.clear();
}
handler.setParent(notSkippedParent.getValue(), o, qName, particle, notSkippedParent.getParticle());
@@ -360,15 +365,13 @@
o, qName, particle,
notSkippedParent.getParticle(), handler);
}
-
- //setParent(handler, notSkippedParent, this);
}
else if (parentTerm.isWildcard() && stack.size() > 1)
{
// the parent has anyType, so it gets the value of its child
for (int i = stack.size() - 2; i >= 0; --i)
{
- Position peeked = stack.peek(i);
+ Position peeked = stack.parent(i);
peeked.setValue(o);
if (peeked.isElement())
break;
@@ -408,106 +411,118 @@
public Position startParticle(QName startName, Attributes atts)
{
- Position position = this;
if(ended)
{
if(qName.equals(startName))
{
if(particle.isRepeatable())
{
- Position parentPosition = stack.peek1();
+ Position parentPosition = stack.parent();
if(parentPosition.repeatTerm(startName, atts))
reset();
- else if(parentPosition.getRepeatableParticleValue() != null)
- stack.endRepeatableParticle(parentPosition, qName, particle, parentPosition.getParticle());
+ else if(repeatableParticleValue != null)
+ endRepeatableParticle(parentPosition);
}
else
{
reset();
+ occurrence = 0;
endRepeatableParent();
}
}
else if(particle.isRepeatable())
{
- Position parentPosition = stack.peek1();
- if(parentPosition.getRepeatableParticleValue() != null)
- stack.endRepeatableParticle(parentPosition, qName, particle, parentPosition.getParticle());
+ if(repeatableParticleValue != null)
+ endRepeatableParticle(stack.parent());
}
+ return this;
}
- else
+
+ ElementBinding element = (ElementBinding) particle.getTerm();
+ TypeBinding parentType = element.getType();
+ ParticleBinding typeParticle = parentType.getParticle();
+ ModelGroupBinding modelGroup = typeParticle == null ? null : (ModelGroupBinding) typeParticle.getTerm();
+ if (modelGroup == null)
{
- ElementBinding element = (ElementBinding)particle.getTerm();
- TypeBinding 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))
{
- if(startName.equals(Constants.QNAME_XOP_INCLUDE))
- {
- TypeBinding anyUriType = stack.schema.getType(Constants.QNAME_ANYURI);
- if(anyUriType == null)
- log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
-
- ElementBinding parentElement = (ElementBinding) particle.getTerm();
- parentElement.setXopUnmarshaller(stack.schema.getXopUnmarshaller());
+ SchemaBinding schema = element.getSchema();
+ TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
+ if (anyUriType == null)
+ log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
- flushIgnorableCharacters();
- handler = DefaultHandlers.XOP_HANDLER;
- ignoreCharacters = true;
- initValue(o, null);
-
- TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
- xopIncludeType.setSchemaBinding(stack.schema);
- xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
- xopIncludeType.setHandler(new XOPIncludeHandler(parentType, stack.schema.getXopUnmarshaller()));
+ ElementBinding parentElement = (ElementBinding) particle.getTerm();
+ parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
- ElementBinding xopInclude = new ElementBinding(stack.schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
- position = new ElementPosition(startName, new ParticleBinding(xopInclude));
- return position;
- }
+ flushIgnorableCharacters();
+ handler = DefaultHandlers.XOP_HANDLER;
+ ignoreCharacters = true;
+ initValue(o, null);
- QName typeName = parentType.getQName();
- throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
- " type of element " + qName +
- " should be complex and contain " + startName + " as a child element."
- );
+ 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(parentType, schema.getXopUnmarshaller()));
+
+ ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
+ next = new ElementPosition(startName, new ParticleBinding(xopInclude));
+ return next;
}
- Position newPosition = modelGroup.newPosition(startName, atts, typeParticle);
- if(newPosition == null)
+ QName typeName = parentType.getQName();
+ throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) + " type of element "
+ + qName + " should be complex and contain " + startName + " as a child element.");
+ }
+
+ if (next != null)
+ {
+ if (particle.getMaxOccursUnbounded() || occurrence < particle.getMinOccurs()
+ || occurrence < particle.getMaxOccurs())
{
- throw new JBossXBRuntimeException(startName + " not found as a child of " + qName + " in " + modelGroup);
+ // this increase is actually ahead of its time, it may fail to locate the element
+ // but in the current impl it doesn't matter
+ ++occurrence;
}
else
{
- flushIgnorableCharacters();
+ throw new JBossXBRuntimeException(startName + " cannot appear in this position. Expected content of "
+ + qName + " is " + modelGroup);
+ }
+ }
- Object value = o;
- while(newPosition.getNext() != null)
- {
- if(newPosition.getParticle().isRepeatable())
- stack.startRepeatableParticle(stack.peek(), value, startName, newPosition.getParticle());
+ next = modelGroup.newPosition(startName, atts, typeParticle);
+ if (next == null)
+ {
+ throw new JBossXBRuntimeException(startName + " not found as a child of " + qName + " in " + modelGroup);
+ }
+ else
+ {
+ flushIgnorableCharacters();
- stack.push(newPosition);
- value = newPosition.initValue(o, atts);
- newPosition.setParentType(parentType);
- newPosition = newPosition.getNext();
- }
+ Object value = o;
+ while (next.getNext() != null)
+ {
+ if (next.getParticle().isRepeatable())
+ next.startRepeatableParticle(value);
- position = newPosition;
- position.setParentType(parentType);
- if(!position.isElement())
- throw new IllegalStateException();
- }
+ stack.push(next);
+ value = next.initValue(o, atts);
+ next.setParentType(parentType);
+ next = next.getNext();
+ }
+
+ next.setParentType(parentType);
+ if (!next.isElement())
+ throw new IllegalStateException();
}
- return position;
+ return next;
}
private void endRepeatableParent()
{
int stackIndex = stack.size() - 2;
Position position;
- Position parentPosition = stack.peek1();
+ Position parentPosition = stack.parent();
while(true)
{
if(parentPosition.isElement())
@@ -523,13 +538,13 @@
if(position.getParticle().isRepeatable())
{
((NonElementPosition)position).endParticle(stackIndex - 1);
- parentPosition = stack.peek(stackIndex - 1);
+ parentPosition = stack.parent(stackIndex - 1);
position.reset();
position.initValue(parentPosition.getValue(), null);
break;
}
- parentPosition = stack.peek(--stackIndex);
+ parentPosition = stack.parent(--stackIndex);
((NonElementPosition)position).endParticle(stackIndex);
}
@@ -584,9 +599,123 @@
while(++stackIndex < stack.size() - 1)
{
parentPosition = position;
- position = stack.peek(stackIndex);
+ position = stack.parent(stackIndex);
position.reset();
position.initValue(parentPosition.getValue(), null);
}
}
+
+ public void push(PositionStack stack, Attributes atts, boolean repeated)
+ {
+ ElementBinding element = (ElementBinding) particle.getTerm();
+
+ // TODO xsi:type support should be implemented in a better way
+ String xsiType = atts.getValue(Constants.NS_XML_SCHEMA_INSTANCE, "type");
+ if (xsiType != null)
+ {
+ if (trace)
+ log.trace(element.getQName() + " uses xsi:type " + xsiType);
+
+ if (nonXsiParticle == null)
+ nonXsiParticle = particle;
+
+ 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 = stack.getNamespaceRegistry().getNamespaceURI(xsiTypePrefix);
+ QName xsiTypeQName = new QName(xsiTypeNs, xsiTypeLocal);
+
+ SchemaBinding schemaBinding = element.getSchema();
+ TypeBinding xsiTypeBinding = schemaBinding.getType(xsiTypeQName);
+ if (xsiTypeBinding == null)
+ {
+ throw new JBossXBRuntimeException("Type binding not found for type " + xsiTypeQName
+ + " specified with xsi:type for element " + qName);
+ }
+
+ ElementBinding xsiElement = new ElementBinding(schemaBinding, qName, xsiTypeBinding);
+ xsiElement.setRepeatableHandler(element.getRepeatableHandler());
+
+ particle = new ParticleBinding(xsiElement, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded());
+ }
+
+ Object parent = stack.isEmpty() ? null : (repeated ? stack.parent().getValue() : stack.current().getValue());
+ if (!repeated && particle.isRepeatable())
+ startRepeatableParticle(parent);
+
+ TypeBinding type = element.getType();
+ if (type == null)
+ throw new JBossXBRuntimeException("No type for element " + element);
+
+ handler = type.getHandler();
+ if (handler == null)
+ handler = DefaultHandlers.ELEMENT_HANDLER;
+
+ List<ElementInterceptor> localInterceptors = parentType == null
+ ? Collections.<ElementInterceptor>emptyList()
+ : parentType.getInterceptors(qName);
+ List<ElementInterceptor> interceptors = element.getInterceptors();
+ if (interceptors.size() + localInterceptors.size() > 0)
+ {
+ if (repeated)
+ stack.pop();
+
+ NamespaceRegistry nsRegistry = stack.getNamespaceRegistry();
+ for (int i = 0; i < localInterceptors.size(); ++i)
+ {
+ ElementInterceptor interceptor = localInterceptors.get(i);
+ parent = interceptor.startElement(parent, qName, type);
+ stack.push(qName, particle, parent, handler, parentType);
+ interceptor.attributes(parent, qName, type, atts, nsRegistry);
+ }
+
+ for (int i = 0; i < interceptors.size(); ++i)
+ {
+ ElementInterceptor interceptor = interceptors.get(i);
+ parent = interceptor.startElement(parent, qName, type);
+ stack.push(qName, particle, parent, handler, parentType);
+ interceptor.attributes(parent, qName, type, atts, nsRegistry);
+ }
+
+ if (repeated)
+ {
+ // to have correct endRepeatableParticle calls
+ stack.push(this);
+ }
+ }
+
+ if (!repeated)
+ stack.push(this);
+
+ String nil = atts.getValue(Constants.NS_XML_SCHEMA_INSTANCE, "nil");
+ if (nil == null || !("1".equals(nil) || "true".equals(nil)))
+ initValue(parent, atts);
+ else
+ o = SundayContentHandler.NIL;
+ }
+
+ private void flushIgnorableCharacters()
+ {
+ if(textContent == null)
+ return;
+
+ if(indentation == Boolean.TRUE || ignorableCharacters)
+ {
+ if(trace)
+ log.trace("ignored characters: " + ((ElementBinding) particle.getTerm()).getQName() + " '" + textContent + "'");
+ textContent = null;
+ indentation = null;
+ }
+ }
}
\ No newline at end of file
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/NonElementPosition.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/NonElementPosition.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/NonElementPosition.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -28,6 +28,7 @@
import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
import org.jboss.xb.binding.sunday.unmarshalling.TermBeforeSetParentCallback;
import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.UnmarshallingContextImpl;
import org.xml.sax.Attributes;
/**
@@ -38,17 +39,11 @@
{
protected ParticleBinding currentParticle;
- protected NonElementPosition(QName name, ParticleBinding particle, ParticleBinding currentParticle)
+ protected NonElementPosition(QName name, ParticleBinding particle, ParticleBinding currentParticle, Position next)
{
super(name, particle);
this.particle = particle;
this.currentParticle = currentParticle;
- }
-
- protected NonElementPosition(QName name, ParticleBinding particle, ParticleBinding currentParticle, Position next)
- {
- this(name, particle, currentParticle);
- this.currentParticle = currentParticle;
this.next = next;
}
@@ -56,12 +51,7 @@
{
return false;
}
-
- public boolean isModelGroup()
- {
- return true;
- }
-
+
public ParticleBinding getCurrentParticle()
{
return currentParticle;
@@ -85,7 +75,7 @@
ended = true;
// model group should always have parent particle
- Position parentPosition = stack.peek1();
+ Position parentPosition = stack.parent();
if(parentPosition.getValue() != null)
setParent(parentPosition);
}
@@ -99,23 +89,28 @@
ended = true;
// model group should always have parent particle
- Position parentPosition = stack.getNotSkippedParent(parentIdex);
+ Position parentPosition = stack.notSkippedParent(parentIdex);
if(parentPosition.getValue() != null)
setParent(parentPosition);
}
private void setParent(Position parentPosition)
{
- if(parentPosition.getRepeatableParticleValue() == null)
+ if(repeatableParticleValue != null)
{
+ repeatableHandler.addTermValue(repeatableParticleValue, o, qName, particle, parentPosition.getParticle(), handler);
+ }
+ else if(parentPosition.getRepeatableParticleValue() == null || !parentPosition.getParticle().getTerm().isSkip())
+ {
TermBeforeSetParentCallback beforeSetParent = particle.getTerm().getBeforeSetParentCallback();
if(beforeSetParent != null)
{
- stack.ctx.parent = parentPosition.getValue();
- stack.ctx.particle = particle;
- stack.ctx.parentParticle = stack.getNotSkippedParent().getParticle();
- o = beforeSetParent.beforeSetParent(o, stack.ctx);
- stack.ctx.clear();
+ UnmarshallingContextImpl ctx = stack.getContext();
+ ctx.parent = parentPosition.getValue();
+ ctx.particle = particle;
+ ctx.parentParticle = stack.notSkippedParent().getParticle();
+ o = beforeSetParent.beforeSetParent(o, ctx);
+ ctx.clear();
}
handler.setParent(parentPosition.getValue(), o, qName, particle, parentPosition.getParticle());
@@ -137,12 +132,12 @@
{
endParticle();
- if(!particle.isRepeatable() && stack.peek1().isElement())
+ if(!particle.isRepeatable() && stack.parent().isElement())
{
TermBinding t = particle.getTerm();
StringBuffer sb = new StringBuffer(250);
sb.append(startName).append(" cannot appear in this position. Expected content of ")
- .append(((ElementBinding)stack.peek1().getParticle().getTerm()).getQName())
+ .append(((ElementBinding)stack.parent().getParticle().getTerm()).getQName())
.append(" is ").append(t);
throw new JBossXBRuntimeException(sb.toString());
}
@@ -153,15 +148,16 @@
{
if(currentParticle != prevParticle)
{
- if(getRepeatableParticleValue() != null &&
+ if(repeatableParticleValue != null &&
prevParticle != null && prevParticle.isRepeatable() && prevParticle.getTerm().isModelGroup())
{
- stack.endRepeatableParticle(this, qName, prevParticle, particle);
- }
+ if (trace)
+ log.trace(" end repeatable " + particle.getTerm());
- if(newPosition.getNext() != null && currentParticle.isRepeatable() && !currentParticle.getTerm().isElement())
- {
- stack.startRepeatableParticle(this, o, startName, currentParticle);
+ // the way it is now it's never null
+ repeatableHandler.endRepeatableParticle(o, repeatableParticleValue, qName, prevParticle, particle);
+ repeatableParticleValue = null;
+ repeatableHandler = null;
}
}
@@ -170,6 +166,9 @@
newPosition = newPosition.getNext();
while (newPosition.getNext() != null)
{
+ if(newPosition.getParticle().isRepeatable())
+ newPosition.startRepeatableParticle(value);
+
stack.push(newPosition);
value = newPosition.initValue(value, atts);
newPosition.setParentType(parentType);
Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/Position.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/Position.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/Position.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -24,10 +24,9 @@
import javax.xml.namespace.QName;
import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ParticleHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.PositionStack;
import org.jboss.xb.binding.sunday.unmarshalling.RepeatableParticleHandler;
import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.StackImpl;
import org.xml.sax.Attributes;
/**
@@ -38,20 +37,10 @@
*/
public interface Position
{
- void setStack(StackImpl stack);
-
- QName getQName();
-
+ void setStack(PositionStack stack);
+
ParticleBinding getParticle();
-
- void setParticle(ParticleBinding particle);
-
- ParticleHandler getHandler();
-
- void setHandler(ParticleHandler handler);
-
- TypeBinding getParentType();
-
+
void setParentType(TypeBinding parentType);
Object getValue();
@@ -59,25 +48,15 @@
void setValue(Object value);
Object getRepeatableParticleValue();
-
- void setRepeatableParticleValue(Object repeatableParticleValue);
-
+
RepeatableParticleHandler getRepeatableHandler();
- void setRepeatableHandler(RepeatableParticleHandler repeatableHandler);
-
boolean isEnded();
- void setEnded(boolean ended);
-
Position getNext();
- void setNext(Position next);
-
boolean isElement();
- boolean isModelGroup();
-
void reset();
Position nextPosition(QName qName, Attributes attrs);
@@ -88,8 +67,6 @@
void setCurrentParticle(ParticleBinding currentParticle);
- void flushIgnorableCharacters();
-
void characters(char[] ch, int start, int length);
Object initValue(Object parent, Attributes atts);
@@ -97,4 +74,8 @@
Position startParticle(QName startName, Attributes atts);
void endParticle();
+
+ void startRepeatableParticle(Object parent);
+
+ void endRepeatableParticle(Position parentPosition);
}
Added: jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/support/MyObject.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/support/MyObject.java (rev 0)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/support/MyObject.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -0,0 +1,74 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, 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.test.xb.builder.object.mc.support;
+
+/**
+ * A MyObject.
+ *
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public class MyObject
+{
+ private String key;
+
+ public MyObject()
+ {
+ }
+
+ public MyObject(String key)
+ {
+ this.key = key;
+ }
+
+ public String getKey()
+ {
+ return key;
+ }
+
+ public void setKey(String key)
+ {
+ this.key = key;
+ }
+
+ public boolean equals(Object object)
+ {
+ if (this == object)
+ return true;
+ if (object == null || object instanceof MyObject == false)
+ return false;
+
+ MyObject other = (MyObject) object;
+
+ return key.equals(other.key);
+ }
+
+ public int hashCode()
+ {
+ return key.hashCode();
+ }
+
+ public String toString()
+ {
+ return key;
+ }
+}
Modified: jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/test/DeploymentTestCase.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/test/DeploymentTestCase.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/object/mc/test/DeploymentTestCase.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -22,15 +22,21 @@
package org.jboss.test.xb.builder.object.mc.test;
import java.util.List;
+import java.util.Set;
import junit.framework.Test;
+import org.jboss.test.xb.builder.object.mc.support.MyObject;
import org.jboss.test.xb.builder.object.mc.support.TestBeanMetaDataFactory;
import org.jboss.test.xb.builder.object.mc.support.TestBeanMetaDataFactory1;
import org.jboss.test.xb.builder.object.mc.support.TestBeanMetaDataFactory2;
+import org.jboss.test.xb.builder.object.mc.support.model.AbstractArrayMetaData;
import org.jboss.test.xb.builder.object.mc.support.model.AbstractKernelDeployment;
+import org.jboss.test.xb.builder.object.mc.support.model.AbstractValueMetaData;
import org.jboss.test.xb.builder.object.mc.support.model.BeanMetaData;
import org.jboss.test.xb.builder.object.mc.support.model.BeanMetaDataFactory;
+import org.jboss.test.xb.builder.object.mc.support.model.PropertyMetaData;
+import org.jboss.test.xb.builder.object.mc.support.model.ValueMetaData;
/**
* DeploymentTestCase.
@@ -231,6 +237,39 @@
assertNotNull(bean);
assertEquals("Bean4", bean.getBean());
}
+
+ public void testDeploymentWithArrayOfJavaBeans() throws Exception
+ {
+ AbstractKernelDeployment deployment = unmarshalDeployment();
+ List<BeanMetaData> beans = deployment.getBeans();
+ assertNotNull(beans);
+ assertEquals(1, beans.size());
+ BeanMetaData beanMetaData = beans.get(0);
+ assertNotNull(beanMetaData);
+ Set<PropertyMetaData> properties = beanMetaData.getProperties();
+ assertNotNull(properties);
+ assertEquals(1, properties.size());
+ PropertyMetaData property = properties.iterator().next();
+ assertNotNull(property);
+ ValueMetaData value = property.getValue();
+ assertNotNull(value);
+ assertTrue(value instanceof AbstractArrayMetaData);
+ AbstractArrayMetaData array = (AbstractArrayMetaData) value;
+ assertEquals(4, array.size());
+ String keys[] = new String[]{"object1", "object2", "object2", "object1"};
+ for(int i = 0; i < keys.length; ++i)
+ {
+ Object o = array.get(i);
+ assertNotNull(o);
+ assertTrue(o instanceof AbstractValueMetaData);
+ AbstractValueMetaData v = (AbstractValueMetaData) o;
+ Object uv = v.getUnderlyingValue();
+ assertNotNull(uv);
+ assertTrue(uv instanceof MyObject);
+ MyObject mo = (MyObject) uv;
+ assertEquals(keys[i], mo.getKey());
+ }
+ }
public static Test suite()
{
Modified: jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/repeatableterms/test/RepeatableTermsUnitTestCase.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/repeatableterms/test/RepeatableTermsUnitTestCase.java 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xb/builder/repeatableterms/test/RepeatableTermsUnitTestCase.java 2009-12-11 11:24:24 UTC (rev 3842)
@@ -64,8 +64,44 @@
Sequence[] sequences = top.getSequences();
assertNotNull(sequences);
+ String[] expected = new String[]{
+ "sequenceChoice1_1", "sequenceChoice2_1", "sequenceChoice1_2", "sequenceChoice1_3", "sequenceChoice2_2"};
+ assertEquals(expected.length, sequences.length);
+ for(int i = 0; i < sequences.length; ++i)
+ assertEquals(expected[i], sequences[i].getChoice());
+
+
Choice[] choices = top.getChoices();
assertNotNull(choices);
+
+ assertEquals(3, choices.length);
+
+ Choice choice = choices[0];
+ assertNotNull(choice);
+ assertNull(choice.getChoiceChoice2());
+ String[] strings = choice.getChoiceChoice1();
+ assertNotNull(strings);
+ assertEquals(2, strings.length);
+ assertEquals("choiceChoice1_1", strings[0]);
+ assertEquals("choiceChoice1_2", strings[1]);
+
+ choice = choices[1];
+ assertNotNull(choice);
+ assertNull(choice.getChoiceChoice1());
+ strings = choice.getChoiceChoice2();
+ assertNotNull(strings);
+ assertEquals(2, strings.length);
+ assertEquals("choiceChoice2_1", strings[0]);
+ assertEquals("choiceChoice2_2", strings[1]);
+
+ choice = choices[2];
+ assertNotNull(choice);
+ assertNull(choice.getChoiceChoice2());
+ strings = choice.getChoiceChoice1();
+ assertNotNull(strings);
+ assertEquals(2, strings.length);
+ assertEquals("choiceChoice1_3", strings[0]);
+ assertEquals("choiceChoice1_4", strings[1]);
}
public void testBinding() throws Exception
Added: jbossxb/trunk/src/test/resources/org/jboss/test/xb/builder/object/mc/test/DeploymentWithArrayOfJavaBeans.xml
===================================================================
--- jbossxb/trunk/src/test/resources/org/jboss/test/xb/builder/object/mc/test/DeploymentWithArrayOfJavaBeans.xml (rev 0)
+++ jbossxb/trunk/src/test/resources/org/jboss/test/xb/builder/object/mc/test/DeploymentWithArrayOfJavaBeans.xml 2009-12-11 11:24:24 UTC (rev 3842)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+ <bean name="SimpleBean" class="org.jboss.test.kernel.config.support.SimpleBean">
+ <property name="array">
+ <array elementClass="java.lang.Object">
+ <javabean xmlns="test:javabean" class="org.jboss.test.xb.builder.object.mc.support.MyObject">
+ <property name="key">object1</property>
+ </javabean>
+ <javabean xmlns="test:javabean" class="org.jboss.test.xb.builder.object.mc.support.MyObject">
+ <property name="key">object2</property>
+ </javabean>
+ <javabean xmlns="test:javabean" class="org.jboss.test.xb.builder.object.mc.support.MyObject">
+ <property name="key">object2</property>
+ </javabean>
+ <javabean xmlns="test:javabean" class="org.jboss.test.xb.builder.object.mc.support.MyObject">
+ <property name="key">object1</property>
+ </javabean>
+ </array>
+ </property>
+ </bean>
+</deployment>
Modified: jbossxb/trunk/src/test/resources/org/jboss/test/xml/choiceresolution/test/Foo2BarSequenceOrBarUnitTestCase.xsd
===================================================================
--- jbossxb/trunk/src/test/resources/org/jboss/test/xml/choiceresolution/test/Foo2BarSequenceOrBarUnitTestCase.xsd 2009-12-09 18:54:20 UTC (rev 3841)
+++ jbossxb/trunk/src/test/resources/org/jboss/test/xml/choiceresolution/test/Foo2BarSequenceOrBarUnitTestCase.xsd 2009-12-11 11:24:24 UTC (rev 3842)
@@ -8,7 +8,7 @@
<xsd:complexType>
<xsd:choice maxOccurs="2">
<xsd:sequence>
- <xsd:element name="foo" type="xsd:string"/>
+ <xsd:element name="foo" type="xsd:string" minOccurs="1"/>
<xsd:element name="bar" type="xsd:string" maxOccurs="2"/>
</xsd:sequence>
<xsd:element name="bar" type="xsd:string" maxOccurs="1"/>
More information about the jboss-svn-commits
mailing list