You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2006/05/19 01:16:10 UTC

svn commit: r407656 [1/2] - in /incubator/servicemix/trunk: servicemix-core/src/main/java/org/apache/servicemix/jbi/jaxp/ servicemix-core/src/main/java/org/apache/servicemix/jbi/util/ servicemix-http/src/main/java/org/apache/servicemix/http/ servicemix...

Author: gnodet
Date: Thu May 18 16:16:09 2006
New Revision: 407656

URL: http://svn.apache.org/viewvc?rev=407656&view=rev
Log:
SM-433: better handling of soap errors (especially with different soap versions)

Added:
    incubator/servicemix/trunk/servicemix-soap/src/test/java/org/apache/servicemix/soap/marshalers/FaultTest.java
    incubator/servicemix/trunk/servicemix-soap/src/test/resources/org/apache/servicemix/soap/marshalers/fault-1.1-ok.xml
    incubator/servicemix/trunk/servicemix-soap/src/test/resources/org/apache/servicemix/soap/marshalers/fault-1.2-ok.xml
Modified:
    incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/jaxp/XMLStreamHelper.java
    incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/util/DOMUtil.java
    incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java
    incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java
    incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpAddressingTest.java
    incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpSoapTest.java
    incubator/servicemix/trunk/servicemix-http/src/test/resources/org/apache/servicemix/http/addressing.xml
    incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapEndpoint.java
    incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapFault.java
    incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java
    incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMarshaler.java
    incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMessage.java
    incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapReader.java
    incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapWriter.java
    incubator/servicemix/trunk/servicemix-soap/src/test/java/org/apache/servicemix/soap/marshalers/SoapMessageMarshalerTest.java

Modified: incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/jaxp/XMLStreamHelper.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/jaxp/XMLStreamHelper.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/jaxp/XMLStreamHelper.java (original)
+++ incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/jaxp/XMLStreamHelper.java Thu May 18 16:16:09 2006
@@ -15,237 +15,330 @@
  */
 package org.apache.servicemix.jbi.jaxp;
 
-import javanet.staxutils.XMLStreamReaderToContentHandler;
-import javanet.staxutils.helpers.XMLFilterImplEx;
-
-import javax.xml.namespace.NamespaceContext;
+import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
 /**
  * Utility methods for working with an XMLStreamWriter. Maybe push this back into
  * stax-utils project.
  * 
+ * Code borrowed to XFire project.
+ * 
  * @version $Revision: 1.16 $
  */
 public class XMLStreamHelper implements XMLStreamConstants {
-    private static Attributes emptyAttributes = new AttributesImpl();
-
 
     /**
-     * Returns true if currently at the start of an element, otherwise move forwards to
-     * the next element start and return true, otherwise false is returned if the end of
-     * the stream is reached.
+     * Copies the reader to the writer.  The start and end document
+     * methods must be handled on the writer manually.
+     * 
+     * TODO: if the namespace on the reader has been declared previously
+     * to where we are in the stream, this probably won't work.
+     * 
+     * @param reader
+     * @param writer
+     * @throws XMLStreamException
      */
-    public static boolean skipToStartOfElement(XMLStreamReader in) throws XMLStreamException {
-        for (int code = in.getEventType(); code != END_DOCUMENT; code = in.next()) {
-            if (code == START_ELEMENT) {
-                return true;
-            }
+    public static void copy( XMLStreamReader reader, XMLStreamWriter writer ) 
+        throws XMLStreamException
+    {
+        int read = 0; // number of elements read in
+        int event = reader.getEventType();
+        
+        while ( reader.hasNext() )
+        {
+            switch( event )
+            {
+                case XMLStreamConstants.START_ELEMENT:
+                    read++;
+                    writeStartElement( reader, writer );
+                    break;
+                case XMLStreamConstants.END_ELEMENT:
+                    writer.writeEndElement();
+                    read--;
+                    if ( read <= 0 )
+                        return;
+                    break;
+                case XMLStreamConstants.CHARACTERS:
+                    writer.writeCharacters( reader.getText() );  
+                    break;
+                case XMLStreamConstants.START_DOCUMENT:
+                case XMLStreamConstants.END_DOCUMENT:
+                case XMLStreamConstants.ATTRIBUTE:
+                case XMLStreamConstants.NAMESPACE:
+                    break;
+                default:
+                    break;
+            }
+            event = reader.next();
         }
-        return false;
     }
 
-    public static void writeStartElement(QName qname, ContentHandler handler) throws SAXException {
-        handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), QNameHelper.getQualifiedName(qname), emptyAttributes);
-    }
+    private static void writeStartElement(XMLStreamReader reader, XMLStreamWriter writer) 
+        throws XMLStreamException
+    {
+        String local = reader.getLocalName();
+        String uri = reader.getNamespaceURI();
+        String prefix = reader.getPrefix();
+        if (prefix == null)
+        {
+            prefix = "";
+        }
+        if (uri == null)
+        {
+            uri = "";
+        }
+        
+        String boundPrefix = writer.getPrefix(uri);
+        boolean writeElementNS = false;
+        if ( boundPrefix == null || !prefix.equals(boundPrefix) )
+        {   
+            writeElementNS = true;
+        }
+        
+        // Write out the element name
+        if (uri != null)
+        {
+            if (prefix.length() == 0) 
+            { 
+                
+                writer.writeStartElement(local);
+                writer.setDefaultNamespace(uri); 
+                
+            } 
+            else 
+            { 
+                writer.writeStartElement(prefix, local, uri); 
+                writer.setPrefix(prefix, uri); 
+            } 
+        }
+        else
+        {
+            writer.writeStartElement( local );
+        }
+
+        // Write out the namespaces
+        for ( int i = 0; i < reader.getNamespaceCount(); i++ )
+        {
+            String nsURI = reader.getNamespaceURI(i);
+            String nsPrefix = reader.getNamespacePrefix(i);
+            if (nsPrefix == null) nsPrefix = "";
+            
+            if ( nsPrefix.length() ==  0 )
+            {
+                writer.writeDefaultNamespace(nsURI);
+            }
+            else
+            {
+                writer.writeNamespace(nsPrefix, nsURI);
+            }
+
+            if (nsURI.equals(uri) && nsPrefix.equals(prefix))
+            {
+                writeElementNS = false;
+            }
+        }
+        
+        // Check if the namespace still needs to be written.
+        // We need this check because namespace writing works 
+        // different on Woodstox and the RI.
+        if (writeElementNS)
+        {
+            if ( prefix == null || prefix.length() ==  0 )
+            {
+                writer.writeDefaultNamespace(uri);
+            }
+            else
+            {
+                writer.writeNamespace(prefix, uri);
+            }
+        }
 
-    public static void writeEndElement(QName qname, ContentHandler handler) throws SAXException {
-        handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), QNameHelper.getQualifiedName(qname));
+        // Write out attributes
+        for ( int i = 0; i < reader.getAttributeCount(); i++ )
+        {
+            String ns = reader.getAttributeNamespace(i);
+            String nsPrefix = reader.getAttributePrefix(i);
+            if ( ns == null || ns.length() == 0 )
+            {
+                writer.writeAttribute(
+                        reader.getAttributeLocalName(i),
+                        reader.getAttributeValue(i));
+            }
+            else if (nsPrefix == null || nsPrefix.length() == 0)
+            {
+                writer.writeAttribute(
+                    reader.getAttributeNamespace(i),
+                    reader.getAttributeLocalName(i),
+                    reader.getAttributeValue(i));
+            }
+            else
+            {
+                writer.writeAttribute(reader.getAttributePrefix(i),
+                                      reader.getAttributeNamespace(i),
+                                      reader.getAttributeLocalName(i),
+                                      reader.getAttributeValue(i));
+            }
+            
+            
+        }
     }
-
-
+    
     /**
-     * Copies the current element and its conetnt to the output
+     * Write a start element with the specified parameters
+     * @param writer
+     * @param uri
+     * @param local
+     * @param prefix
+     * @throws XMLStreamException
      */
-    public static void copy(XMLStreamReader in, XMLStreamWriter out, boolean repairing) throws XMLStreamException {
-        int elementCount = 0;
-        for (int code = in.getEventType(); in.hasNext(); code = in.next()) {
-          elementCount = copyOne(in, out, repairing, code, elementCount);
+    public static void writeStartElement( XMLStreamWriter writer, String uri, String local, String prefix ) 
+        throws XMLStreamException 
+    {
+        if (prefix == null)
+        {
+            prefix = "";
         }
-        while (elementCount-- > 0) {
-            out.writeEndElement();
+        if (uri == null)
+        {
+            uri = "";
+        }
+        
+        String boundPrefix = writer.getPrefix(uri);
+        boolean writeElementNS = false;
+        if ( boundPrefix == null || !prefix.equals(boundPrefix) )
+        {   
+            writeElementNS = true;
+        }
+        
+        // Write out the element name
+        if (uri != null)
+        {
+            if (prefix.length() == 0) 
+            { 
+                
+                writer.writeStartElement(local);
+                writer.setDefaultNamespace(uri); 
+                
+            } 
+            else 
+            { 
+                writer.writeStartElement(prefix, local, uri); 
+                writer.setPrefix(prefix, uri); 
+            } 
+        }
+        else
+        {
+            writer.writeStartElement( local );
+        }
+
+        // Check if the namespace still needs to be written.
+        // We need this check because namespace writing works 
+        // different on Woodstox and the RI.
+        if (writeElementNS)
+        {
+            if ( prefix.length() ==  0 )
+            {
+                writer.writeDefaultNamespace(uri);
+            }
+            else
+            {
+                writer.writeNamespace(prefix, uri);
+            }
         }
     }
 
     /**
-     *
+     * Write a start element with the given QName.
+     * However, if a namespace has already been bound to a prefix,
+     * use the existing one, else default to the prefix
+     * in the QName (if specified).  Else, a prefix is generated.
+     * 
+     * @param writer
+     * @param name
+     * @throws XMLStreamException
      */
-    public static int copyOne(XMLStreamReader in, XMLStreamWriter out, boolean repairing, int code, int elementCount) throws XMLStreamException {
-      switch (code) {
-        case START_ELEMENT:
-            elementCount++;
-            writeStartElementAndAttributes(out, in, repairing);
-            break;
-
-        case END_ELEMENT:
-            if (--elementCount < 0) {
-                return elementCount;
-            }
-            out.writeEndElement();
-            break;
-
-        case CDATA:
-            out.writeCData(in.getText());
-            break;
-
-        case CHARACTERS:
-            out.writeCharacters(in.getText());
-            break;
-      }
-      return elementCount;
-    }
-    
-    public static void writeStartElement(XMLStreamWriter out, String prefix, String uri, String localName, boolean repairing) throws XMLStreamException {
-        boolean map = isPrefixNotMappedToUri(out, prefix, uri);
-        if (prefix != null && prefix.length() > 0) {
-            if (map) {
-                out.setPrefix(prefix, uri);
-            }
-            out.writeStartElement(prefix, localName, uri);
-            if (map && !repairing) {
-                out.writeNamespace(prefix, uri);
-            }
-        }
-        else {
-            boolean hasURI = uri != null && uri.length() > 0;
-            if (map && hasURI) {
-                out.setDefaultNamespace(uri);
-            }
-            out.writeStartElement(uri, localName);
-            if (map && !repairing && hasURI) {
-                out.writeDefaultNamespace(uri);
-            }
-        }
+    public static void writeStartElement(XMLStreamWriter writer, QName name) throws XMLStreamException {
+        String prefix = choosePrefix(writer, name, false);
+        writeStartElement(writer, name.getNamespaceURI(), name.getLocalPart(), prefix);
     }
 
-    public static void writeStartElement(XMLStreamWriter out, QName envelopeName, boolean repairing) throws XMLStreamException {
-        writeStartElement(out, envelopeName.getPrefix(), envelopeName.getNamespaceURI(), envelopeName.getLocalPart(), repairing);
+    /**
+     * 
+     * @param out
+     * @param name
+     * @throws XMLStreamException
+     */
+    public static void writeTextQName(XMLStreamWriter out, QName name) throws XMLStreamException {
+        String prefix = choosePrefix(out, name, true);
+        if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) {
+            out.writeCharacters(name.getLocalPart());
+        } else {
+            out.writeCharacters(prefix + ":" + name.getLocalPart());
+        }
     }
-
-    public static void writeStartElement(XMLStreamWriter out, XMLStreamReader in, boolean repairing) throws XMLStreamException {
-        String prefix = in.getPrefix();
-
-        // we can avoid this step if in repairing mode
-        int count = in.getNamespaceCount();
-        for (int i = 0; i < count; i++) {
-            String aPrefix = in.getNamespacePrefix(i);
-            if (prefix == aPrefix || (prefix != null && prefix.equals(aPrefix))) {
-                continue;
-            }
-            String uri = in.getNamespaceURI(i);
-            if (isPrefixNotMappedToUri(out, aPrefix, uri)) {
-                if (aPrefix != null && aPrefix.length() > 0) {
-                    out.setPrefix(aPrefix, uri);
+    
+    protected static String choosePrefix(XMLStreamWriter out, QName name, boolean declare) throws XMLStreamException {
+        String uri = name.getNamespaceURI();
+        // If no namespace
+        if (uri == null || XMLConstants.NULL_NS_URI.equals(uri)) {
+            if (!XMLConstants.NULL_NS_URI.equals(out.getNamespaceContext().getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX))) {
+                out.setPrefix(XMLConstants.DEFAULT_NS_PREFIX, XMLConstants.NULL_NS_URI);
+            }
+            return XMLConstants.DEFAULT_NS_PREFIX;
+        // Need to write a prefix
+        } else {
+            String defPrefix = name.getPrefix();
+            // A prefix is specified
+            if (defPrefix != null && !XMLConstants.DEFAULT_NS_PREFIX.equals(defPrefix)) {
+                // if the uri is bound to the specified prefix, good, else
+                if (!uri.equals(out.getNamespaceContext().getNamespaceURI(defPrefix))) {
+                    // if there is a prefix bound to the uri, use it
+                    if (out.getNamespaceContext().getPrefix(uri) != null) {
+                        defPrefix = out.getNamespaceContext().getPrefix(uri);
+                    // get prefix from the writer
+                    } else if (out.getPrefix(uri) != null) {
+                        defPrefix = out.getPrefix(uri);
+                    // we need to bind the prefix
+                    } else if (declare) {
+                        out.setPrefix(defPrefix, uri);
+                        out.writeNamespace(defPrefix, uri);
+                    }
                 }
-                else {
-                    out.setDefaultNamespace(uri);
+            // No prefix specified
+            } else {
+                // if there is a prefix bound to the uri, use it
+                if (out.getNamespaceContext().getPrefix(uri) != null) {
+                    defPrefix = out.getNamespaceContext().getPrefix(uri);
+                // get prefix from the writer
+                } else if (out.getPrefix(uri) != null) {
+                    defPrefix = out.getPrefix(uri);
+                // we need to generate a prefix
+                } else {
+                    defPrefix = getUniquePrefix(out); 
+                    if (declare) {
+                        out.setPrefix(defPrefix, uri);
+                        out.writeNamespace(defPrefix, uri);
+                    }
                 }
             }
+            return defPrefix;
         }
-        String localName = in.getLocalName();
-        String uri = in.getNamespaceURI();
-        writeStartElement(out, prefix, uri, localName, repairing);
     }
-
-
-    public static void writeStartElementAndAttributes(XMLStreamWriter out, XMLStreamReader in, boolean repairing) throws XMLStreamException {
-        writeStartElement(out, in, repairing);
-        if (!repairing) {
-            writeNamespaces(out, in, in.getPrefix());
-        }
-        writeAttributes(out, in);
-    }
-
-    public static void writeAttributes(XMLStreamWriter out, XMLStreamReader in) throws XMLStreamException {
-        int count = in.getAttributeCount();
-        for (int i = 0; i < count; i++) {
-            out.writeAttribute(in.getAttributePrefix(i),
-                    in.getAttributeNamespace(i),
-                    in.getAttributeLocalName(i),
-                    in.getAttributeValue(i));
-        }
-    }
-
-    public static void writeNamespaces(XMLStreamWriter out, XMLStreamReader in, String prefixOfCurrentElement) throws XMLStreamException {
-        int count = in.getNamespaceCount();
-        for (int i = 0; i < count; i++) {
-            String prefix = in.getNamespacePrefix(i);
-            String uri = in.getNamespaceURI(i);
-            
-            // ROGER
-            if ( prefixOfCurrentElement == null && prefix.length()==0 ) {
-              continue;
-            }
-            
-            if (prefixOfCurrentElement != null && prefixOfCurrentElement.equals(prefix)) {
-                continue;
-            }
-            if (isPrefixNotMappedToUri(out, prefix, uri)) {
-                out.writeNamespace(prefix, uri);
-            }
-        }
-    }
-
-
-    public static void writeNamespacesExcludingPrefixAndNamespace(XMLStreamWriter out, XMLStreamReader in, String ignorePrefix, String ignoreNamespace) throws XMLStreamException {
-        int count = in.getNamespaceCount();
-        for (int i = 0; i < count; i++) {
-            String prefix = in.getNamespacePrefix(i);
-            if (!ignorePrefix.equals(prefix)) {
-                String uri = in.getNamespaceURI(i);
-                if (!ignoreNamespace.equals(uri)) {
-                    out.writeNamespace(prefix, uri);
-                }
+    
+    protected static String getUniquePrefix(XMLStreamWriter writer) {
+        int n = 1;
+        while (true) {
+            String nsPrefix = "ns" + n;
+            if (writer.getNamespaceContext().getNamespaceURI(nsPrefix) == null) {
+                return nsPrefix;
             }
+            n++;
         }
     }
 
-    public static void writeAttribute(XMLStreamWriter out, QName name, String attributeValue) throws XMLStreamException {
-        writeAttribute(out, name.getPrefix(), name.getNamespaceURI(), name.getLocalPart(), attributeValue);
-    }
-
-    public static void writeAttribute(XMLStreamWriter out, String prefix, String namespaceURI, String localPart, String attributeValue) throws XMLStreamException {
-        out.writeAttribute(prefix, namespaceURI, localPart, attributeValue);
-    }
-
-    protected static boolean isPrefixNotMappedToUri(XMLStreamWriter out, String prefix, String uri) {
-        if (prefix == null) {
-            prefix = "";
-        }
-        NamespaceContext context = out.getNamespaceContext();
-        if (context == null) {
-            return false;
-        }
-        String mappedUri = context.getPrefix(prefix);
-        boolean map = (mappedUri == null || !mappedUri.equals(uri));
-        return map;
-    }
-
-    /**
-     * Copies the content to the SAX stream
-     */
-    public static void copy(XMLStreamReader in, ContentHandler contentHandler) throws XMLStreamException {
-        XMLFilterImplEx filter = new XMLFilterImplEx();
-        filter.setContentHandler(contentHandler);
-        XMLStreamReaderToContentHandler converter = new XMLStreamReaderToContentHandler(in, filter);
-        converter.bridge();
-    }
-
-    /**
-     * Copies the element and its content to the SAX stream
-     */
-    public static void copyElement(XMLStreamReader in, ContentHandler contentHandler) throws XMLStreamException {
-        copy(new FragmentStreamReader(in), contentHandler);
-    }
-
-    
 }

Modified: incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/util/DOMUtil.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/util/DOMUtil.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/util/DOMUtil.java (original)
+++ incubator/servicemix/trunk/servicemix-core/src/main/java/org/apache/servicemix/jbi/util/DOMUtil.java Thu May 18 16:16:09 2006
@@ -161,4 +161,50 @@
         }
         return answer;
     }
+
+    /**
+     * Get the first child element
+     * @param parent
+     * @return
+     */
+    public static Element getFirstChildElement(Element parent) {
+        NodeList childs = parent.getChildNodes();
+        for (int i = 0; i < childs.getLength(); i++) {
+            Node child = childs.item(i);
+            if (child instanceof Element) {
+                return (Element) child;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Get the next sibling element
+     * @param el
+     * @return
+     */
+    public static Element getNextSiblingElement(Element el) {
+        for (Node n = el.getNextSibling(); n != null; n = n.getNextSibling()) {
+            if (n instanceof Element) {
+                return (Element) n;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Build a QName from the element name
+     * @param el
+     * @return
+     */
+    public static QName getQName(Element el) {
+        if (el == null) {
+            return null;
+        } else if (el.getPrefix() != null) {
+            return new QName(el.getNamespaceURI(), el.getLocalName(), el.getPrefix());
+        } else {
+            return new QName(el.getNamespaceURI(), el.getLocalName());
+        }
+    }
+    
 }

Modified: incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java (original)
+++ incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java Thu May 18 16:16:09 2006
@@ -93,25 +93,43 @@
         PortType portType = null;
         // If the WSDL description only contain one PortType, use it
         if (def.getServices().size() == 0 && def.getPortTypes().size() == 1) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("WSDL only defines a PortType, using this one");
+            }
             portType = (PortType) def.getPortTypes().values().iterator().next();
         } else if (targetInterfaceName != null) {
             portType = def.getPortType(targetInterfaceName);
+            if (portType == null && logger.isDebugEnabled()) {
+                logger.debug("PortType for targetInterfaceName could not be found");
+            }
         } else if (targetService != null && targetEndpoint != null) {
             Service svc = def.getService(targetService);
             Port port = (svc != null) ? svc.getPort(targetEndpoint) : null;
             portType = (port != null) ? port.getBinding().getPortType() : null;
+            if (portType == null && logger.isDebugEnabled()) {
+                logger.debug("PortType for targetService/targetEndpoint could not be found");
+            }
         } else if (targetService != null) {
             Service svc = def.getService(targetService);
             if (svc != null && svc.getPorts().size() == 1) {
                 Port port = (Port) svc.getPorts().values().iterator().next();
                 portType = (port != null) ? port.getBinding().getPortType() : null;
             }
+            if (portType == null && logger.isDebugEnabled()) {
+                logger.debug("Service for targetService could not be found");
+            }
         } else if (interfaceName != null) {
             portType = def.getPortType(interfaceName);
+            if (portType == null && logger.isDebugEnabled()) {
+                logger.debug("Service for targetInterfaceName could not be found");
+            }
         } else {
             Service svc = def.getService(service);
             Port port = (svc != null) ? svc.getPort(endpoint) : null;
             portType = (port != null && port.getBinding() != null) ? port.getBinding().getPortType() : null;
+            if (portType == null && logger.isDebugEnabled()) {
+                logger.debug("Port for service/endpoint could not be found");
+            }
         }
         return portType;
     }

Modified: incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java (original)
+++ incubator/servicemix/trunk/servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java Thu May 18 16:16:09 2006
@@ -121,15 +121,14 @@
             int response = getClient().executeMethod(host, method);
             if (response != HttpStatus.SC_OK) {
                 if (exchange instanceof InOnly == false) {
-                    Fault fault = exchange.createFault();
                     SoapReader reader = soapMarshaler.createReader();
                     Header contentType = method.getResponseHeader("Content-Type");
                     soapMessage = reader.read(method.getResponseBodyAsStream(), 
                                               contentType != null ? contentType.getValue() : null);
+                    Fault fault = exchange.createFault();
                     fault.setProperty(JbiConstants.PROTOCOL_HEADERS, getHeaders(method));
                     jbiMarshaler.toNMS(fault, soapMessage);
                     exchange.setFault(fault);
-                    exchange.setStatus(ExchangeStatus.ERROR);
                     channel.send(exchange);
                     return;
                 } else {

Modified: incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpAddressingTest.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpAddressingTest.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpAddressingTest.java (original)
+++ incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpAddressingTest.java Thu May 18 16:16:09 2006
@@ -15,7 +15,11 @@
  */
 package org.apache.servicemix.http;
 
+import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
 
 import javax.jbi.messaging.ExchangeStatus;
 import javax.jbi.messaging.InOut;
@@ -26,6 +30,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.servicemix.client.DefaultServiceMixClient;
 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
+import org.apache.servicemix.jbi.util.FileUtil;
 import org.apache.servicemix.tck.SpringTestSupport;
 import org.springframework.context.support.AbstractXmlApplicationContext;
 import org.w3c.dom.Node;
@@ -43,13 +48,13 @@
         me.getInMessage().setContent(new StreamSource(fis));
         client.sendSync(me);
         if (me.getStatus() == ExchangeStatus.ERROR) {
-            if (me.getFault() != null) {
-                fail("Received fault: " + new SourceTransformer().toString(me.getFault().getContent()));
-            } else if (me.getError() != null) {
+            if (me.getError() != null) {
                 throw me.getError();
             } else {
                 fail("Received ERROR status");
             }
+        } else if (me.getFault() != null) {
+            fail("Received fault: " + new SourceTransformer().toString(me.getFault().getContent()));
         } else {
             Node node = new SourceTransformer().toDOMNode(me.getOutMessage());
             logger.info(new SourceTransformer().toString(node));
@@ -58,14 +63,34 @@
         }
     }
     
+    public void testOkFromUrl() throws Exception {
+        URLConnection connection = new URL("http://localhost:8192/").openConnection();
+        connection.setDoOutput(true);
+        connection.setDoInput(true);
+        OutputStream os = connection.getOutputStream();
+        // Post the request file.
+        InputStream fis = getClass().getResourceAsStream("addressing-request.xml");
+        FileUtil.copyInputStream(fis, os);
+        // Read the response.
+        InputStream is = connection.getInputStream();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        FileUtil.copyInputStream(is, baos);
+        System.err.println(baos.toString());
+    }
+    
     public void testBad() throws Exception {
+        // This test is bit weird, because the http consumer is not soap
+        // so it will just forward the HTTP error
+        //
+        // TODO: note that WSA based faults are not created
+        //
         DefaultServiceMixClient client = new DefaultServiceMixClient(jbi);
         InOut me = client.createInOutExchange();
         me.setService(new QName("http://test", "MyProviderService"));
         InputStream fis = getClass().getResourceAsStream("bad-addressing-request.xml");
         me.getInMessage().setContent(new StreamSource(fis));
         client.sendSync(me);
-        assertEquals(ExchangeStatus.ERROR, me.getStatus());
+        assertEquals(ExchangeStatus.ACTIVE, me.getStatus());
         assertNotNull(me.getFault());
         logger.info(new SourceTransformer().toString(me.getFault().getContent()));
     }

Modified: incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpSoapTest.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpSoapTest.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpSoapTest.java (original)
+++ incubator/servicemix/trunk/servicemix-http/src/test/java/org/apache/servicemix/http/HttpSoapTest.java Thu May 18 16:16:09 2006
@@ -37,9 +37,17 @@
 import org.apache.servicemix.components.util.TransformComponentSupport;
 import org.apache.servicemix.jbi.FaultException;
 import org.apache.servicemix.jbi.container.JBIContainer;
+import org.apache.servicemix.jbi.jaxp.SourceTransformer;
 import org.apache.servicemix.jbi.jaxp.StringSource;
 import org.apache.servicemix.jbi.resolver.ServiceNameEndpointResolver;
+import org.apache.servicemix.jbi.util.DOMUtil;
 import org.apache.servicemix.jbi.util.FileUtil;
+import org.apache.servicemix.soap.marshalers.SoapMarshaler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.ibm.wsdl.util.xml.DOMUtils;
 
 public class HttpSoapTest extends TestCase {
 
@@ -114,11 +122,11 @@
         
     }
 
-    public void testSoapFault() throws Exception {
+    public void testSoapFault12() throws Exception {
         TransformComponentSupport echo = new TransformComponentSupport() {
             protected boolean transform(MessageExchange exchange, NormalizedMessage in, NormalizedMessage out) throws MessagingException {
                 Fault f = exchange.createFault();
-                f.setContent(new StringSource("<hello>this is a fault</hello>"));
+                f.setContent(new StringSource("<hello xmlns='myuri'>this is a fault</hello>"));
                 throw new FaultException(null, exchange, f);
             }
         };
@@ -126,27 +134,117 @@
         echo.setEndpoint("echo");
         container.activateComponent(echo, "echo");
         
+        HttpEndpoint ep1 = new HttpEndpoint();
+        ep1.setService(new QName("urn:test", "http"));
+        ep1.setEndpoint("ep1");
+        ep1.setTargetService(new QName("urn:test", "echo"));
+        ep1.setTargetEndpoint("echo");
+        ep1.setLocationURI("http://localhost:8193/ep1/");
+        ep1.setRoleAsString("consumer");
+        ep1.setDefaultMep(URI.create("http://www.w3.org/2004/08/wsdl/in-out"));
+        ep1.setSoap(true);
+        
+        HttpEndpoint ep2 = new HttpEndpoint();
+        ep2.setService(new QName("urn:test", "http"));
+        ep2.setEndpoint("ep2");
+        ep2.setTargetService(new QName("urn:test", "http"));
+        ep2.setTargetEndpoint("ep3");
+        ep2.setLocationURI("http://localhost:8193/ep2/");
+        ep2.setRoleAsString("consumer");
+        ep2.setDefaultMep(URI.create("http://www.w3.org/2004/08/wsdl/in-out"));
+        ep2.setSoap(true);
+        
+        HttpEndpoint ep3 = new HttpEndpoint();
+        ep3.setService(new QName("urn:test", "http"));
+        ep3.setEndpoint("ep3");
+        ep3.setLocationURI("http://localhost:8193/ep1/");
+        ep3.setRoleAsString("provider");
+        ep3.setDefaultMep(URI.create("http://www.w3.org/2004/08/wsdl/in-out"));
+        ep3.setSoap(true);
+        
         HttpSpringComponent http = new HttpSpringComponent();
+        http.setEndpoints(new HttpEndpoint[] { ep1, ep2, ep3 });
+        container.activateComponent(http, "http1");
+        
+        container.start();
+        
+        PostMethod method = new PostMethod("http://localhost:8193/ep2/");
+        method.setRequestEntity(new InputStreamRequestEntity(getClass().getResourceAsStream("soap-request-12.xml")));
+        int state = new HttpClient().executeMethod(method);
+        assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, state);
+        SourceTransformer st = new SourceTransformer();
+        Node node = st.toDOMNode(new StreamSource(method.getResponseBodyAsStream()));
+        System.err.println(st.toString(node));
+
+        Element e = ((Document) node).getDocumentElement();
+        assertEquals(new QName(SoapMarshaler.SOAP_12_URI, SoapMarshaler.ENVELOPE), DOMUtil.getQName(e));
+        e = DOMUtil.getFirstChildElement(e);
+        assertEquals(new QName(SoapMarshaler.SOAP_12_URI, SoapMarshaler.BODY), DOMUtil.getQName(e));
+        e = DOMUtil.getFirstChildElement(e);
+        assertEquals(new QName(SoapMarshaler.SOAP_12_URI, SoapMarshaler.FAULT), DOMUtil.getQName(e));
+    }
+    
+    public void testSoapFault11() throws Exception {
+        TransformComponentSupport echo = new TransformComponentSupport() {
+            protected boolean transform(MessageExchange exchange, NormalizedMessage in, NormalizedMessage out) throws MessagingException {
+                Fault f = exchange.createFault();
+                f.setContent(new StringSource("<hello xmlns='myuri'>this is a fault</hello>"));
+                throw new FaultException(null, exchange, f);
+            }
+        };
+        echo.setService(new QName("urn:test", "echo"));
+        echo.setEndpoint("echo");
+        container.activateComponent(echo, "echo");
         
         HttpEndpoint ep1 = new HttpEndpoint();
-        ep1.setService(new QName("urn:test", "echo"));
-        ep1.setEndpoint("echo");
-        ep1.setLocationURI("http://localhost:8192/ep1/");
+        ep1.setService(new QName("urn:test", "http"));
+        ep1.setEndpoint("ep1");
+        ep1.setTargetService(new QName("urn:test", "echo"));
+        ep1.setTargetEndpoint("echo");
+        ep1.setLocationURI("http://localhost:8194/ep1/");
         ep1.setRoleAsString("consumer");
         ep1.setDefaultMep(URI.create("http://www.w3.org/2004/08/wsdl/in-out"));
         ep1.setSoap(true);
         
-        http.setEndpoints(new HttpEndpoint[] { ep1 });
+        HttpEndpoint ep2 = new HttpEndpoint();
+        ep2.setService(new QName("urn:test", "http"));
+        ep2.setEndpoint("ep2");
+        ep2.setTargetService(new QName("urn:test", "http"));
+        ep2.setTargetEndpoint("ep3");
+        ep2.setLocationURI("http://localhost:8194/ep2/");
+        ep2.setRoleAsString("consumer");
+        ep2.setDefaultMep(URI.create("http://www.w3.org/2004/08/wsdl/in-out"));
+        ep2.setSoap(true);
         
-        container.activateComponent(http, "http");
+        HttpEndpoint ep3 = new HttpEndpoint();
+        ep3.setService(new QName("urn:test", "http"));
+        ep3.setEndpoint("ep3");
+        ep3.setLocationURI("http://localhost:8194/ep1/");
+        ep3.setRoleAsString("provider");
+        ep3.setDefaultMep(URI.create("http://www.w3.org/2004/08/wsdl/in-out"));
+        ep3.setSoap(true);
+        
+        HttpSpringComponent http = new HttpSpringComponent();
+        http.setEndpoints(new HttpEndpoint[] { ep1, ep2, ep3 });
+        container.activateComponent(http, "http1");
         
         container.start();
         
-        PostMethod method = new PostMethod("http://localhost:8192/ep1/");
+        PostMethod method = new PostMethod("http://localhost:8194/ep2/");
         method.setRequestEntity(new InputStreamRequestEntity(getClass().getResourceAsStream("soap-request.xml")));
         int state = new HttpClient().executeMethod(method);
+        String str = method.getResponseBodyAsString();
+        System.err.println(str);
         assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, state);
-        FileUtil.copyInputStream(method.getResponseBodyAsStream(), System.out);
+        SourceTransformer st = new SourceTransformer();
+        Node node = st.toDOMNode(new StringSource(str));
+
+        Element e = ((Document) node).getDocumentElement();
+        assertEquals(new QName(SoapMarshaler.SOAP_11_URI, SoapMarshaler.ENVELOPE), DOMUtil.getQName(e));
+        e = DOMUtils.getFirstChildElement(e);
+        assertEquals(new QName(SoapMarshaler.SOAP_11_URI, SoapMarshaler.BODY), DOMUtil.getQName(e));
+        e = DOMUtils.getFirstChildElement(e);
+        assertEquals(new QName(SoapMarshaler.SOAP_11_URI, SoapMarshaler.FAULT), DOMUtil.getQName(e));
     }
 
 }

Modified: incubator/servicemix/trunk/servicemix-http/src/test/resources/org/apache/servicemix/http/addressing.xml
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-http/src/test/resources/org/apache/servicemix/http/addressing.xml?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-http/src/test/resources/org/apache/servicemix/http/addressing.xml (original)
+++ incubator/servicemix/trunk/servicemix-http/src/test/resources/org/apache/servicemix/http/addressing.xml Thu May 18 16:16:09 2006
@@ -31,7 +31,9 @@
       
       <sm:activationSpec service="test:MyConsumerService" endpoint="myConsumer">
         <sm:component>
-          <bean class="org.apache.servicemix.components.util.EchoComponent" />
+          <bean class="org.apache.servicemix.components.util.EchoComponent">
+            <property name="copyProperties" value="false" />
+          </bean>
         </sm:component>
       </sm:activationSpec>
 

Modified: incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapEndpoint.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapEndpoint.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapEndpoint.java (original)
+++ incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapEndpoint.java Thu May 18 16:16:09 2006
@@ -236,26 +236,41 @@
      * informations to it.
      */
     protected void retrieveProxiedEndpointDefinition() {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Retrieving proxied endpoint definition");
+        }
         try {
             ComponentContext ctx = this.serviceUnit.getComponent().getComponentContext();
             ServiceEndpoint ep = null;
             if (targetService != null && targetEndpoint != null) {
                 ep = ctx.getEndpoint(targetService, targetEndpoint);
+                if (ep == null && logger.isDebugEnabled()) {
+                    logger.debug("Could not retrieve endpoint targetService/targetEndpoint");
+                }
             }
             if (ep == null && targetService != null) {
                 ServiceEndpoint[] eps = ctx.getEndpointsForService(targetService);
                 if (eps != null && eps.length > 0) {
                     ep = eps[0];
                 }
+                if (ep == null && logger.isDebugEnabled()) {
+                    logger.debug("Could not retrieve endpoint for targetService");
+                }
             }
             if (ep == null && targetInterfaceName != null) {
                 ServiceEndpoint[] eps = ctx.getEndpoints(targetInterfaceName);
                 if (eps != null && eps.length > 0) {
                     ep = eps[0];
                 }
+                if (ep == null && logger.isDebugEnabled()) {
+                    logger.debug("Could not retrieve endpoint for targetInterfaceName");
+                }
             }
             if (ep == null && service != null && endpoint != null) {
                 ep = ctx.getEndpoint(service, endpoint);
+                if (ep == null && logger.isDebugEnabled()) {
+                    logger.debug("Could not retrieve endpoint for service/endpoint");
+                }
             }
             if (ep != null) {
                 Document doc = ctx.getEndpointDescriptor(ep);

Modified: incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapFault.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapFault.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapFault.java (original)
+++ incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/SoapFault.java Thu May 18 16:16:09 2006
@@ -15,8 +15,13 @@
  */
 package org.apache.servicemix.soap;
 
+import java.net.URI;
+
+import javax.xml.namespace.QName;
 import javax.xml.transform.Source;
 
+import org.apache.servicemix.soap.marshalers.SoapMarshaler;
+
 /**
  * Represents a SOAP fault which occurred while processing the
  * message.
@@ -29,51 +34,65 @@
 	
     private static final long serialVersionUID = 984561453557136677L;
     
-    public static final String SENDER = "Sender";
-	public static final String RECEIVER = "Receiver";
+    public static final QName SENDER = SoapMarshaler.SOAP_12_CODE_SENDER;
+	public static final QName RECEIVER = SoapMarshaler.SOAP_12_CODE_RECEIVER;
 	
-    private String code;
-    private String subcode;
+    private QName code;
+    private QName subcode;
     private String reason;
-    private String node;
-    private String role;
+    private URI node;
+    private URI role;
     private Source details;
 
     public SoapFault(Exception cause) {
         super(cause);
     }
 
-    public SoapFault(String code, String reason) {
+    public SoapFault(QName code, String reason) {
+        super(reason);
         this.code = code;
         this.reason = reason;
     }
 
-    public SoapFault(String code, String subcode, String reason) {
+    public SoapFault(QName code, QName subcode, String reason) {
+        super(reason);
         this.code = code;
         this.subcode = subcode;
         this.reason = reason;
     }
 
-    public SoapFault(String code, String reason, String node, String role) {
+    public SoapFault(QName code, String reason, URI node, URI role) {
+        super(reason);
+        this.code = code;
+        this.reason = reason;
+        this.node = node;
+        this.role = role;
+    }
+
+    public SoapFault(QName code, String reason, URI node, URI role, Source details) {
+        super(reason);
         this.code = code;
         this.reason = reason;
         this.node = node;
         this.role = role;
+        this.details = details;
     }
 
-    public SoapFault(String code, String reason, String node, String role, Source details) {
+    public SoapFault(QName code, QName subcode, String reason, URI node, URI role, Source details) {
+        super(reason);
         this.code = code;
+        this.subcode = subcode;
         this.reason = reason;
         this.node = node;
         this.role = role;
         this.details = details;
     }
 
-    public String getCode() {
+    public QName getCode() {
         return code;
     }
 
-    public String getSubcode() {
+    public QName getSubcode() {
         return subcode;
     }
 
@@ -81,15 +100,53 @@
         return reason;
     }
 
-    public String getNode() {
+    public URI getNode() {
         return node;
     }
 
-    public String getRole() {
+    public URI getRole() {
         return role;
     }
 
 	public Source getDetails() {
 		return details;
 	}
+
+    public void translateCodeTo11() {
+        if (code != null) {
+            if (subcode != null) {
+                code = subcode;
+                subcode = null;
+            } else if (SoapMarshaler.SOAP_12_CODE_DATAENCODINGUNKNOWN.equals(code)) {
+                code = SoapMarshaler.SOAP_11_CODE_CLIENT;
+            } else if (SoapMarshaler.SOAP_12_CODE_MUSTUNDERSTAND.equals(code)) {
+                code = SoapMarshaler.SOAP_11_CODE_MUSTUNDERSTAND;
+            } else if (SoapMarshaler.SOAP_12_CODE_RECEIVER.equals(code)) {
+                code = SoapMarshaler.SOAP_11_CODE_SERVER;
+            } else if (SoapMarshaler.SOAP_12_CODE_SENDER.equals(code)) {
+                code = SoapMarshaler.SOAP_11_CODE_CLIENT;
+            }
+        } else {
+            code = SoapMarshaler.SOAP_11_CODE_SERVER;
+        }
+    }
+
+    public void translateCodeTo12() {
+        if (code != null && subcode == null) {
+            if (SoapMarshaler.SOAP_11_CODE_CLIENT.equals(code)) {
+                code = SoapMarshaler.SOAP_12_CODE_SENDER;
+            } else if (SoapMarshaler.SOAP_11_CODE_MUSTUNDERSTAND.equals(code)) {
+                code = SoapMarshaler.SOAP_12_CODE_MUSTUNDERSTAND;
+            } else if (SoapMarshaler.SOAP_11_CODE_SERVER.equals(code)) {
+                code = SoapMarshaler.SOAP_12_CODE_RECEIVER;
+            } else if (SoapMarshaler.SOAP_11_CODE_VERSIONMISMATCH.equals(code)) {
+                code = SoapMarshaler.SOAP_12_CODE_VERSIONMISMATCH;
+            } else {
+                subcode = code;
+                code = SoapMarshaler.SOAP_12_CODE_SENDER;
+            }
+        } else if (code == null) {
+            code = SoapMarshaler.SOAP_12_CODE_RECEIVER;
+        }
+    }
 }

Modified: incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java (original)
+++ incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java Thu May 18 16:16:09 2006
@@ -15,15 +15,18 @@
  */
 package org.apache.servicemix.soap.marshalers;
 
+import java.net.URI;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
 import javax.activation.DataHandler;
+import javax.jbi.messaging.Fault;
 import javax.jbi.messaging.NormalizedMessage;
 import javax.xml.namespace.QName;
 
 import org.apache.servicemix.JbiConstants;
+import org.apache.servicemix.soap.SoapFault;
 import org.w3c.dom.DocumentFragment;
 
 /**
@@ -34,6 +37,12 @@
  */
 public class JBIMarshaler {
 
+    public static final String SOAP_FAULT_CODE = "org.apache.servicemix.soap.fault.code";
+    public static final String SOAP_FAULT_SUBCODE = "org.apache.servicemix.soap.fault.subcode";
+    public static final String SOAP_FAULT_REASON = "org.apache.servicemix.soap.fault.reason";
+    public static final String SOAP_FAULT_NODE = "org.apache.servicemix.soap.fault.node";
+    public static final String SOAP_FAULT_ROLE = "org.apache.servicemix.soap.fault.role";
+    
 	public void toNMS(NormalizedMessage normalizedMessage, SoapMessage soapMessage) throws Exception {
     	if (soapMessage.hasHeaders()) {
     		normalizedMessage.setProperty(JbiConstants.SOAP_HEADERS, soapMessage.getHeaders());
@@ -46,7 +55,21 @@
         										(DataHandler) entry.getValue());
         	}
         }
-        normalizedMessage.setContent(soapMessage.getSource());
+        normalizedMessage.setSecuritySubject(soapMessage.getSubject());
+        if (soapMessage.getFault() != null) {
+            if (normalizedMessage instanceof Fault == false) {
+                throw new IllegalStateException("The soap message is a fault but the jbi message is not");
+            }
+            SoapFault fault = soapMessage.getFault();
+            normalizedMessage.setProperty(SOAP_FAULT_CODE, fault.getCode());
+            normalizedMessage.setProperty(SOAP_FAULT_SUBCODE, fault.getSubcode());
+            normalizedMessage.setProperty(SOAP_FAULT_REASON, fault.getReason());
+            normalizedMessage.setProperty(SOAP_FAULT_NODE, fault.getNode());
+            normalizedMessage.setProperty(SOAP_FAULT_ROLE, fault.getRole());
+            normalizedMessage.setContent(fault.getDetails());
+        } else {
+            normalizedMessage.setContent(soapMessage.getSource());
+        }
 	}
 	
 	public void fromNMS(SoapMessage soapMessage, NormalizedMessage normalizedMessage) {
@@ -63,7 +86,17 @@
 			DataHandler handler = normalizedMessage.getAttachment(id);
 			soapMessage.addAttachment(id, handler);
 		}
-		soapMessage.setSource(normalizedMessage.getContent());
+        if (normalizedMessage instanceof Fault) {
+            QName code = (QName) normalizedMessage.getProperty(SOAP_FAULT_CODE);
+            QName subcode = (QName) normalizedMessage.getProperty(SOAP_FAULT_SUBCODE);
+            String reason = (String) normalizedMessage.getProperty(SOAP_FAULT_REASON);
+            URI node = (URI) normalizedMessage.getProperty(SOAP_FAULT_NODE);
+            URI role = (URI) normalizedMessage.getProperty(SOAP_FAULT_ROLE);
+            SoapFault fault = new SoapFault(code, subcode, reason, node, role, normalizedMessage.getContent());
+            soapMessage.setFault(fault);
+        } else {
+            soapMessage.setSource(normalizedMessage.getContent());
+        }
 	}
 
 }

Modified: incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMarshaler.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMarshaler.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMarshaler.java (original)
+++ incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMarshaler.java Thu May 18 16:16:09 2006
@@ -15,6 +15,7 @@
  */
 package org.apache.servicemix.soap.marshalers;
 
+import javax.xml.namespace.QName;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLOutputFactory;
 
@@ -37,20 +38,49 @@
 	public static final String HEADER = "Header";
 	public static final String BODY = "Body";
 	public static final String FAULT = "Fault";
-
+    
+    public static final QName SOAP_11_FAULTCODE = new QName("faultcode");
+    public static final QName SOAP_11_FAULTSTRING = new QName("faultstring");
+    public static final QName SOAP_11_FAULTACTOR = new QName("faultactor");
+    public static final QName SOAP_11_FAULTDETAIL = new QName("detail");
+    public static final QName SOAP_11_CODE_VERSIONMISMATCH = new QName(SOAP_11_URI, "VersionMismatch");
+    public static final QName SOAP_11_CODE_MUSTUNDERSTAND = new QName(SOAP_11_URI, "MustUnderstand");
+    public static final QName SOAP_11_CODE_CLIENT = new QName(SOAP_11_URI, "Client");
+    public static final QName SOAP_11_CODE_SERVER = new QName(SOAP_11_URI, "Server");
+    
+    public static final QName SOAP_12_FAULTCODE = new QName(SOAP_12_URI, "Code");
+    public static final QName SOAP_12_FAULTSUBCODE = new QName(SOAP_12_URI, "Subcode");
+    public static final QName SOAP_12_FAULTVALUE = new QName(SOAP_12_URI, "Value");
+    public static final QName SOAP_12_FAULTREASON = new QName(SOAP_12_URI, "Reason");
+    public static final QName SOAP_12_FAULTTEXT = new QName(SOAP_12_URI, "Text");
+    public static final QName SOAP_12_FAULTNODE = new QName(SOAP_12_URI, "Node");
+    public static final QName SOAP_12_FAULTROLE = new QName(SOAP_12_URI, "Role");
+    public static final QName SOAP_12_FAULTDETAIL = new QName(SOAP_12_URI, "Detail");
+    public static final QName SOAP_12_CODE_DATAENCODINGUNKNOWN = new QName(SOAP_12_URI, "DataEncodingUnknown");
+    public static final QName SOAP_12_CODE_VERSIONMISMATCH = new QName(SOAP_12_URI, "VersionMismatch");
+    public static final QName SOAP_12_CODE_MUSTUNDERSTAND = new QName(SOAP_12_URI, "MustUnderstand");
+    public static final QName SOAP_12_CODE_RECEIVER = new QName(SOAP_12_URI, "Receiver");
+    public static final QName SOAP_12_CODE_SENDER = new QName(SOAP_12_URI, "Sender");
+    
 	protected XMLInputFactory inputFactory;
 	protected XMLOutputFactory outputFactory;
 	protected StAXSourceTransformer  sourceTransformer;
 	protected boolean repairingNamespace;
 	protected String prefix = SOAP_PREFIX;
 	protected boolean soap = true;
+    protected boolean useDom = false;
 	protected String soapUri = SOAP_12_URI;
 
 	public SoapMarshaler() {
 	}
 
-	public SoapMarshaler(boolean soap) {
+    public SoapMarshaler(boolean soap) {
+        this.soap = soap;
+    }
+
+	public SoapMarshaler(boolean soap, boolean useDom) {
 		this.soap = soap;
+        this.useDom = useDom;
 	}
 
     public XMLInputFactory getInputFactory() {
@@ -95,6 +125,20 @@
     	this.soap = soap;
     }
     
+    /**
+     * @return the useDom
+     */
+    public boolean isUseDom() {
+        return useDom;
+    }
+
+    /**
+     * @param useDom the useDom to set
+     */
+    public void setUseDom(boolean useDom) {
+        this.useDom = useDom;
+    }
+
     public String getPrefix() {
     	return prefix;
     }

Modified: incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMessage.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMessage.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMessage.java (original)
+++ incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapMessage.java Thu May 18 16:16:09 2006
@@ -15,10 +15,12 @@
  */
 package org.apache.servicemix.soap.marshalers;
 
+import java.security.Principal;
 import java.util.HashMap;
 import java.util.Map;
 
 import javax.activation.DataHandler;
+import javax.security.auth.Subject;
 import javax.xml.namespace.QName;
 import javax.xml.transform.Source;
 
@@ -40,8 +42,21 @@
 	private Map attachments;
 	private Map headers;
 	private SoapFault fault;
+    private Subject subject;
 	
-	public Map getAttachments() {
+	/**
+     * @return the subject
+     */
+    public Subject getSubject() {
+        return subject;
+    }
+    /**
+     * @param subject the subject to set
+     */
+    public void setSubject(Subject subject) {
+        this.subject = subject;
+    }
+    public Map getAttachments() {
 		return attachments;
 	}
 	public void setAttachments(Map attachments) {
@@ -99,5 +114,12 @@
 	public void setFault(SoapFault fault) {
 		this.fault = fault;
 	}
+    
+    public void addPrincipal(Principal principal) {
+        if (subject == null) {
+            subject = new Subject();
+        }
+        subject.getPrincipals().add(principal);
+    }
 	
 }

Modified: incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapReader.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapReader.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapReader.java (original)
+++ incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapReader.java Thu May 18 16:16:09 2006
@@ -18,6 +18,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.SequenceInputStream;
+import java.net.URI;
 import java.util.Properties;
 
 import javax.mail.Session;
@@ -26,18 +27,22 @@
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
 import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamSource;
 
 import org.apache.servicemix.jbi.jaxp.ExtendedXMLStreamReader;
 import org.apache.servicemix.jbi.jaxp.FragmentStreamReader;
 import org.apache.servicemix.jbi.jaxp.StaxSource;
 import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.apache.servicemix.jbi.util.DOMUtil;
 import org.apache.servicemix.soap.SoapFault;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
 
 /**
  * 
@@ -49,7 +54,7 @@
 
 	private SoapMarshaler marshaler;
   
-  protected static final Source EMPTY_CONTENT = new StringSource("<payload/>");
+    protected static final Source EMPTY_CONTENT = new StringSource("<payload/>");
 
 	public SoapReader(SoapMarshaler marshaler) {
 		this.marshaler = marshaler;
@@ -70,7 +75,11 @@
 
 	public SoapMessage read(InputStream is) throws Exception {
 		if (marshaler.isSoap()) {
-			return readSoap(is);
+            if (marshaler.isUseDom()) {
+                return readSoapUsingDom(is);
+            } else {
+                return readSoapUsingStax(is);
+            }
 		} else {
 			SoapMessage message = new SoapMessage();
 			message.setSource(new StreamSource(is));
@@ -78,7 +87,65 @@
 		}
 	}
 
-	private SoapMessage readSoap(InputStream is) throws Exception {
+    private SoapMessage readSoapUsingDom(InputStream is) throws Exception {
+        SoapMessage message = new SoapMessage();
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().parse(is);
+        Element env = doc.getDocumentElement();
+        QName envName = DOMUtil.getQName(env);
+        if (!envName.getLocalPart().equals(SoapMarshaler.ENVELOPE)) {
+            throw new SoapFault(SoapFault.SENDER, "Unrecognized element: "
+                    + envName + ". Expecting 'Envelope'.");
+        }
+        message.setEnvelopeName(envName);
+        // Check soap 1.1 or 1.2
+        String soapUri = envName.getNamespaceURI();
+        if (!SoapMarshaler.SOAP_11_URI.equals(soapUri) && !SoapMarshaler.SOAP_12_URI.equals(soapUri)) {
+            throw new SoapFault(SoapFault.SENDER, "Unrecognized namespace: " + soapUri
+                    + " for element 'Envelope'.");
+        }
+        // Check Headers
+        Element child = DOMUtil.getFirstChildElement(env);
+        if (DOMUtil.getQName(child).equals(new QName(soapUri, SoapMarshaler.HEADER))) {
+            parseHeaders(message, child);
+            child = DOMUtil.getNextSiblingElement(child);
+        }
+        // Check Body
+        if (!DOMUtil.getQName(child).equals(new QName(soapUri, SoapMarshaler.BODY))) {
+            throw new SoapFault(SoapFault.SENDER, "Unrecognized element: "
+                    + DOMUtil.getQName(child) + ". Expecting 'Body'.");
+        }
+        // Create Source for content
+        child = DOMUtil.getFirstChildElement(child);
+        if (child != null) {
+            QName childName = DOMUtil.getQName(child);
+            message.setBodyName(childName);
+            // Check for fault
+            if (childName.equals(new QName(soapUri, SoapMarshaler.FAULT))) {
+                message.setFault(readFaultUsingDom(child));
+            } else {
+                message.setSource(new DOMSource(child));
+            }
+        }
+        child = DOMUtil.getNextSiblingElement(child);
+        if (child != null) {
+            throw new SoapFault(SoapFault.RECEIVER, "Body element has more than one child element.");
+        }
+        return message;
+    }
+    
+    private void parseHeaders(SoapMessage message, Element headers) {
+        for (Element child = DOMUtil.getFirstChildElement(headers);
+             child != null;
+             child = DOMUtil.getNextSiblingElement(child)) {
+            DocumentFragment df = child.getOwnerDocument().createDocumentFragment();
+            df.appendChild(child.cloneNode(true));
+            message.addHeader(DOMUtil.getQName(child), df);
+        }
+    }
+    
+	private SoapMessage readSoapUsingStax(InputStream is) throws Exception {
 		SoapMessage message = new SoapMessage();
 		XMLStreamReader reader = marshaler.getInputFactory().createXMLStreamReader(is);
 		reader = new ExtendedXMLStreamReader(reader);
@@ -117,11 +184,152 @@
 		}
 		// Create Source for content
 		if (reader.nextTag() != XMLStreamConstants.END_ELEMENT) {
-			message.setBodyName(reader.getName());
-			message.setSource(new StaxSource(new FragmentStreamReader(reader)));
+            QName childName = reader.getName();
+            message.setBodyName(childName);
+            // Check for fault
+            if (childName.equals(new QName(soapUri, SoapMarshaler.FAULT))) {
+                message.setFault(readFaultUsingStax(reader));
+            } else {
+                message.setSource(new StaxSource(new FragmentStreamReader(reader)));
+            }
 		}
 		return message;
 	}
+    
+    private SoapFault readFaultUsingDom(Element element) throws SoapFault {
+        QName code = null;
+        QName subcode = null;
+        String reason = null;
+        URI node = null;
+        URI role = null;
+        Source details = null;
+        // Parse soap 1.1 faults
+        if (element.getNamespaceURI().equals(SoapMarshaler.SOAP_11_URI)) {
+            // Fault code
+            Element child = DOMUtil.getFirstChildElement(element);
+            checkElementName(child, SoapMarshaler.SOAP_11_FAULTCODE);
+            code = DOMUtil.createQName(child, DOMUtil.getElementText(child));
+            // Fault string
+            child = DOMUtil.getNextSiblingElement(child);
+            checkElementName(child, SoapMarshaler.SOAP_11_FAULTSTRING);
+            reason = DOMUtil.getElementText(child);
+            child = DOMUtil.getNextSiblingElement(child);
+            QName childname = DOMUtil.getQName(child);
+            // Fault actor
+            if (SoapMarshaler.SOAP_11_FAULTACTOR.equals(childname)) {
+                node = URI.create(DOMUtil.getElementText(child));
+                child = DOMUtil.getNextSiblingElement(child);
+                childname = DOMUtil.getQName(child);
+            }
+            // Fault details
+            if (SoapMarshaler.SOAP_11_FAULTDETAIL.equals(childname)) {
+                Element subchild = DOMUtil.getFirstChildElement(child);
+                if (subchild != null) {
+                    details = new DOMSource(subchild);
+                    subchild = DOMUtil.getNextSiblingElement(subchild);
+                    if (subchild != null) {
+                        throw new SoapFault(SoapFault.RECEIVER, "Multiple elements are not supported in Detail");
+                    }
+                }
+                child = DOMUtil.getNextSiblingElement(child);
+                childname = DOMUtil.getQName(child);
+            }
+            // Nothing should be left
+            if (childname != null) {
+                throw new SoapFault(SoapFault.SENDER, "Unexpected element: " + childname);
+            }
+        // Parse soap 1.2 faults
+        } else {
+            // Fault code
+            Element child = DOMUtil.getFirstChildElement(element);
+            checkElementName(child, SoapMarshaler.SOAP_12_FAULTCODE);
+            Element subchild = DOMUtil.getFirstChildElement(child);
+            checkElementName(subchild, SoapMarshaler.SOAP_12_FAULTVALUE);
+            code = DOMUtil.createQName(subchild, DOMUtil.getElementText(subchild));
+            if (!SoapMarshaler.SOAP_12_CODE_DATAENCODINGUNKNOWN.equals(code) &&
+                !SoapMarshaler.SOAP_12_CODE_MUSTUNDERSTAND.equals(code) &&
+                !SoapMarshaler.SOAP_12_CODE_RECEIVER.equals(code) &&
+                !SoapMarshaler.SOAP_12_CODE_SENDER.equals(code) &&
+                !SoapMarshaler.SOAP_12_CODE_VERSIONMISMATCH.equals(code)) {
+                throw new SoapFault(SoapFault.SENDER, "Unexpected fault code: " + code); 
+            }
+            subchild = DOMUtil.getNextSiblingElement(subchild);
+            if (subchild != null) {
+                checkElementName(subchild, SoapMarshaler.SOAP_12_FAULTSUBCODE);
+                Element subsubchild = DOMUtil.getFirstChildElement(subchild);
+                checkElementName(subsubchild, SoapMarshaler.SOAP_12_FAULTVALUE);
+                subcode = DOMUtil.createQName(subsubchild, DOMUtil.getElementText(subsubchild));
+                subsubchild = DOMUtil.getNextSiblingElement(subsubchild);
+                if (subsubchild != null) {
+                    checkElementName(subsubchild, SoapMarshaler.SOAP_12_FAULTSUBCODE);
+                    throw new SoapFault(SoapFault.RECEIVER, "Unsupported nested subcodes");
+                }
+            }
+            // Fault reason
+            child = DOMUtil.getNextSiblingElement(child);
+            checkElementName(child, SoapMarshaler.SOAP_12_FAULTREASON);
+            subchild = DOMUtil.getFirstChildElement(child);
+            checkElementName(subchild, SoapMarshaler.SOAP_12_FAULTTEXT);
+            reason = DOMUtil.getElementText(subchild);
+            subchild = DOMUtil.getNextSiblingElement(subchild);
+            if (subchild != null) {
+                throw new SoapFault(SoapFault.RECEIVER, "Unsupported multiple reasons");
+            }
+            // Fault node
+            child = DOMUtil.getNextSiblingElement(child);
+            QName childname = DOMUtil.getQName(child);
+            if (SoapMarshaler.SOAP_12_FAULTNODE.equals(childname)) {
+                node = URI.create(DOMUtil.getElementText(child));
+                child = DOMUtil.getNextSiblingElement(child);
+                childname = DOMUtil.getQName(child);
+            }
+            // Fault role
+            if (SoapMarshaler.SOAP_12_FAULTROLE.equals(childname)) {
+                role = URI.create(DOMUtil.getElementText(child));
+                child = DOMUtil.getNextSiblingElement(child);
+                childname = DOMUtil.getQName(child);
+            }
+            // Fault details
+            if (SoapMarshaler.SOAP_12_FAULTDETAIL.equals(childname)) {
+                subchild = DOMUtil.getFirstChildElement(child);
+                if (subchild != null) {
+                    details = new DOMSource(subchild);
+                    subchild = DOMUtil.getNextSiblingElement(subchild);
+                    if (subchild != null) {
+                        throw new SoapFault(SoapFault.RECEIVER, "Multiple elements are not supported in Detail");
+                    }
+                }
+                child = DOMUtil.getNextSiblingElement(child);
+                childname = DOMUtil.getQName(child);
+            }
+            // Nothing should be left
+            if (childname != null) {
+                throw new SoapFault(SoapFault.SENDER, "Unexpected element: " + childname);
+            }
+        }
+        SoapFault fault = new SoapFault(code, subcode, reason, node, role, details);
+        return fault;
+    }
+    
+    private SoapFault readFaultUsingStax(XMLStreamReader reader) throws SoapFault {
+        try {
+            FragmentStreamReader rh = new FragmentStreamReader(reader);
+            Document doc = (Document) marshaler.getSourceTransformer().toDOMNode(
+                    new StaxSource(rh));
+            return readFaultUsingDom(doc.getDocumentElement());
+        } catch (SoapFault e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SoapFault(e);
+        }
+    }
+    
+    private void checkElementName(Element element, QName expected) throws SoapFault {
+        QName name= DOMUtil.getQName(element);
+        if (!expected.equals(name)) {
+            throw new SoapFault(SoapFault.SENDER, "Expected element: " + expected + " but found " + name);
+        }            
+    }
 
 	private void parseHeaders(SoapMessage message, XMLStreamReader reader)
 			throws Exception {

Modified: incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapWriter.java
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapWriter.java?rev=407656&r1=407655&r2=407656&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapWriter.java (original)
+++ incubator/servicemix/trunk/servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/SoapWriter.java Thu May 18 16:16:09 2006
@@ -19,6 +19,7 @@
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Iterator;
@@ -34,6 +35,7 @@
 import javax.mail.internet.MimeMultipart;
 import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.Source;
@@ -103,7 +105,7 @@
                 if (message.getFault().getDetails() != null) {
                     XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(
                             message.getFault().getDetails());
-                    XMLStreamHelper.copy(reader, writer, marshaler.isRepairingNamespace());
+                    XMLStreamHelper.copy(reader, writer);
                 } else {
                     throw new IllegalStateException("Cannot write non xml faults for non soap messages");
                 }
@@ -176,7 +178,7 @@
             for (Iterator it = message.getHeaders().values().iterator(); it.hasNext();) {
                 DocumentFragment df = (DocumentFragment) it.next();
                 Element e = (Element) df.getFirstChild();
-                XMLStreamHelper.copy(new W3CDOMStreamReader(e), writer, marshaler.isRepairingNamespace());
+                XMLStreamHelper.copy(new W3CDOMStreamReader(e), writer);
             }
             writer.writeEndElement();
         }
@@ -193,7 +195,7 @@
 
     private void writeContents(XMLStreamWriter writer) throws Exception {
         XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(message.getSource());
-        XMLStreamHelper.copy(reader, writer, marshaler.isRepairingNamespace());
+        XMLStreamHelper.copy(reader, writer);
     }
 
     private void writeFault(XMLStreamWriter writer) throws Exception {
@@ -201,14 +203,52 @@
         String soapUri = envelope.getNamespaceURI();
         if (SoapMarshaler.SOAP_11_URI.equals(soapUri)) {
             writeSoap11Fault(writer);
-        } else {
+        } else if (SoapMarshaler.SOAP_12_URI.equals(soapUri)) {
             writeSoap12Fault(writer);
+        } else {
+            throw new IllegalStateException("Unknown soap namespace: " + soapUri);
         }
     }
 
     private void writeSoap11Fault(XMLStreamWriter writer) throws Exception {
-        // TODO
-        writeSoap12Fault(writer);
+        QName envelope = getEnvelopeName();
+        String soapUri = envelope.getNamespaceURI();
+        String soapPrefix = envelope.getPrefix();
+        writer.setPrefix(soapPrefix, soapUri);
+        SoapFault fault = message.getFault();
+        fault.translateCodeTo11();
+
+        writer.writeStartElement(soapPrefix, SoapMarshaler.FAULT, soapUri);
+        QName code = fault.getCode();
+        if (code != null) {
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTCODE);
+            XMLStreamHelper.writeTextQName(writer, code);
+            writer.writeEndElement();
+        }
+        String reason = fault.getReason();
+        if (reason == null && fault.getCause() != null) {
+            reason = fault.getCause().toString();
+        }
+        XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTSTRING);
+        if (reason != null) {
+            writer.writeCharacters(reason);
+        }
+        writer.writeEndElement();
+        URI node = fault.getNode();
+        if (node != null) {
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTACTOR);
+            writer.writeCharacters(node.toString());
+            writer.writeEndElement();
+        }
+        Source details = fault.getDetails();
+        if (details != null) {
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_11_FAULTDETAIL);
+            XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(details);
+            XMLStreamHelper.copy(reader, writer);
+            writer.writeEndElement();
+        }
+
+        writer.writeEndElement();
     }
 
     private void writeSoap12Fault(XMLStreamWriter writer) throws Exception {
@@ -217,19 +257,20 @@
         String soapPrefix = envelope.getPrefix();
         writer.setPrefix(soapPrefix, soapUri);
         SoapFault fault = message.getFault();
-
-        writer.writeStartElement(soapPrefix, "Fault", soapUri);
-        String code = fault.getCode();
+        fault.translateCodeTo12();
+        
+        writer.writeStartElement(soapPrefix, SoapMarshaler.FAULT, soapUri);
+        QName code = fault.getCode();
         if (code != null) {
-            writer.writeStartElement(soapPrefix, "Code", soapUri);
-            writer.writeStartElement(soapPrefix, "Value", soapUri);
-            writer.writeCharacters(soapPrefix + ":" + code);
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTCODE);
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTVALUE);
+            XMLStreamHelper.writeTextQName(writer, code);
             writer.writeEndElement();
-            String subcode = fault.getSubcode();
+            QName subcode = fault.getSubcode();
             if (subcode != null) {
-                writer.writeStartElement(soapPrefix, "Subcode", soapUri);
-                writer.writeStartElement(soapPrefix, "Value", soapUri);
-                writer.writeCharacters(subcode);
+                XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTSUBCODE);
+                XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTVALUE);
+                XMLStreamHelper.writeTextQName(writer, subcode);
                 writer.writeEndElement();
                 writer.writeEndElement();
             }
@@ -239,39 +280,39 @@
         if (reason == null && fault.getCause() != null) {
             reason = fault.getCause().toString();
         }
+        XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTREASON);
+        XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTTEXT);
+        writer.writeAttribute(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI, "lang", "en");
         if (reason != null) {
-            writer.writeStartElement(soapPrefix, "Reason", soapUri);
-            writer.writeStartElement(soapPrefix, "Text", soapUri);
-            writer.writeAttribute(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI, "lang", "en-US");
             writer.writeCharacters(reason);
-            writer.writeEndElement();
-            writer.writeEndElement();
         }
-        String node = fault.getNode();
+        writer.writeEndElement();
+        writer.writeEndElement();
+        URI node = fault.getNode();
         if (node != null) {
-            writer.writeStartElement(soapPrefix, "Node", soapUri);
-            writer.writeCharacters(node);
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTNODE);
+            writer.writeCharacters(node.toString());
             writer.writeEndElement();
         }
 
-        String role = fault.getRole();
+        URI role = fault.getRole();
         if (role != null) {
-            writer.writeStartElement(soapPrefix, "Role", soapUri);
-            writer.writeCharacters(role);
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTROLE);
+            writer.writeCharacters(role.toString());
             writer.writeEndElement();
         }
 
         Source details = fault.getDetails();
         if (details != null) {
-            writer.writeStartElement(soapPrefix, "Details", soapUri);
+            XMLStreamHelper.writeStartElement(writer, SoapMarshaler.SOAP_12_FAULTDETAIL);
             XMLStreamReader reader = marshaler.getSourceTransformer().toXMLStreamReader(details);
-            XMLStreamHelper.copy(reader, writer, marshaler.isRepairingNamespace());
+            XMLStreamHelper.copy(reader, writer);
             writer.writeEndElement();
         }
 
         writer.writeEndElement();
     }
-
+    
     protected QName getEnvelopeName() {
         QName name = message.getEnvelopeName();
         if (name == null) {
@@ -281,5 +322,5 @@
         }
         return name;
     }
-
+    
 }