Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
     * 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.marshalling;
  
  import java.io.Reader;
  import java.io.Writer;
  import java.util.List;

Author(s):
Alexey Loubyansky
Version:
$Revision: 2913 $
  
  public class MarshallerImpl
      extends AbstractMarshaller
  {
     private Stack stack = new StackImpl();
  
     private Object root;

   
Whether NULL values should be ignored or marshalled as xsi:nil='1'
  
     private boolean supportNil = true;
  
     private boolean ignoreUnresolvedWildcard;
  
     private QName rootTypeQName;
  
  
     private SchemaBinding schema;
  
     private MarshallingContextImpl ctx = new MarshallingContextImpl();
  
     public boolean isIgnoreUnresolvedWildcard()
     {
        return ;
     }
  
     public void setIgnoreUnresolvedWildcard(boolean ignoreUnresolvedWildcard)
     {
        this. = ignoreUnresolvedWildcard;
     }
  
     {
        return ;
     }
  
     public void setSchemaResolver(SchemaBindingResolver schemaResolver)
     {
        this. = schemaResolver;
    }
 
    public QName getRootTypeQName()
    {
       return ;
    }
 
    public void setRootTypeQName(QName rootTypeQName)
    {
       this. = rootTypeQName;
    }
 
    public boolean isSupportNil()
    {
       return ;
    }
 
    public void setSupportNil(boolean supportNil)
    {
       this. = supportNil;
    }

   
Adds an attribute to the top most elements. First, we check whether there is a namespace associated with the passed in prefix. If the prefix was not declared, an exception is thrown.

Parameters:
prefix the prefix of the attribute to be declared
localName local name of the attribute
type the type of the attribute
value the value of the attribute
 
    public void addAttribute(String prefixString localNameString typeString value)
    {
       // todo addAttribute(String prefix, String localName, String type, String value)
    }
 
    // AbstractMarshaller implementation
 
    public void marshal(Reader xsdReaderObjectModelProvider providerObject rootWriter writer)
    {
       SchemaBinding model = XsdBinder.bind(xsdReadernull);
       marshallInternal(rootmodelwriter);
    }
 
    public void marshal(String xsdURLObjectModelProvider providerObject rootWriter writerthrows IOException,
        SAXException
    {
       SchemaBinding model = XsdBinder.bind(xsdURL);
       marshallInternal(rootmodelwriter);
    }
 
    public void marshal(SchemaBinding modelObjectModelProvider providerObject rootWriter writer)
        throws IOException,
        SAXException
    {
       marshallInternal(rootmodelwriter);
    }
 
    private void marshallInternal(Object rootSchemaBinding schemaWriter writer)
        throws IOExceptionSAXException
    {
       if(schema == null)
       {
          throw new JBossXBRuntimeException("XSModel is not available!");
       }
 
       this. = schema;
       this. = root;
 
       .startDocument();
 
       if( != null)
       {
          if(.isEmpty())
          {
             throw new JBossXBRuntimeException("If type name (" +
                  +
                 ") for the root element is specified then the name for the root element is required!"
             );
          }
          QName rootQName = .get(0);
 
          TypeBinding type = schema.getType();
          if(type == null)
          {
             throw new JBossXBRuntimeException("Global type definition is not found: " + );
          }
 
          if(isArrayWrapper(type))
          {
             .push(root);
             marshalComplexType(rootQNametypetruefalse);
             .pop();
          }
          else
          {
             ElementBinding element = new ElementBinding(schemarootQNametype);
             . = new ParticleBinding(element);
             marshalElementOccurence(elementrootfalsetrue);
          }
       }
       else if(.isEmpty())
       {
          Iterator<ParticleBindingelements = schema.getElementParticles();
          if(!elements.hasNext())
          {
             throw new JBossXBRuntimeException("The schema doesn't contain global element declarations.");
          }
 
          while(elements.hasNext())
          {
             ParticleBinding element = elements.next();
             . = element;
             marshalElementOccurence((ElementBindingelement.getTerm(), roottruetrue);
          }
       }
       else
       {
          for(int i = 0; i < .size(); ++i)
          {
             QName qName = .get(i);
             ParticleBinding element = schema.getElementParticle(qName);
             if(element == null)
             {
                Iterator<ElementBindingcomponents = schema.getElements();
                String roots = "";
                for(int j = 0; components.hasNext(); ++j)
                {
                   ElementBinding xsObject = (ElementBinding)components.next();
                   if(j > 0)
                   {
                      roots += ", ";
                   }
                   roots += xsObject.getQName();
                }
                throw new IllegalStateException("Root element not found: " + qName + " among " + roots);
             }
 
             . = element;
             marshalElementOccurence((ElementBindingelement.getTerm(), roottruetrue);
          }
       }
 
       .endDocument();
 
       // version & encoding
       writeXmlVersion(writer);
 
       ContentWriter contentWriter = new ContentWriter(writer,
       );
       .handleContent(contentWriter);
 
       if(.isTraceEnabled())
       {
          java.io.StringWriter traceWriter = new java.io.StringWriter();
          contentWriter = new ContentWriter(traceWriter,
          );
          .handleContent(contentWriter);
          .trace("marshalled:\n" + traceWriter.getBuffer().toString());
       }
    }
 
    private boolean marshalElementOccurence(ElementBinding element,
                                            Object value,
                                            boolean optional,
                                            boolean declareNs)
    {
       QName xsiTypeQName = null;
       TypeBinding xsiType = null;
       if(value != null)
       {
          QName typeQName = element.getType().getQName();
          xsiTypeQName = (QName).get(value.getClass());
          // in case xsiTypeQName is not null, typeQName should also be not null
          if(xsiTypeQName != null &&
              !(typeQName.getLocalPart().equals(xsiTypeQName.getLocalPart()) &&
                  typeQName.getNamespaceURI().equals(xsiTypeQName.getNamespaceURI())
              ))
          {
             if(.isTraceEnabled())
             {
                .trace(value.getClass() + " is mapped to xsi:type " + xsiTypeQName);
             }
 
             xsiType = .getType(xsiTypeQName);
             if(xsiType == null)
             {
                .warn("Class " +
                    value.getClass() +
                    " is mapped to type " +
                    xsiTypeQName +
                    " but the type is not found in schema."
                );
             }
             // todo should check derivation also, i.e. if(xsiType.derivedFrom())
          }
       }
 
       TermBeforeMarshallingCallback marshallingHandler = element.getBeforeMarshallingCallback();
       if(marshallingHandler != null)
       {
          value = marshallingHandler.beforeMarshalling(value);
       }
       
       .push(value);
       boolean marshalled = marshalElement(elementxsiTypeoptionaldeclareNs);
       .pop();
 
       return marshalled;
    }
 
    private boolean marshalElement(ElementBinding elementTypeBinding xsiTypeboolean optionalboolean declareNs)
    {
       Object value = .peek();
       boolean nillable = element.isNillable();
       boolean result = value != null || value == null && (optional || nillable);
       boolean trace = .isTraceEnabled() && result;
       if(trace)
       {
          .trace("started element " + element.getQName());
       }
 
       if(value != null)
       {
          boolean declareXsiType = xsiType != null;
          marshalElementType(element.getQName(),
              declareXsiType ? xsiType : element.getType(),
              declareNs,
              declareXsiType
          );
       }
       else if(nillable)
       {
          writeNillable(element.getQName(), nillable);
       }
 
       if(trace)
       {
          .trace("finished element " + element.getQName());
       }
 
       return result;
    }
 
    private void marshalElementType(QName elementQName,
                                    TypeBinding type,
                                    boolean declareNs,
                                    boolean declareXsiType)
    {
       String elementNs = elementQName.getNamespaceURI();
       String elementLocal = elementQName.getLocalPart();
 
       XOPMarshaller xopMarshaller = .getXopMarshaller();
       if(xopMarshaller == null)
       {
          xopMarshaller = type.getXopMarshaller();
       }
       
       if(xopMarshaller != null && isXopOptimizable(type))
       {
 
          if(xopMarshaller.isXOPPackage())
          {
             // XOPMarshaller callback will create the attachment part
             Object o = .peek();
             String cid = xopMarshaller.addMtomAttachment(new XOPObject(o), elementNselementLocal);
 
             // Create the xopInclude element from CID and exit
             AttributesImpl attrs = null;
             String prefix = getPrefix(elementNs);
             boolean genPrefix = prefix == null && elementNs != null && elementNs.length() > 0;
             if(genPrefix)
             {
                prefix = "ns_" + elementLocal;
                attrs = new AttributesImpl(1);
                declareNs(attrsprefixelementNs);
             }
 
             String qName = prefixLocalName(prefixelementLocal);
             .startElement(elementNselementLocalqNameattrs);
 
             AttributesImpl xopAttrs = new AttributesImpl(2);
             xopAttrs.add(."xop""xmlns:xop""CDATA".);
             xopAttrs.add(null"href""href""CDATA"cid);
 
             .startElement(."Include""xop:Include"xopAttrs);
             .endElement(."Include""xop:Include");
 
             .endElement(elementNselementLocalqName);
 
             // Skip further processing
             return;
 
          }
          else
          {
             // XOPMarshaller did not process the object
             // In this case we try to marshall the corresponding simple type
             if(!type.isSimple())
             {
                if(type.hasOnlyXmlMimeAttributes()) // TODO: what's the purpose of this? It's xopOptimizable anyway...
                {
                   if(.isTraceEnabled())
                   {
                      .trace(
                          "XML MIME attributes of type " + type.getQName() +
                              " are ignored, the value is marshalled as " + type.getSimpleType().getQName()
                      );
                   }
 
                   type = type.getSimpleType();
                }
             }          
          }
 
       }
 
       // If we reach this point then either it wasn't a XOP element at all
       // or the XOPMarshaller did not process it.
 
       if(type.isSimple())
       {
          marshalSimpleType(elementQNametypedeclareNsdeclareXsiType);
       }
       else
       {
          marshalComplexType(elementQNametypedeclareNsdeclareXsiType);
       }
    }
 
    private void marshalSimpleType(QName elementQName,
                                   TypeBinding type,
                                   boolean declareNs,
                                   boolean declareXsiType)
    {
       . = null;
       if((declareNs || declareXsiType) && .size() > 0)
       {
          if(. == null)
          {
             . = new AttributesImpl(.size() + 1);
          }
          declareNs(.);
       }
 
       String elementNs = elementQName.getNamespaceURI();
       String elementLocal = elementQName.getLocalPart();
 
       String prefix = getPrefix(elementNs);
       boolean genPrefix = prefix == null && elementNs != null && elementNs.length() > 0;
       if(genPrefix)
       {
          prefix = "ns_" + elementLocal;
          if(. == null)
          {
             . = new AttributesImpl(1);
          }
          declareNs(.prefixelementNs);
       }
 
       if(declareXsiType)
       {
          declareXsiType(type.getQName(), .);
       }
 
       String typeName = type.getQName() == null ? null : type.getQName().getLocalPart();
       if(. == null && ..equals(typeName) ||
           ..equals(typeName) ||
           type.getItemType() != null &&
               (..equals(type.getItemType().getQName().getLocalPart()) ||
                   ..equals(type.getItemType().getQName().getLocalPart())
               )
           )
       {
          . = new AttributesImpl(5);
       }
 
       Object value = .peek();
       String marshalled = marshalCharacters(elementNsprefixtypevalue);
 
       String qName = prefixLocalName(prefixelementLocal);
       .startElement(elementNselementLocalqName.);
       .characters(marshalled.toCharArray(), 0, marshalled.length());
       .endElement(elementNselementLocalqName);
    }
 
    private void marshalComplexType(QName elementQName,
                                    TypeBinding type,
                                    boolean declareNs,
                                    boolean declareXsiType)
    {
       Collection<AttributeBindingattrBindings = type.getAttributes();
       int attrsTotal = declareNs || declareXsiType ? .size() + attrBindings.size() + 1: attrBindings.size();
       . = attrsTotal > 0 ? new AttributesImpl(attrsTotal) : null;
 
       if(declareNs && .size() > 0)
       {
          declareNs(.);
       }
 
       String generatedPrefix = null;
       if(declareXsiType)
       {
          generatedPrefix = declareXsiType(type.getQName(), .);
          if(generatedPrefix != null)
          {
             String typeNsWithGeneratedPrefix = type.getQName().getNamespaceURI();
             declareNs(.generatedPrefixtypeNsWithGeneratedPrefix);
             declareNamespace(generatedPrefixtypeNsWithGeneratedPrefix);
          }
       }
 
       String elementNs = elementQName.getNamespaceURI();
       String elementLocal = elementQName.getLocalPart();
 
       String prefix = getPrefix(elementNs);
       boolean genPrefix = prefix == null && elementNs != null && elementNs.length() > 0;
       if(genPrefix)
       {
          // todo: it's possible that the generated prefix already mapped. this should be fixed
          prefix = "ns_" + elementLocal;
          declareNamespace(prefixelementNs);
          if(. == null)
          {
             . = new AttributesImpl(1);
          }
          declareNs(.prefixelementNs);
       }
 
       if(!attrBindings.isEmpty())
       {
          for(Iterator<AttributeBindingi = attrBindings.iterator(); i.hasNext();)
          {
             AttributeBinding attrBinding = i.next();
             QName attrQName = attrBinding.getQName();
 
             if(..equals(attrQName))
             {
                continue;
             }
 
             . = attrBinding;
             AttributeMarshaller marshaller = attrBinding.getMarshaller();
             String marshalledAttr = marshaller.marshal();
 
             if(marshalledAttr != null)
             {
                if(. == null)
                {
                   . = new AttributesImpl(5);
                }
 
                String attrNs = attrQName.getNamespaceURI();
                String attrLocal = attrQName.getLocalPart();
                String attrPrefix = null;
                if(attrNs != null)
                {
                   attrPrefix = getPrefix(attrNs);
                   if(attrPrefix == null && attrNs != null && attrNs.length() > 0)
                   {
                      attrPrefix = "ns_" + attrLocal;
                      declareNs(.attrPrefixattrNs);
                   }
                }
 
                String prefixedName = prefixLocalName(attrPrefixattrLocal);
                ..add(attrNsattrLocalprefixedName"CDATA"marshalledAttr);
             }
          }
          . = null;
       }
 
       String characters = null;
       TypeBinding simpleType = type.getSimpleType();
       if(simpleType != null && !..equals(type.getQName()))
       {
          String fieldName = .getSimpleContentProperty();
          CharactersMetaData charactersMetaData = type.getCharactersMetaData();
          PropertyMetaData propertyMetaData = charactersMetaData == null ? null : charactersMetaData.getProperty();
          if(propertyMetaData != null)
          {
             fieldName = propertyMetaData.getName();
          }
 
          if(fieldName != null)
          {
             boolean ignoreUnresolvedFieldOrClass = type.getSchemaBinding().isIgnoreUnresolvedFieldOrClass();
             Object o = .peek();
             Object value = getElementValue(ofieldNameignoreUnresolvedFieldOrClass);
             if(value != null)
             {
                String typeName = simpleType.getQName().getLocalPart();
                if(. == null && (..equals(typeName) ||
                    ..equals(typeName) ||
                    simpleType.getItemType() != null &&
                        (..equals(simpleType.getItemType().getQName().getLocalPart()) ||
                            ..equals(simpleType.getItemType().getQName().getLocalPart())
                        )
                )
                    )
                {
                   . = new AttributesImpl(5);
                }
 
                characters = marshalCharacters(elementNsprefixsimpleTypevalue);
             }
          }
       }
 
       String qName = prefixLocalName(prefixelementLocal);
       .startElement(elementNselementLocalqName.);
 
       ParticleBinding particle = type.getParticle();
       if(particle != null)
       {
          marshalParticle(particlefalse);
       }
 
       if(characters != null)
       {
          .characters(characters.toCharArray(), 0, characters.length());
       }
       .endElement(elementNselementLocalqName);
 
       . = null;
 
       if(genPrefix)
       {
          removePrefixMapping(prefix);
       }
 
       if(generatedPrefix != null)
       {
          removePrefixMapping(generatedPrefix);
       }
    }
 
    private boolean marshalParticle(ParticleBinding particleboolean declareNs)
    {
       boolean marshalled;
       TermBinding term = particle.getTerm();
       Object o;
       Iterator<?> i;
       
       ParticleBinding ctxParticle = .;
       . = particle;
       
       if(term.isModelGroup())
       {
          ModelGroupBinding modelGroup = (ModelGroupBinding)term;
          if(modelGroup.isSkip() || .isEmpty())
          {
             marshalled = marshalModelGroup(modelGroupdeclareNs);
          }
          else
          {
             PropertyMetaData propertyMetaData = modelGroup.getPropertyMetaData();
             if(propertyMetaData == null)
             {
                throw new JBossXBRuntimeException(
                    "Currently, property binding metadata must be available for a model group to be marshalled!"
                );
             }
 
             o = getChildren(.peek(), propertyMetaData.getName(),
                 modelGroup.getSchema().isIgnoreUnresolvedFieldOrClass()
             );
 
             TermBeforeMarshallingCallback marshallingHandler = modelGroup.getBeforeMarshallingCallback();
 
             i = o != null && isRepeatable(particle) ? getIterator(o) : null;
             if(i != null)
             {
                marshalled = true;
                while(i.hasNext() && marshalled)
                {
                   Object value = i.next();
 
                   if(marshallingHandler != null)
                   {
                      value = marshallingHandler.beforeMarshalling(value);
                   }
 
                   .push(value);
                   marshalled = marshalModelGroup(modelGroupdeclareNs);
                   .pop();
                }
             }
             else
             {
                if(marshallingHandler != null)
                {
                   o = marshallingHandler.beforeMarshalling(o);
                }
 
                .push(o);
                marshalled = marshalModelGroup(modelGroupdeclareNs);
                .pop();
             }
          }
       }
       else if(term.isWildcard())
       {
          o = .peek();
 
          boolean popWildcardValue = false;
          ObjectLocalMarshaller marshaller = null;
          if(mapping != null)
          {
             marshaller = mapping.marshaller;
             o = mapping.fieldInfo.getValue(o);
             .push(o);
             popWildcardValue = true;
          }
 
          TermBeforeMarshallingCallback marshallingHandler = term.getBeforeMarshallingCallback();
          
          i = o != null && isRepeatable(particle) ? getIterator(o) : null;
          if(i != null)
          {
             marshalled = true;
             while(i.hasNext() && marshalled)
             {
                Object value = i.next();
 
                if(marshallingHandler != null)
                {
                   value = marshallingHandler.beforeMarshalling(value);
                }
 
                marshalled = marshalWildcardOccurence(particlemarshallervaluedeclareNs);
             }
          }
          else
          {
             if(marshallingHandler != null)
             {
                o = marshallingHandler.beforeMarshalling(o);
             }
 
             marshalled = marshalWildcardOccurence(particlemarshallerodeclareNs);
          }
 
          if(popWildcardValue)
          {
             .pop();
          }
       }
       else
       {
          ElementBinding element = (ElementBinding)term;
          SchemaBinding schema = element.getSchema();
          o = getElementValue(elementschema.isIgnoreLowLine(), schema.isIgnoreUnresolvedFieldOrClass());
 
          i = o != null && isRepeatable(particle) ? getIterator(o) : null;
          if(i != null)
          {
             marshalled = true;
             while(i.hasNext() && marshalled)
             {
                Object value = i.next();
                marshalled = marshalElementOccurence(elementvalueparticle.getMinOccurs() == 0, declareNs);
             }
          }
          else
          {
             marshalled = marshalElementOccurence(elementoparticle.getMinOccurs() == 0, declareNs);
          }
       }
       
       . = ctxParticle;
       return marshalled;
    }
 
    private boolean marshalWildcardOccurence(ParticleBinding particle,
                                             ObjectLocalMarshaller marshaller,
                                             Object value,
                                             boolean declareNs)
    {
       boolean marshalled = true;
       if(marshaller != null)
       {
          marshaller.marshal(value);
       }
       else if(value != null)
       {
          .push(value);
          marshalled = marshalWildcard(particledeclareNs);
          .pop();
       }
       return marshalled;
    }
 
    private boolean marshalWildcard(ParticleBinding particleboolean declareNs)
    {
       WildcardBinding wildcard = (WildcardBinding)particle.getTerm();
       Object o = .peek();
       ClassMapping mapping = getClassMapping(o.getClass());
       if(mapping == null)
       {
          // todo: YAH (yet another hack)
          QName autoType = SimpleTypeBindings.typeQName(o.getClass());
          if(autoType != null)
          {
             String marshalled = SimpleTypeBindings.marshal(autoType.getLocalPart(), onull);
             .characters(marshalled.toCharArray(), 0, marshalled.length());
             return true;
          }
          else
          {
             ObjectLocalMarshaller marshaller = wildcard.getUnresolvedMarshaller();
             if(marshaller != null)
             {
                marshaller.marshal(o);
                return true;
             }
             
             String msg = "Failed to marshal wildcard: neither class mapping was found for "
                + o.getClass() + "@" + o.hashCode()
                + " (toString: " + o
                + ") nor marshaller for unresolved classes was setup.";
             if()
             {
                .warn(msg);
                return true;
             }
             else
             {
                throw new JBossXBRuntimeException(msg);
             }
          }
       }
 
       Object parentRoot = this.;
       Stack parentStack = this.;
       SchemaBinding parentSchema = this.;
 
       this. = o;
       this. = new StackImpl();
       this. = mapping.schemaUrl == null ? this. : XsdBinder.bind(mapping.schemaUrl);
 
       boolean marshalled;
       if(mapping.elementName != null)
       {
          ParticleBinding element = .getElementParticle(mapping.elementName);
          if(element == null)
          {
             throw new JBossXBRuntimeException("Element " + mapping.elementName + " is not declared in the schema.");
          }
 
          ParticleBinding ctxParticle = .;
          . = element;
          marshalled = marshalElementOccurence((ElementBindingelement.getTerm(), particle.getMinOccurs() == 0, declareNs);
          . = ctxParticle;
       }
       else if(mapping.typeName != null)
       {
          TypeBinding typeDef = .getType(mapping.typeName);
          if(typeDef == null)
          {
             throw new JBossXBRuntimeException("Type " +
                 mapping.typeName +
                 " is not defined in the schema."
             );
          }
 
          if(wildcard.getQName() == null)
          {
             throw new JBossXBRuntimeException("Expected the wildcard to have a non-null QName.");
          }
 
          ElementBinding element = new ElementBinding(wildcard.getQName(), typeDef);
          ParticleBinding ctxParticle = .;
          . = new ParticleBinding(element);
          marshalled = marshalElementOccurence(elementparticle.getMinOccurs() == 0, declareNs);
          . = ctxParticle;
       }
       else
       {
          throw new JBossXBRuntimeException("Class mapping for " +
              mapping.cls +
              " is associated with neither global element name nor global type name."
          );
       }
 
       this. = parentRoot;
       this. = parentStack;
       this. = parentSchema;
 
       return marshalled;
    }
 
    private boolean marshalModelGroup(ModelGroupBinding modelGroupboolean declareNs)
    {
       boolean marshalled;
       if(modelGroup instanceof AllBinding)
       {
          marshalled = marshalModelGroupAll(modelGroup.getParticles(), declareNs);
       }
       else if(modelGroup instanceof ChoiceBinding)
       {
          marshalled = marshalModelGroupChoice(modelGroup.getParticles(), declareNs);
       }
       else
       {
          marshalled = marshalModelGroupSequence(modelGroupdeclareNs);
       }
       return marshalled;
    }
 
    private boolean marshalModelGroupAll(Collection<ParticleBindingparticlesboolean declareNs)
    {
       boolean marshalled = false;
       for(Iterator<ParticleBindingi = particles.iterator(); i.hasNext();)
       {
          ParticleBinding particle = i.next();
          marshalled |= marshalParticle(particledeclareNs);
       }
       return marshalled;
    }
 
    private boolean marshalModelGroupChoice(Collection<ParticleBindingparticlesboolean declareNs)
    {
       boolean marshalled = false;
       Content mainContent = this.;
       for(Iterator<ParticleBindingi = particles.iterator(); i.hasNext() && !marshalled;)
       {
          ParticleBinding particle = i.next();
          this. = new Content();
          marshalled = marshalParticle(particledeclareNs);
       }
 
       if(marshalled)
       {
          mainContent.append(this.);
       }
       this. = mainContent;
 
       return marshalled;
    }
 
    private boolean marshalModelGroupSequence(ModelGroupBinding sequenceboolean declareNs)
    {
       // if sequence is bound to a collection,
       // we assume the iterator over the collection is in sync with the particle iterator
       Iterator<?> valueIterator = null;
       if(!sequence.isSkip() && !.isEmpty())
       {
          Object o = .peek();
          if(o != null && (Collection.class.isAssignableFrom(o.getClass()) || o.getClass().isArray()))
          {
             valueIterator = getIterator(o);
          }
       }
 
       boolean marshalled = true;
       for(Iterator<ParticleBindingi = sequence.getParticles().iterator(); i.hasNext();)
       {
          if(valueIterator != null)
          {
             Object o = valueIterator.hasNext() ? valueIterator.next() : null;
             .push(o);
          }
 
          ParticleBinding particle = i.next();
          marshalled &= marshalParticle(particledeclareNs);
 
          if(valueIterator != null)
          {
             .pop();
          }
       }
       return marshalled;
    }
 
    private String marshalCharacters(String elementUri,
                                     String elementPrefix,
                                     TypeBinding simpleType,
                                     Object value)
    {
       String marshalled;
       QName simpleTypeQName = simpleType.getQName();
       if(simpleType.getItemType() != null)
       {
          TypeBinding itemType = simpleType.getItemType();
          if(..equals(itemType.getQName().getNamespaceURI()))
          {
             List<?> list;
             if(value instanceof List)
             {
                list = (List<?>)value;
             }
             else if(value.getClass().isArray())
             {
                list = asList(value);
            }
            else
            {
               // todo: qname are also not yet supported
               throw new JBossXBRuntimeException(
                   "Expected value for list type is an array or " + List.class.getName() + " but got: " + value
               );
            }
            marshalled = SimpleTypeBindings.marshalList(itemType.getQName().getLocalPart(), listnull);
         }
         else
         {
            throw new JBossXBRuntimeException("Marshalling of list types with item types not from " +
                . + " is not supported."
            );
         }
      }
      else if(simpleTypeQName != null && ..equals(simpleTypeQName.getNamespaceURI()))
      {
         String typeName = simpleTypeQName.getLocalPart();
         String prefix = null;
         boolean removePrefix = false;
         if(..equals(typeName) ||
             ..equals(typeName))
         {
            QName qNameValue = (QName)value;
            if(qNameValue.getNamespaceURI() != null && qNameValue.getNamespaceURI().length() > 0)
            {
               prefix = .getPrefix(qNameValue.getNamespaceURI());
               if(prefix == null)
               {
                  prefix = qNameValue.getPrefix();
                  if(prefix == null || prefix.length() == 0)
                  {
                     prefix = qNameValue.getLocalPart() + "_ns";
                  }
                  .addPrefixMapping(prefixqNameValue.getNamespaceURI());
                  .declareNamespace(prefixqNameValue.getNamespaceURI());
                  removePrefix = true;
               }
            }
         }
         marshalled = SimpleTypeBindings.marshal(typeNamevalue);