You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2008/05/28 22:24:49 UTC

svn commit: r661070 - in /cxf/branches/2.0.x-fixes: ./ common/common/src/main/java/org/apache/cxf/staxutils/ parent/ rt/core/src/main/java/org/apache/cxf/interceptor/ systests/src/test/java/org/apache/cxf/systest/type_test/soap/

Author: dkulp
Date: Wed May 28 13:24:48 2008
New Revision: 661070

URL: http://svn.apache.org/viewvc?rev=661070&view=rev
Log:
Merged revisions 661064 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r661064 | dkulp | 2008-05-28 16:02:59 -0400 (Wed, 28 May 2008) | 2 lines
  
  [CXF-1551, CXF-1614] Cache xml events when validating and flush them out only if validation succeeds
........

Added:
    cxf/branches/2.0.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/CachingXmlEventWriter.java
      - copied unchanged from r661064, cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/CachingXmlEventWriter.java
Modified:
    cxf/branches/2.0.x-fixes/   (props changed)
    cxf/branches/2.0.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
    cxf/branches/2.0.x-fixes/parent/pom.xml
    cxf/branches/2.0.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
    cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitClientTypeTest.java
    cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitServerImpl.java

Propchange: cxf/branches/2.0.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: cxf/branches/2.0.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java?rev=661070&r1=661069&r2=661070&view=diff
==============================================================================
--- cxf/branches/2.0.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java (original)
+++ cxf/branches/2.0.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java Wed May 28 13:24:48 2008
@@ -25,6 +25,7 @@
 import java.io.Writer;
 //import java.util.HashMap;
 //import java.util.Map;
+import java.util.Iterator;
 import java.util.logging.Logger;
 
 import javax.xml.namespace.NamespaceContext;
@@ -38,6 +39,12 @@
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.DTD;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.StartDocument;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 import javax.xml.transform.dom.DOMSource;
@@ -875,4 +882,113 @@
             LOG.severe(e.getMessage());
         }
     }
+    
+    
+    private static void writeStartElementEvent(XMLEvent event, XMLStreamWriter writer) 
+        throws XMLStreamException {
+        StartElement start = event.asStartElement();
+        QName name = start.getName();
+        String nsURI = name.getNamespaceURI();
+        String localName = name.getLocalPart();
+        String prefix = name.getPrefix();
+        
+        if (prefix != null) {
+            writer.writeStartElement(prefix, localName, nsURI);
+        } else if (nsURI != null) {
+            writer.writeStartElement(localName, nsURI);
+        } else {
+            writer.writeStartElement(localName);
+        }
+        Iterator it = start.getNamespaces();
+        while (it != null && it.hasNext()) {
+            writeEvent((XMLEvent)it.next(), writer);
+        }
+        
+        it = start.getAttributes();
+        while (it != null && it.hasNext()) {
+            writeAttributeEvent((Attribute)it.next(), writer);            
+        }
+    }
+    private static void writeAttributeEvent(XMLEvent event, XMLStreamWriter writer) 
+        throws XMLStreamException {
+        
+        Attribute attr = (Attribute)event;
+        QName name = attr.getName();
+        String nsURI = name.getNamespaceURI();
+        String localName = name.getLocalPart();
+        String prefix = name.getPrefix();
+        String value = attr.getValue();
+
+        if (prefix != null) {
+            writer.writeAttribute(prefix, nsURI, localName, value);
+        } else if (nsURI != null) {
+            writer.writeAttribute(nsURI, localName, value);
+        } else {
+            writer.writeAttribute(localName, value);
+        }
+    }
+
+    public static void writeEvent(XMLEvent event, XMLStreamWriter writer)
+        throws XMLStreamException {
+
+        switch (event.getEventType()) {
+        case XMLEvent.START_ELEMENT:
+            writeStartElementEvent(event, writer);
+            break;
+        case XMLEvent.END_ELEMENT:
+            writer.writeEndElement();
+            break;
+        case XMLEvent.ATTRIBUTE: 
+            writeAttributeEvent(event, writer);
+            break;
+        case XMLEvent.ENTITY_REFERENCE:
+            writer.writeEntityRef(((javax.xml.stream.events.EntityReference)event).getName());
+            break;
+        case XMLEvent.DTD:
+            writer.writeDTD(((DTD)event).getDocumentTypeDeclaration());
+            break;
+        case XMLEvent.PROCESSING_INSTRUCTION:
+            if (((javax.xml.stream.events.ProcessingInstruction)event).getData() != null) {
+                writer.writeProcessingInstruction(
+                    ((javax.xml.stream.events.ProcessingInstruction)event).getTarget(), 
+                    ((javax.xml.stream.events.ProcessingInstruction)event).getData());
+            } else {
+                writer.writeProcessingInstruction(
+                    ((javax.xml.stream.events.ProcessingInstruction)event).getTarget());
+            }
+            break;
+        case XMLEvent.NAMESPACE:
+            if (((Namespace)event).isDefaultNamespaceDeclaration()) {
+                writer.writeDefaultNamespace(((Namespace)event).getNamespaceURI());
+            } else {
+                writer.writeNamespace(((Namespace)event).getPrefix(),
+                                      ((Namespace)event).getNamespaceURI());
+            }
+            break;
+        case XMLEvent.COMMENT:
+            writer.writeComment(((javax.xml.stream.events.Comment)event).getText());
+            break;
+        case XMLEvent.CHARACTERS:
+        case XMLEvent.SPACE:
+            writer.writeCharacters(event.asCharacters().getData());
+            break;
+        case XMLEvent.CDATA:
+            writer.writeCData(event.asCharacters().getData());
+            break;
+        case XMLEvent.START_DOCUMENT:
+            if (((StartDocument)event).encodingSet()) {
+                writer.writeStartDocument(((StartDocument)event).getCharacterEncodingScheme(),
+                                          ((StartDocument)event).getVersion());
+
+            } else {
+                writer.writeStartDocument(((StartDocument)event).getVersion());
+            }
+            break;
+        case XMLEvent.END_DOCUMENT:
+            writer.writeEndDocument();
+            break;
+        default:
+            //shouldn't get here
+        }
+    }
 }

Modified: cxf/branches/2.0.x-fixes/parent/pom.xml
URL: http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/parent/pom.xml?rev=661070&r1=661069&r2=661070&view=diff
==============================================================================
--- cxf/branches/2.0.x-fixes/parent/pom.xml (original)
+++ cxf/branches/2.0.x-fixes/parent/pom.xml Wed May 28 13:24:48 2008
@@ -427,6 +427,17 @@
                     </exclusion>
                 </exclusions>
             </dependency>
+			<dependency>
+				<groupId>net.java.dev.stax-utils</groupId>
+				<artifactId>stax-utils</artifactId>
+				<version>20060502</version>
+				<exclusions>
+					<exclusion>
+						<groupId>com.bea.xml</groupId>
+						<artifactId>jsr173-ri</artifactId>
+					</exclusion>
+				</exclusions>
+			</dependency>
 
             <dependency>
                 <groupId>org.codehaus.woodstox</groupId>

Modified: cxf/branches/2.0.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java?rev=661070&r1=661069&r2=661070&view=diff
==============================================================================
--- cxf/branches/2.0.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java (original)
+++ cxf/branches/2.0.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AbstractOutDatabindingInterceptor.java Wed May 28 13:24:48 2008
@@ -26,6 +26,7 @@
 
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.XMLEvent;
 import javax.xml.validation.Schema;
 
 import org.apache.cxf.databinding.DataWriter;
@@ -40,6 +41,8 @@
 import org.apache.cxf.service.model.BindingInfo;
 import org.apache.cxf.service.model.BindingOperationInfo;
 import org.apache.cxf.service.model.MessagePartInfo;
+import org.apache.cxf.staxutils.CachingXmlEventWriter;
+import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.wsdl.EndpointReferenceUtils;
 
 public abstract class AbstractOutDatabindingInterceptor extends AbstractPhaseInterceptor<Message> {
@@ -62,8 +65,23 @@
                               BindingOperationInfo operation, MessageContentsList objs, 
                               List<MessagePartInfo> parts) {
         OutputStream out = message.getContent(OutputStream.class);
-        XMLStreamWriter xmlWriter = message.getContent(XMLStreamWriter.class);
+        XMLStreamWriter origXmlWriter = message.getContent(XMLStreamWriter.class);
         Service service = exchange.get(Service.class);
+        XMLStreamWriter xmlWriter = origXmlWriter;
+        CachingXmlEventWriter cache = null;
+        
+        if (shouldValidate(message) && !isRequestor(message)) {
+            //need to cache the events in case validation fails
+            cache = new CachingXmlEventWriter();
+            try {
+                cache.setNamespaceContext(origXmlWriter.getNamespaceContext());
+            } catch (XMLStreamException e) {
+                //ignorable, will just get extra namespace decls
+            }
+            xmlWriter = cache;
+            out = null;
+        }
+        
         if (out != null 
             && writeToOutputStream(message, operation.getBinding(), service)
             && !MessageUtils.isTrue(message.getContextualProperty(DISABLE_OUTPUTSTREAM_OPTIMIZATION))) {
@@ -94,6 +112,21 @@
                 }
             }
         }
+        if (cache != null) {
+            try {
+                for (XMLEvent event : cache.getEvents()) {
+                    StaxUtils.writeEvent(event, origXmlWriter);
+                }
+            } catch (XMLStreamException e) {
+                throw new Fault(e);
+            }
+        }
+    }
+    
+    
+    protected boolean shouldValidate(Message m) {
+        Object en = m.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
+        return Boolean.TRUE.equals(en) || "true".equals(en);
     }
     
     protected boolean writeToOutputStream(Message m, BindingInfo info, Service s) {
@@ -132,8 +165,7 @@
     }
 
     private void setSchemaOutMessage(Service service, Message message, DataWriter<?> writer) {
-        Object en = message.getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
-        if (Boolean.TRUE.equals(en) || "true".equals(en)) {
+        if (shouldValidate(message)) {
             Schema schema = EndpointReferenceUtils.getSchema(service.getServiceInfos().get(0));
             writer.setSchema(schema);
         }

Modified: cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitClientTypeTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitClientTypeTest.java?rev=661070&r1=661069&r2=661070&view=diff
==============================================================================
--- cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitClientTypeTest.java (original)
+++ cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitClientTypeTest.java Wed May 28 13:24:48 2008
@@ -18,14 +18,17 @@
  */
 package org.apache.cxf.systest.type_test.soap;
 
+import java.util.Arrays;
 import java.util.List;
 
 import javax.xml.namespace.QName;
 import javax.xml.soap.SOAPElement;
 import javax.xml.soap.SOAPFactory;
 import javax.xml.ws.Holder;
+import javax.xml.ws.soap.SOAPFaultException;
 
 import org.apache.cxf.systest.type_test.AbstractTypeTestClient5;
+import org.apache.type_test.types1.FixedArray;
 import org.apache.type_test.types2.StructWithAnyArrayLax;
 import org.apache.type_test.types2.StructWithAnyStrict;
 import org.junit.BeforeClass;
@@ -45,6 +48,24 @@
     }
 
     @Test
+    public void testValidationFailureOnServerOut() throws Exception {
+        FixedArray x = new FixedArray();
+        FixedArray yOrig = new FixedArray();
+        
+        x.getItem().addAll(Arrays.asList(24, 42, 2008));
+        yOrig.getItem().addAll(Arrays.asList(24, 0, 1));
+
+        Holder<FixedArray> y = new Holder<FixedArray>(yOrig);
+        Holder<FixedArray> z = new Holder<FixedArray>();
+        try {
+            docClient.testFixedArray(x, y, z);
+            fail("should have thrown exception");
+        } catch (SOAPFaultException ex) {
+            assertTrue(ex.getMessage(), ex.getMessage().contains("Marshalling"));
+        }
+    }
+    
+    @Test
     public void testStructWithAnyStrict() throws Exception {
         SOAPFactory factory = SOAPFactory.newInstance();
         SOAPElement elem = factory.createElement("StringElementQualified",

Modified: cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitServerImpl.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitServerImpl.java?rev=661070&r1=661069&r2=661070&view=diff
==============================================================================
--- cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitServerImpl.java (original)
+++ cxf/branches/2.0.x-fixes/systests/src/test/java/org/apache/cxf/systest/type_test/soap/SOAPDocLitServerImpl.java Wed May 28 13:24:48 2008
@@ -21,6 +21,7 @@
 
 import javax.jws.WebService;
 import javax.xml.ws.Endpoint;
+import javax.xml.ws.Holder;
 
 
 import org.apache.cxf.BusFactory;
@@ -28,6 +29,7 @@
 import org.apache.cxf.systest.type_test.TypeTestImpl;
 import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
 import org.apache.type_test.doc.TypeTestPortType;
+import org.apache.type_test.types1.FixedArray;
 
 public class SOAPDocLitServerImpl extends AbstractBusTestServerBase {
     
@@ -58,6 +60,22 @@
                 endpointInterface = "org.apache.type_test.doc.TypeTestPortType",
                 targetNamespace = "http://apache.org/type_test/doc",
                 wsdlLocation = "testutils/type_test/type_test_doclit_soap.wsdl")
-    class SOAPTypeTestImpl extends TypeTestImpl implements TypeTestPortType {
+    public class SOAPTypeTestImpl extends TypeTestImpl implements TypeTestPortType {
+        
+        //override so we can test some bad validation things
+        public FixedArray testFixedArray(
+                                         FixedArray x,
+                                         Holder<FixedArray> y,
+                                         Holder<FixedArray> z) {
+            z.value = new FixedArray();
+            z.value.getItem().addAll(y.value.getItem());
+            y.value = new FixedArray();
+            y.value.getItem().addAll(x.getItem());
+            if (x.getItem().get(0) == 24) {
+                y.value.getItem().add(0);
+                z.value.getItem().remove(0);
+            }
+            return x;
+        }
     }
 }