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 2009/11/02 18:30:53 UTC
svn commit: r831978 - in /cxf/trunk:
rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/
systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/
testutils/src/main/java/org/apache/hello_world_soap_http/
Author: dkulp
Date: Mon Nov 2 17:30:52 2009
New Revision: 831978
URL: http://svn.apache.org/viewvc?rev=831978&view=rev
Log:
[CXF-1277] Enable schema validation for RPC/Lit
Modified:
cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerRPCLitTest.java
cxf/trunk/testutils/src/main/java/org/apache/hello_world_soap_http/RPCLitGreeterImpl.java
Modified: cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java?rev=831978&r1=831977&r2=831978&view=diff
==============================================================================
--- cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java (original)
+++ cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java Mon Nov 2 17:30:52 2009
@@ -56,12 +56,15 @@
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.SOAPConstants;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.service.model.MessagePartInfo;
@@ -76,6 +79,85 @@
* Utility functions for JAXB.
*/
public final class JAXBEncoderDecoder {
+ private static final class AddXSITypeStreamReader extends StreamReaderDelegate {
+ private boolean first = true;
+ private final QName typeQName;
+
+ private AddXSITypeStreamReader(XMLStreamReader reader, QName typeQName) {
+ super(reader);
+ this.typeQName = typeQName;
+ }
+
+ public int getAttributeCount() {
+ return super.getAttributeCount() + (first ? 1 : 0);
+ }
+
+ public String getAttributeLocalName(int index) {
+ if (first && index == 0) {
+ return "type";
+ }
+ return super.getAttributeLocalName(index - 1);
+ }
+
+ public QName getAttributeName(int index) {
+ if (first && index == 0) {
+ return new QName(SOAPConstants.XSI_NS, "type");
+ }
+ return super.getAttributeName(index - 1);
+ }
+
+ public String getAttributeNamespace(int index) {
+ if (first && index == 0) {
+ return SOAPConstants.XSI_NS;
+ }
+ return super.getAttributeNamespace(index - 1);
+ }
+
+ public String getAttributePrefix(int index) {
+ if (first && index == 0) {
+ return "xsi";
+ }
+ return super.getAttributePrefix(index - 1);
+ }
+
+ public String getAttributeType(int index) {
+ if (first && index == 0) {
+ return "#TEXT";
+ }
+ return super.getAttributeType(index - 1);
+ }
+
+ public String getAttributeValue(int index) {
+ if (first && index == 0) {
+ String pfx = this.getNamespaceContext().getPrefix(typeQName.getNamespaceURI());
+ if (StringUtils.isEmpty(pfx)) {
+ return typeQName.getLocalPart();
+ }
+ return pfx + ":" + typeQName.getLocalPart();
+ }
+ return super.getAttributeValue(index);
+ }
+
+ public int next() throws XMLStreamException {
+ first = false;
+ return super.next();
+ }
+
+ public String getAttributeValue(String namespaceUri,
+ String localName) {
+ if (first
+ && SOAPConstants.XSI_NS.equals(namespaceUri)
+ && "type".equals(localName)) {
+ String pfx = this.getNamespaceContext().getPrefix(typeQName.getNamespaceURI());
+ if (StringUtils.isEmpty(pfx)) {
+ return typeQName.getLocalPart();
+ }
+ return pfx + ":" + typeQName.getLocalPart();
+ }
+ return super.getAttributeValue(namespaceUri, localName);
+ }
+ }
+
private static final Logger LOG = LogUtils.getLogger(JAXBEncoderDecoder.class);
private JAXBEncoderDecoder() {
@@ -144,6 +226,10 @@
writeObject(marshaller, source, new JAXBElement(elName, String.class, mObj));
} else if (mObj instanceof JAXBElement) {
writeObject(marshaller, source, mObj);
+ } else if (marshaller.getSchema() != null) {
+ //force xsi:type so types can be validated instead of trying to
+ //use the RPC/lit element names that aren't in the schema
+ writeObject(marshaller, source, new JAXBElement(elName, Object.class, mObj));
} else {
writeObject(marshaller, source, new JAXBElement(elName, cls, mObj));
}
@@ -528,6 +614,10 @@
String obj = (String)unmarshall(u, source, elName, String.class, unwrap);
return new HexBinaryAdapter().unmarshal(obj);
+ } else if (part != null && u.getSchema() != null
+ && !(part.getXmlSchema() instanceof XmlSchemaElement)) {
+ //Validating RPC/Lit, make sure we don't try a root element name thing
+ source = updateSourceWithXSIType(source, part.getTypeQName());
}
Object o = unmarshall(u, source, elName, clazz, unwrap);
@@ -539,6 +629,17 @@
return o;
}
+ private static Object updateSourceWithXSIType(Object source, final QName typeQName) {
+ if (source instanceof XMLStreamReader) {
+ XMLStreamReader reader = (XMLStreamReader)source;
+ String type = reader.getAttributeValue(SOAPConstants.XSI_NS, "type");
+ if (StringUtils.isEmpty(type)) {
+ source = new AddXSITypeStreamReader(reader, typeQName);
+ }
+ }
+ return source;
+ }
+
private static Object createSet(MessagePartInfo part, List<Object> ret) {
Type genericType = (Type)part.getProperty("generic.type");
Class tp2 = (Class)((ParameterizedType)genericType).getRawType();
@@ -551,6 +652,7 @@
} catch (Exception e) {
c = new HashSet<Object>();
}
+
c.addAll(ret);
return c;
}
Modified: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerRPCLitTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerRPCLitTest.java?rev=831978&r1=831977&r2=831978&view=diff
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerRPCLitTest.java (original)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/ClientServerRPCLitTest.java Mon Nov 2 17:30:52 2009
@@ -32,6 +32,7 @@
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
+import javax.xml.bind.UnmarshalException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@@ -39,8 +40,10 @@
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Endpoint;
+import javax.xml.ws.soap.SOAPFaultException;
import javax.xml.xpath.XPathConstants;
import org.w3c.dom.Document;
@@ -154,15 +157,25 @@
in.setElem3(45);
try {
+ ((BindingProvider)greeter).getRequestContext().put("schema-validation-enabled", Boolean.TRUE);
MyComplexStruct out = greeter.sendReceiveData(in);
assertNotNull("no response received from service", out);
assertEquals(in.getElem1(), out.getElem1());
assertEquals(in.getElem2(), out.getElem2());
assertEquals(in.getElem3(), out.getElem3());
+
+
+
} catch (UndeclaredThrowableException ex) {
throw (Exception) ex.getCause();
}
+ try {
+ in.setElem2("invalid");
+ greeter.sendReceiveData(in);
+ } catch (SOAPFaultException f) {
+ assertTrue(f.getCause() instanceof UnmarshalException);
+ }
}
@Test
Modified: cxf/trunk/testutils/src/main/java/org/apache/hello_world_soap_http/RPCLitGreeterImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/testutils/src/main/java/org/apache/hello_world_soap_http/RPCLitGreeterImpl.java?rev=831978&r1=831977&r2=831978&view=diff
==============================================================================
--- cxf/trunk/testutils/src/main/java/org/apache/hello_world_soap_http/RPCLitGreeterImpl.java (original)
+++ cxf/trunk/testutils/src/main/java/org/apache/hello_world_soap_http/RPCLitGreeterImpl.java Mon Nov 2 17:30:52 2009
@@ -49,6 +49,9 @@
System.out.println("Executing operation sendReceiveData");
System.out.println("Received struct with values :\nElement-1 : " + in.getElem1() + "\nElement-2 : "
+ in.getElem2() + "\nElement-3 : " + in.getElem3() + "\n");
+ if ("invalid".equals(in.getElem2())) {
+ in.setElem2(null);
+ }
return in;
}