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;
+    }
+
 
 
 }