[ 
https://issues.apache.org/jira/browse/TUSCANY-2342?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jean-Sebastien Delfino reassigned TUSCANY-2342:
-----------------------------------------------

    Assignee: Jean-Sebastien Delfino

> Problems in BaseStAXArtifactProcessor with writing prefixes
> -----------------------------------------------------------
>
>                 Key: TUSCANY-2342
>                 URL: https://issues.apache.org/jira/browse/TUSCANY-2342
>             Project: Tuscany
>          Issue Type: Bug
>          Components: Java SCA Assembly Model
>            Reporter: Greg Dritschler
>            Assignee: Jean-Sebastien Delfino
>
> I think that BaseStAXArtifactProcessor has some bugs related to writing 
> namespace prefixes for attribute values.
> Let's start with this method:
>     protected void writeStart(XMLStreamWriter writer, String uri, String 
> name, XAttr... attrs) throws XMLStreamException {
>         String prefix = writeElementPrefix(writer, uri);
>         writeAttributePrefixes(writer, attrs);
>         writer.writeStartElement(uri, name);
>        
>         if (prefix != null){
>             writer.writeNamespace(prefix,uri);
>         }
>         writeAttributes(writer, attrs);
>     }
> writeAttributePrefixes calls down to XAttr.writePrefix.
> If the value is a QName then XAttr.writePrefix calls XAttr.writeQNamePrefix.
>         private void writeQNamePrefix(XMLStreamWriter writer, QName qname) 
> throws XMLStreamException {
>             if (qname != null) {
>                 String prefix = qname.getPrefix();
>                 String uri = qname.getNamespaceURI();
>                 prefix = writer.getPrefix(uri);
>                 if (prefix != null) {
>                     return;
>                 } else {
>                    
>                     // Find an available prefix and bind it to the given URI
>                     NamespaceContext nsc = writer.getNamespaceContext();
>                     for (int i=1; ; i++) {
>                         prefix = "ns" + i;
>                         if (nsc.getNamespaceURI(prefix) == null) {
>                             break;
>                         }
>                     }
>                     writer.setPrefix(prefix, uri);
>                 }
>             }
>         }
> If the QName has a uri which isn't yet bound to a prefix, this method binds 
> it.  Note that it does not write the namespace to the stream, nor does it 
> return anything to its caller to tell it to write the namespace.  So the 
> resulting XML has an unbound prefix which will cause problems for anyone 
> re-reading the composite.
> writeQNamePrefix cannot write the namespace itself because it is being called 
> by writeStart before the element has been started.  If this is the root 
> element of the document, attempting to do a write at this point will cause an 
> exception.
> I'm not sure why the code is arranged this way.  I thought it might be to 
> minimize the number of prefixes generated by binding the prefix in the 
> parent's element rather than the element we are about to write.  But that 
> doesn't work when you are working with the root element and don't have a 
> parent element.
> So I don't know why this structure of separately writing the prefixes is 
> here.  XAttr.writeQNameValue has code to bind a prefix to a new URI, and it 
> DOES write the prefix-uri binding to the stream.  Why isn't that good enough?
> Speaking of writeQNameValue, I have a question about it too.
>         private String writeQNameValue(XMLStreamWriter writer, QName qname) 
> throws XMLStreamException {
>             if (qname != null) {
>                 String prefix = qname.getPrefix();
>                 String uri = qname.getNamespaceURI();
>                 prefix = writer.getPrefix(uri);
>                 if (prefix != null && prefix.length() > 0) {
>                     // Use the prefix already bound to the given URI
>                     return prefix + ":" + qname.getLocalPart();
>                 } else {
>                    
>                     // Find an available prefix and bind it to the given URI
>                     NamespaceContext nsc = writer.getNamespaceContext();
>                     for (int i=1; ; i++) {
>                         prefix = "ns" + i;
>                         if (nsc.getNamespaceURI(prefix) == null) {
>                             break;
>                         }
>                     }
>                     writer.setPrefix(prefix, uri);
>                     writer.writeNamespace(prefix, uri);
>                     return prefix + ":" + qname.getLocalPart();
>                 }
>             } else {
>                 return null;
>             }
>         }
> I am wondering about the check for prefix.length() > 0.  The documentation 
> for getPrefix() is sketchy, but it seems to return the empty string if the 
> given namespace is the default namespace.  So this code generates a new 
> prefix when the QName value uses the default namespace.  Why does it do that? 
>  I think if getPrefix returns a non-null value of zero length, this method 
> should return the local part of the QName with no prefix.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to