BindingVisitorDispatch.walk(object, encoder.getBindingWalker(), element, executor, context);
if (!executor.getProperties().isEmpty()) {
//group into a map of name, list
MultiHashMap map = new MultiHashMap();
for (Iterator p = executor.getProperties().iterator(); p.hasNext();) {
Object[] property = (Object[]) p.next();
map.put(property[0], property[1]);
}
//turn each map entry into a particle
HashMap particles = new HashMap();
for (Iterator e = map.entrySet().iterator(); e.hasNext();) {
Map.Entry entry = (Map.Entry) e.next();
//key could be a name or a particle
if ( entry.getKey() instanceof XSDParticle ) {
XSDParticle particle = (XSDParticle) entry.getKey();
particles.put( Schemas.getParticleName( particle), particle );
continue;
}
QName name = (QName) entry.getKey();
Collection values = (Collection) entry.getValue();
//check for comment
if (Encoder.COMMENT.equals(name)) {
//create a dom element which text nodes for the comments
Element comment = encoder.getDocument()
.createElement(Encoder.COMMENT.getLocalPart());
for (Iterator v = values.iterator(); v.hasNext();) {
comment.appendChild(encoder.getDocument().createTextNode(v.next().toString()));
}
XSDParticle particle = XSDFactory.eINSTANCE.createXSDParticle();
XSDElementDeclaration elementDecl = XSDFactory.eINSTANCE
.createXSDElementDeclaration();
elementDecl.setTargetNamespace(Encoder.COMMENT.getNamespaceURI());
elementDecl.setName(Encoder.COMMENT.getLocalPart());
elementDecl.setElement(comment);
particle.setContent(elementDecl);
particles.put(name, particle);
continue;
}
//find hte element
XSDElementDeclaration elementDecl = encoder.getSchemaIndex()
.getElementDeclaration(name);
if (elementDecl == null) {
//look for the element declaration as a particle of the containing type
XSDParticle particle =
Schemas.getChildElementParticle(element.getType(), name.getLocalPart(), true);
if (particle != null) {
particles.put(name, particle);
continue;
}
}
if (elementDecl == null) {
//TODO: resolving like this will return an element no
// matter what, modifying the underlying schema, this might
// be dangerous. What we shold do is force the schema to
// resolve all of it simports when the encoder starts
elementDecl = encoder.getSchema()
.resolveElementDeclaration(name.getNamespaceURI(),
name.getLocalPart());
}
//look for a particle in the containing type which is either
// a) a base type of the element
// b) in the same subsittuion group
// if found use the particle to dervice multiplicity
XSDParticle reference = null;
for ( Iterator p = Schemas.getChildElementParticles(element.getType(), true).iterator(); p.hasNext(); ) {
XSDParticle particle = (XSDParticle) p.next();
XSDElementDeclaration el = (XSDElementDeclaration) particle.getContent();
if ( el.isElementDeclarationReference() ) {
el = el.getResolvedElementDeclaration();
}
if ( Schemas.isBaseType(elementDecl, el) ) {
reference = particle;
break;
}
}
//wrap the property in a particle
XSDParticle particle = XSDFactory.eINSTANCE.createXSDParticle();
XSDElementDeclaration wrapper = XSDFactory.eINSTANCE.createXSDElementDeclaration();
wrapper.setResolvedElementDeclaration( elementDecl );
particle.setContent(wrapper);
//particle.setContent(elementDecl);
//if there is a reference, derive multiplicity
if ( reference != null ) {
particle.setMaxOccurs( reference.getMaxOccurs() );
}
else {
//dervice from collection
if ( values.size() > 1) {
//make a multi property
particle.setMaxOccurs(-1);
} else {
//single property
particle.setMaxOccurs(1);
}
}
particles.put(name, particle);
}
//process the particles in order in which we got the properties
for (Iterator p = executor.getProperties().iterator(); p.hasNext();) {
Object[] property = (Object[]) p.next();
Collection values = (Collection) map.get( property[0] );
QName name;
if ( property[0] instanceof XSDParticle ) {
name = Schemas.getParticleName( (XSDParticle) property[0] );
}