You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by em...@apache.org on 2018/08/27 03:35:29 UTC
[cxf] branch master updated: [CXF-7823]:JAXBEncoderDecoder doesn't respect @XmlType's propOrder in… (#437)
This is an automated email from the ASF dual-hosted git repository.
ema pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/master by this push:
new 354ab5e [CXF-7823]:JAXBEncoderDecoder doesn't respect @XmlType's propOrder in… (#437)
354ab5e is described below
commit 354ab5e7eb63aef3f7b213cb9637acf8f9274305
Author: jimma <em...@redhat.com>
AuthorDate: Mon Aug 27 11:35:26 2018 +0800
[CXF-7823]:JAXBEncoderDecoder doesn't respect @XmlType's propOrder in… (#437)
* [CXF-7823]:JAXBEncoderDecoder doesn't respect @XmlType's propOrder in Exception class
* [CXF-7823]:Fix test fauilure and typo
---
.../org/apache/cxf/jaxb/JAXBEncoderDecoder.java | 35 ++++++++++-
.../apache/cxf/systest/jaxb/TestServiceTest.java | 36 ++++++++++-
.../apache/cxf/systest/jaxb/service/ErrorData.java | 62 +++++++++++++++++++
.../jaxb/service/PropertyOrderException.java | 70 ++++++++++++++++++++++
.../cxf/systest/jaxb/service/TestService.java | 3 +
.../cxf/systest/jaxb/service/TestServiceImpl.java | 17 ++++++
6 files changed, 221 insertions(+), 2 deletions(-)
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 1e6ec27..15d476d 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
@@ -56,6 +56,7 @@ import javax.xml.bind.annotation.XmlAccessOrder;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.bind.attachment.AttachmentUnmarshaller;
@@ -425,7 +426,28 @@ public final class JAXBEncoderDecoder {
}
});
}
-
+ XmlType xmlType = cls.getAnnotation(XmlType.class);
+ if (xmlType != null && xmlType.propOrder().length > 1 && !xmlType.propOrder()[0].isEmpty()) {
+ final List<String> orderList = Arrays.asList(xmlType.propOrder());
+ Collections.sort(combinedMembers, new Comparator<Member>() {
+ public int compare(Member m1, Member m2) {
+ String m1Name = getName(m1);
+ String m2Name = getName(m2);
+ int m1Index = orderList.indexOf(m1Name);
+ int m2Index = orderList.indexOf(m2Name);
+ if (m1Index != -1 && m2Index != -1) {
+ return m1Index - m2Index;
+ }
+ if (m1Index == -1 && m2Index != -1) {
+ return 1;
+ }
+ if (m1Index != -1 && m2Index == -1) {
+ return -1;
+ }
+ return 0;
+ }
+ });
+ }
for (Member member : combinedMembers) {
if (member instanceof Field) {
Field f = (Field)member;
@@ -461,6 +483,17 @@ public final class JAXBEncoderDecoder {
}
}
+ private static String getName(Member m1) {
+ String m1Name = null;
+ if (m1 instanceof Field) {
+ m1Name = ((Field)m1).getName();
+ } else {
+ int idx = m1.getName().startsWith("get") ? 3 : 2;
+ String name = m1.getName().substring(idx);
+ m1Name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
+ }
+ return m1Name;
+ }
private static void writeArrayObject(Marshaller marshaller,
Object source,
QName mname,
diff --git a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/TestServiceTest.java b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/TestServiceTest.java
index a78ca34..e2d43da 100644
--- a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/TestServiceTest.java
+++ b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/TestServiceTest.java
@@ -28,9 +28,13 @@ import org.w3c.dom.Document;
import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.ext.logging.LoggingOutInterceptor;
+import org.apache.cxf.ext.logging.event.LogEvent;
+import org.apache.cxf.ext.logging.event.LogEventSender;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.systest.jaxb.model.ExtendedWidget;
import org.apache.cxf.systest.jaxb.model.Widget;
+import org.apache.cxf.systest.jaxb.service.PropertyOrderException;
import org.apache.cxf.systest.jaxb.service.TestService;
import org.apache.cxf.test.TestUtilities;
import org.apache.cxf.testutil.common.TestUtil;
@@ -44,7 +48,7 @@ import org.junit.Test;
@ContextConfiguration(locations = { "classpath:extrajaxbclass.xml" })
public class TestServiceTest extends AbstractJUnit4SpringContextTests {
static final String PORT = TestUtil.getPortNumber(TestServiceTest.class);
-
+ private static TestLoggingEventSender fault = new TestLoggingEventSender();
private TestUtilities testUtilities;
public TestServiceTest() {
@@ -73,7 +77,37 @@ public class TestServiceTest extends AbstractJUnit4SpringContextTests {
Assert.assertEquals(expected, widgetFromService);
}
+ @Test
+ public void testExceptionPropertyOrder() throws Throwable {
+ ((Bus)applicationContext.getBean("cxf")).getOutFaultInterceptors().add(new LoggingOutInterceptor(fault));
+ TestService testClient = getTestClient();
+ ((BindingProvider)testClient).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
+ "http://localhost:" + PORT
+ + "/service/TestEndpoint");
+ try {
+ testClient.echo("Exception");
+ } catch (PropertyOrderException e) {
+ Assert.assertTrue("Expect <message> element is before <data> element :" + fault.getMessage(),
+ fault.getMessage().indexOf("</message><data") > -1);
+ }
+ }
+
+ static class TestLoggingEventSender implements LogEventSender {
+ private String logMessage;
+
+ public String getMessage() {
+ return logMessage;
+ }
+ public void clearMessage() {
+ logMessage = null;
+ }
+ @Override
+ public void send(LogEvent event) {
+ logMessage = event.getPayload();
+ }
+ }
+
@Test
public void testSchema() throws Exception {
URL url = new URL("http://localhost:" + PORT + "/service/TestService?wsdl");
diff --git a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/ErrorData.java b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/ErrorData.java
new file mode 100644
index 0000000..5fe127f
--- /dev/null
+++ b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/ErrorData.java
@@ -0,0 +1,62 @@
+/**
+ * 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.systest.jaxb.service;
+
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType(name = "ErrorData")
+public class ErrorData implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+ private long code;
+ private String title;
+ private String description;
+
+ public ErrorData() {
+ }
+
+ public ErrorData(long code, String title, String description, String stack) {
+ this.code = code;
+ this.title = title;
+ this.description = description;
+ }
+
+ public long getCode() {
+ return code;
+ }
+
+ public void setCode(long code) {
+ this.code = code;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
diff --git a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/PropertyOrderException.java b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/PropertyOrderException.java
new file mode 100644
index 0000000..61ee4ce
--- /dev/null
+++ b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/PropertyOrderException.java
@@ -0,0 +1,70 @@
+/**
+ * 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.systest.jaxb.service;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "fault")
+@XmlType(name = "", propOrder = {
+ "message", "data"
+}, namespace = "")
+public class PropertyOrderException extends Exception implements java.io.Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @XmlElement(name = "message", required = true, nillable = true)
+ private String message;
+
+ @XmlElement(name = "data", required = true, nillable = true)
+ private ErrorData data;
+
+ public PropertyOrderException() {
+ this.data = new ErrorData();
+ this.message = null;
+ }
+
+ public PropertyOrderException(ErrorData data) {
+ this.data = data;
+ this.message = null;
+ }
+
+ public PropertyOrderException(String message) {
+ this.data = null;
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return this.message;
+ }
+
+ public ErrorData getData() {
+ return data;
+ }
+
+ public void setData(ErrorData data) {
+ this.data = data;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+}
diff --git a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestService.java b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestService.java
index 4eef3c2..1977e93 100644
--- a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestService.java
+++ b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestService.java
@@ -34,5 +34,8 @@ public interface TestService {
@WebMethod
void testExceptionMarshalling() throws TestServiceException;
+
+ @WebMethod
+ String echo(String test) throws PropertyOrderException;
}
diff --git a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestServiceImpl.java b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestServiceImpl.java
index 60f1395..fca13d4 100644
--- a/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestServiceImpl.java
+++ b/systests/databinding/src/test/java/org/apache/cxf/systest/jaxb/service/TestServiceImpl.java
@@ -19,6 +19,7 @@
package org.apache.cxf.systest.jaxb.service;
+import javax.jws.WebMethod;
import javax.jws.WebService;
import org.apache.cxf.systest.jaxb.model.ExtendedWidget;
@@ -35,6 +36,22 @@ public class TestServiceImpl implements TestService {
throw new TestServiceException("Your hovercraft is full of eels.");
}
+ @WebMethod
+ public String echo(String test) throws PropertyOrderException {
+ if ("Exception".equalsIgnoreCase(test)) {
+ PropertyOrderException exception = new PropertyOrderException();
+ ErrorData ed = new ErrorData();
+ ed.setCode(500);
+ ed.setDescription("Error happened");
+ ed.setTitle("Error title");
+ exception.setData(ed);
+ exception.setMessage("Exception message");
+ throw exception;
+
+ }
+ return test;
+ }
+
}