* @return
*/
protected AddToSchemaResult buildSchemaComponentsForXPath(XPathFragment frag, AddToSchemaResult xpr, boolean isChoice, Property next) {
boolean isAny = next.isAny() || next.isAnyAttribute();
TypeDefParticle currentParticle = xpr.particle;
Schema workingSchema = xpr.schema;
// each nested choice on a collection will be unbounded
boolean isUnbounded = false;
if(currentParticle != null) {
isUnbounded = (currentParticle.getMaxOccurs() != null && currentParticle.getMaxOccurs()==Occurs.UNBOUNDED);
}
// don't process the last frag; that will be handled by the calling method if necessary
// note that we may need to process the last frag if it has a namespace or is an 'any'
boolean lastFrag = (frag.getNextFragment() == null || frag.getNextFragment().nameIsText());
// if the element is already in the sequence we don't want the calling method to add a second one
if (lastFrag && (elementExistsInParticle(frag.getLocalName(), frag.getShortName(), currentParticle) != null)) {
xpr.particle = null;
return xpr;
}
// if the current element exists, use it; otherwise create a new one
Element currentElement = elementExistsInParticle(frag.getLocalName(), frag.getShortName(), currentParticle);
boolean currentElementExists = (currentElement != null);
if (!currentElementExists) {
currentElement = new Element();
// don't set the element name yet, as it may end up being a ref
ComplexType cType = new ComplexType();
TypeDefParticle particle = null;
if (isChoice) {
particle = new Choice();
if (isUnbounded) {
particle.setMaxOccurs(Occurs.UNBOUNDED);
}
} else {
XPathFragment nextFragment = frag.getNextFragment();
if (frag.containsIndex() || frag.getPredicate() != null || (!next.isXmlList() && null != nextFragment && nextFragment.isAttribute() && helper.isCollectionType(next.getType()))) {
currentElement.setMaxOccurs(Occurs.UNBOUNDED);
}
particle = new Sequence();
}
cType.setTypeDefParticle(particle);
currentElement.setComplexType(cType);
} else {
//if the current element already exists, we may need to change it's type
XPathFragment nextFrag = frag.getNextFragment();
if(nextFrag != null && nextFrag.isAttribute()) {
if(currentElement.getType() != null && currentElement.getComplexType() == null) {
//there's already a text mapping to this element, so
//attributes can be added by making it complex with
//simple content.
SimpleType type = currentElement.getSimpleType();
if(type != null) {
ComplexType cType = new ComplexType();
cType.setSimpleContent(new SimpleContent());
Extension extension = new Extension();
extension.setBaseType(type.getRestriction().getBaseType());
cType.getSimpleContent().setExtension(extension);
currentElement.setSimpleType(null);
currentElement.setComplexType(cType);
} else {
String eType = currentElement.getType();
ComplexType cType = new ComplexType();
SimpleContent sContent = new SimpleContent();
Extension extension = new Extension();
extension.setBaseType(eType);
sContent.setExtension(extension);
cType.setSimpleContent(sContent);
currentElement.setType(null);
currentElement.setComplexType(cType);
}
}
}
}
// may need to create a ref, depending on the namespace
Element globalElement = null;
String fragUri = frag.getNamespaceURI();
if (fragUri != null) {
Schema fragSchema = getSchemaForNamespace(fragUri);
String targetNS = workingSchema.getTargetNamespace();
// handle Attribute case
if (frag.isAttribute()) {
if (fragSchema == null || (fragSchema.isAttributeFormDefault() && !fragUri.equals(targetNS)) || (!fragSchema.isAttributeFormDefault() && fragUri.length() > 0)) {
// must generate a global attribute and create a reference to it
// if the global attribute exists, use it; otherwise create a new one
// if fragSchema is null, just generate the ref
if(fragSchema != null) {
Attribute globalAttribute = null;
globalAttribute = (Attribute) fragSchema.getTopLevelAttributes().get(frag.getLocalName());
if (globalAttribute == null) {
globalAttribute = createGlobalAttribute(frag, workingSchema, fragSchema, next);
}
} else {
//may need to add an import
addImportIfRequired(workingSchema, fragSchema, fragUri);
}
// add the attribute ref to the current element
String attributeRefName;
if (fragUri.equals(targetNS)) {
String prefix = fragSchema.getNamespaceResolver().resolveNamespaceURI(fragUri);
attributeRefName = prefix + COLON + frag.getLocalName();
} else {
attributeRefName = frag.getShortName();
}
TypeDefParticleOwner type;
if(currentParticle != null) {
type = currentParticle.getOwner();
} else {
type = xpr.simpleContentType;
}
if (type instanceof ComplexType) {
createRefAttribute(attributeRefName, (ComplexType)type);
}
// set the frag's schema as it may be different than the current schema
xpr.schema = fragSchema;
// ref case - indicate to the calling method that there's nothing to do
xpr.particle = null;
}
// since we are dealing with an attribute, we are on the last fragment; return
return xpr;
}
// here we are dealing with an Element
if ((fragSchema.isElementFormDefault() && !fragUri.equals(targetNS)) || (!fragSchema.isElementFormDefault() && fragUri.length() > 0)) {
// must generate a global element and create a reference to it
// if the global element exists, use it; otherwise create a new one
globalElement = (Element) fragSchema.getTopLevelElements().get(frag.getLocalName());
if (globalElement == null) {
globalElement = createGlobalElement(frag, workingSchema, fragSchema, isChoice, isUnbounded, next, (lastFrag && !isAny));
}
// if the current element doesn't exist set a ref and add it to the sequence
if (!currentElementExists) {