{
particle = schemaBinding.getElementParticle(startName);
}
else
{
throw new JBossXBRuntimeException("Failed to resolve schema nsURI=" + namespaceURI + " location=" + schemaLocation);
}
}
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) item.particle.getTerm();
parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
flushIgnorableCharacters();
item.handler = DefaultHandlers.XOP_HANDLER;
item.ignoreCharacters = true;
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
{
flushIgnorableCharacters();
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);
}