Repository: cxf Updated Branches: refs/heads/2.7.x-fixes db389bb01 -> 00a5137b2
CXF-6107 support unmarshaller aware xml stream reader Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/00a5137b Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/00a5137b Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/00a5137b Branch: refs/heads/2.7.x-fixes Commit: 00a5137b2d837e5710f35da83ba4d48291446ca9 Parents: db389bb Author: Jason Pell <[email protected]> Authored: Mon Nov 17 18:42:41 2014 +1100 Committer: Jason Pell <[email protected]> Committed: Mon Nov 17 18:42:41 2014 +1100 ---------------------------------------------------------------------- .../org/apache/cxf/jaxb/JAXBEncoderDecoder.java | 12 ++++ .../jaxb/UnmarshallerAwareXMLStreamReader.java | 29 +++++++++ .../cxf/jaxb/DocLiteralInInterceptorTest.java | 34 +++++++++- .../cxf/jaxb/FixNamespacesXMLStreamReader.java | 68 ++++++++++++++++++++ .../resources/GreetMeDocLiteralReqDiffNs.xml | 20 ++++++ 5 files changed, 160 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/00a5137b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java index 88b5cda..14904b7 100644 --- a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java +++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBEncoderDecoder.java @@ -835,6 +835,12 @@ public final class JAXBEncoderDecoder { DepthXMLStreamReader dr = (DepthXMLStreamReader)source; XMLStreamReader reader = dr.getReader(); + + // allows the XML Stream Reader to adjust it's behaviour based on the state of the unmarshaller + if (reader instanceof UnmarshallerAwareXMLStreamReader) { + ((UnmarshallerAwareXMLStreamReader) reader).setUnmarshaller(u); + } + if (u.getSchema() != null) { //validating, but we may need more namespaces reader = findExtraNamespaces(reader); @@ -843,6 +849,12 @@ public final class JAXBEncoderDecoder { .unmarshal(dr.getReader()); } else if (source instanceof XMLStreamReader) { XMLStreamReader reader = (XMLStreamReader)source; + + // allows the XML Stream Reader to adjust it's behaviour based on the state of the unmarshaller + if (reader instanceof UnmarshallerAwareXMLStreamReader) { + ((UnmarshallerAwareXMLStreamReader) reader).setUnmarshaller(u); + } + if (u.getSchema() != null) { //validating, but we may need more namespaces reader = findExtraNamespaces(reader); http://git-wip-us.apache.org/repos/asf/cxf/blob/00a5137b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/UnmarshallerAwareXMLStreamReader.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/UnmarshallerAwareXMLStreamReader.java b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/UnmarshallerAwareXMLStreamReader.java new file mode 100644 index 0000000..382acc0 --- /dev/null +++ b/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/UnmarshallerAwareXMLStreamReader.java @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.jaxb; + +import javax.xml.bind.Unmarshaller; + +/* + * A XML Stream Reader that adjusts it's behaviour based on the state of the unmarshaller. + */ +public interface UnmarshallerAwareXMLStreamReader { + void setUnmarshaller(Unmarshaller unmarshaller); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/00a5137b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/DocLiteralInInterceptorTest.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/DocLiteralInInterceptorTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/DocLiteralInInterceptorTest.java index 20eeea6..a45c89d 100644 --- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/DocLiteralInInterceptorTest.java +++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/DocLiteralInInterceptorTest.java @@ -19,18 +19,19 @@ package org.apache.cxf.jaxb; + import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBContext; +import javax.xml.bind.UnmarshalException; import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; - import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; import org.apache.cxf.binding.Binding; @@ -39,6 +40,7 @@ import org.apache.cxf.binding.BindingFactoryManager; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.endpoint.EndpointImpl; import org.apache.cxf.interceptor.DocLiteralInInterceptor; +import org.apache.cxf.interceptor.Fault; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.ExchangeImpl; @@ -59,6 +61,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; + import static org.easymock.EasyMock.createNiceControl; import static org.easymock.EasyMock.expect; @@ -92,13 +95,38 @@ public class DocLiteralInInterceptorTest extends Assert { @Test public void testInterceptorInboundWrapped() throws Exception { + XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader( + getTestStream(getClass(), "resources/GreetMeDocLiteralReq.xml")); + + testInterceptorInboundWrapped(reader); + } + + @Test + public void testInterceptorInboundWrappedDiffNs() throws Exception { + XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader( + getTestStream(getClass(), "resources/GreetMeDocLiteralReqDiffNs.xml")); + FixNamespacesXMLStreamReader fixNs = new FixNamespacesXMLStreamReader(reader); + testInterceptorInboundWrapped(fixNs); + } + + @Test + public void testInterceptorInboundWrappedDiffNsNoFix() throws Exception { + XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader( + getTestStream(getClass(), "resources/GreetMeDocLiteralReqDiffNs.xml")); + try { + testInterceptorInboundWrapped(reader); + } catch (Fault f) { + assertTrue(f.getCause() instanceof UnmarshalException); + } + } + + private void testInterceptorInboundWrapped(XMLStreamReader inReader) throws Exception { setUpUsingHelloWorld(); //WrappedInInterceptor interceptor = new WrappedInInterceptor(); DocLiteralInInterceptor interceptor = new DocLiteralInInterceptor(); - message.setContent(XMLStreamReader.class, XMLInputFactory.newInstance() - .createXMLStreamReader(getTestStream(getClass(), "resources/GreetMeDocLiteralReq.xml"))); + message.setContent(XMLStreamReader.class, inReader); XMLStreamReader reader = message.getContent(XMLStreamReader.class); // skip the start element of soap body StaxUtils.skipToStartOfElement(reader); http://git-wip-us.apache.org/repos/asf/cxf/blob/00a5137b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/FixNamespacesXMLStreamReader.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/FixNamespacesXMLStreamReader.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/FixNamespacesXMLStreamReader.java new file mode 100644 index 0000000..bb67737 --- /dev/null +++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/FixNamespacesXMLStreamReader.java @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.jaxb; + +import java.util.Collection; + +import javax.xml.bind.Unmarshaller; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.util.StreamReaderDelegate; + +import com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl; +import com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext; + +/** + * A sample of an unmarshaller aware xml stream reader that can adjust the namespace of elements read in, as long + * as the local name matches. Based on the same kind of thing for SAX encountered at + * + * http://stackoverflow.com/questions/277502/jaxb-how-to-ignore-namespace-during-unmarshalling-xml-document + */ +public class FixNamespacesXMLStreamReader extends StreamReaderDelegate implements UnmarshallerAwareXMLStreamReader { + private UnmarshallingContext ctx; + + public FixNamespacesXMLStreamReader(final XMLStreamReader delegate) { + super(delegate); + } + + public String getNamespaceURI() { + String localName = getLocalName(); + String namespace = super.getNamespaceURI(); + namespace = getMappedNamespace(localName, namespace); + return namespace; + } + + private String getMappedNamespace(String localName, String namespace) { + if (ctx != null) { + Collection<QName> expected = ctx.getCurrentExpectedElements(); + for (QName expectedQname : expected) { + if (localName.equals(expectedQname.getLocalPart())) { + return expectedQname.getNamespaceURI(); + } + } + } + return namespace; + } + + @Override + public void setUnmarshaller(Unmarshaller unmarshaller) { + this.ctx = ((UnmarshallerImpl) unmarshaller).getContext(); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/00a5137b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/resources/GreetMeDocLiteralReqDiffNs.xml ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/resources/GreetMeDocLiteralReqDiffNs.xml b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/resources/GreetMeDocLiteralReqDiffNs.xml new file mode 100644 index 0000000..c478583 --- /dev/null +++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/resources/GreetMeDocLiteralReqDiffNs.xml @@ -0,0 +1,20 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<ns4:greetMe xmlns:ns4="http://apache.org/hello_world_soap_http/types" + xmlns:ns3="http://apache.org/hello_world/data"><ns3:requestType>TestSOAPInputPMessage</ns3:requestType></ns4:greetMe>
