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 2013/10/10 17:22:44 UTC

svn commit: r1531019 - in /cxf/branches/2.7.x-fixes: rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/runtime/ rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/ rt/bindings/corba/src/main/resources/schemas/wsdl/ systests/u...

Author: dkulp
Date: Thu Oct 10 15:22:44 2013
New Revision: 1531019

URL: http://svn.apache.org/r1531019
Log:
Merged revisions 1531017 via  git cherry-pick from
https://svn.apache.org/repos/asf/cxf/trunk

........
  r1531017 | dkulp | 2013-10-10 11:17:22 -0400 (Thu, 10 Oct 2013) | 6 lines

  [CXF-5254] Correct handling of wrapped and unwrapped sequences

  Corba Binding allows to set "wrapped" flag on sequences/arrays. It is
  used at runtime to correctly produce events related to Corba-XML
  mapping.

........

Added:
    cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaPrimitiveArrayEventProducer.java   (with props)
Modified:
    cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/runtime/CorbaStreamWriter.java
    cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructEventProducer.java
    cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructListener.java
    cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/resources/schemas/wsdl/corba-binding.xsd
    cxf/branches/2.7.x-fixes/systests/uncategorized/src/test/java/org/apache/cxf/systest/type_test/AbstractTypeTestClient5.java
    cxf/branches/2.7.x-fixes/testutils/src/main/resources/wsdl/type_test/type_test.xsd

Modified: cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/runtime/CorbaStreamWriter.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/runtime/CorbaStreamWriter.java?rev=1531019&r1=1531018&r2=1531019&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/runtime/CorbaStreamWriter.java (original)
+++ cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/runtime/CorbaStreamWriter.java Thu Oct 10 15:22:44 2013
@@ -36,6 +36,7 @@ import org.apache.cxf.binding.corba.Corb
 import org.apache.cxf.binding.corba.CorbaTypeMap;
 import org.apache.cxf.binding.corba.types.CorbaHandlerUtils;
 import org.apache.cxf.binding.corba.types.CorbaObjectHandler;
+import org.apache.cxf.binding.corba.types.CorbaStructListener;
 import org.apache.cxf.binding.corba.types.CorbaTypeListener;
 import org.apache.cxf.binding.corba.wsdl.ArgType;
 import org.apache.cxf.service.model.ServiceInfo;
@@ -104,6 +105,11 @@ public class CorbaStreamWriter implement
         } else {
             QName name = elements.pop();
             if ((name.equals(paramElement)) || (name.equals(wrapElementName))) {
+                // let the struct check if all members wer processed
+                // it is necessary for empty sequences with minOccurs=0 as last elements of struct
+                if (currentTypeListener instanceof CorbaStructListener) {
+                    currentTypeListener.processEndElement(name);
+                }
                 currentTypeListener = null;
             } else {
                 currentTypeListener.processEndElement(name);

Added: cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaPrimitiveArrayEventProducer.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaPrimitiveArrayEventProducer.java?rev=1531019&view=auto
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaPrimitiveArrayEventProducer.java (added)
+++ cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaPrimitiveArrayEventProducer.java Thu Oct 10 15:22:44 2013
@@ -0,0 +1,35 @@
+/**
+ * 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.binding.corba.types;
+
+import org.apache.cxf.service.model.ServiceInfo;
+import org.omg.CORBA.ORB;
+
+public class CorbaPrimitiveArrayEventProducer extends AbstractNoStartEndEventProducer {
+    
+    // No start and end elements for the array
+    public CorbaPrimitiveArrayEventProducer(CorbaObjectHandler h,
+                                               ServiceInfo service,
+                                               ORB orbRef) {
+        CorbaArrayHandler handler = (CorbaArrayHandler)h;
+        iterator = handler.getElements().iterator();
+        orb = orbRef;
+        serviceInfo = service;
+    }
+}

Propchange: cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaPrimitiveArrayEventProducer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructEventProducer.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructEventProducer.java?rev=1531019&r1=1531018&r2=1531019&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructEventProducer.java (original)
+++ cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructEventProducer.java Thu Oct 10 15:22:44 2013
@@ -18,8 +18,9 @@
  */
 package org.apache.cxf.binding.corba.types;
 
+import org.apache.cxf.binding.corba.wsdl.Abstractanonsequence;
+import org.apache.cxf.binding.corba.wsdl.Abstractsequence;
 import org.apache.cxf.service.model.ServiceInfo;
-
 import org.omg.CORBA.ORB;
 
 public class CorbaStructEventProducer extends AbstractStartEndEventProducer {
@@ -47,13 +48,31 @@ public class CorbaStructEventProducer ex
             event = currentEventProducer.next();
         } else if (iterator.hasNext()) {
             CorbaObjectHandler obj = iterator.next();
-            //Special case for primitive sequence inside struct
-            if ((obj instanceof CorbaSequenceHandler)
-                && (CorbaHandlerUtils.isPrimitiveIDLTypeSequence(obj))
-                && (!((CorbaSequenceHandler)obj).getElements().isEmpty())
-                && (!CorbaHandlerUtils.isOctets(obj.getType()))) {
-                currentEventProducer =
-                    new CorbaPrimitiveSequenceEventProducer(obj, serviceInfo, orb);
+            //Special case for wrapped/unwrapped arrays or sequences
+            boolean primitiveSequence = obj instanceof CorbaSequenceHandler
+                        && (!CorbaHandlerUtils.isOctets(obj.getType()));
+            boolean primitivearray = obj instanceof CorbaArrayHandler
+                        && (!CorbaHandlerUtils.isOctets(obj.getType()));
+            if (primitiveSequence || primitivearray) {
+                boolean wrapped = true;
+                if (obj.getType() instanceof Abstractanonsequence) {
+                    wrapped = ((Abstractanonsequence)obj.getType()).isWrapped();
+                } else if (obj.getType() instanceof Abstractsequence) {
+                    wrapped = ((Abstractsequence)obj.getType()).isWrapped();
+                }
+                if (obj instanceof CorbaSequenceHandler) {
+                    if (wrapped) {
+                        currentEventProducer = new CorbaSequenceEventProducer(obj, serviceInfo, orb);
+                    } else {
+                        currentEventProducer = new CorbaPrimitiveSequenceEventProducer(obj, serviceInfo, orb);
+                    }
+                } else {
+                    if (wrapped) {
+                        currentEventProducer = new CorbaArrayEventProducer(obj, serviceInfo, orb);
+                    } else {
+                        currentEventProducer = new CorbaPrimitiveArrayEventProducer(obj, serviceInfo, orb);
+                    }
+                }
             } else if (obj.getSimpleName().equals(obj.getIdlType().getLocalPart() + "_f")) { 
                 //some "special cases" we need to make sure are mapped correctly
 

Modified: cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructListener.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructListener.java?rev=1531019&r1=1531018&r2=1531019&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructListener.java (original)
+++ cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/java/org/apache/cxf/binding/corba/types/CorbaStructListener.java Thu Oct 10 15:22:44 2013
@@ -24,6 +24,9 @@ import javax.xml.namespace.QName;
 
 import org.apache.cxf.binding.corba.CorbaTypeMap;
 import org.apache.cxf.binding.corba.utils.CorbaUtils;
+import org.apache.cxf.binding.corba.wsdl.Abstractanonsequence;
+import org.apache.cxf.binding.corba.wsdl.Abstractsequence;
+import org.apache.cxf.binding.corba.wsdl.CorbaTypeImpl;
 import org.apache.cxf.binding.corba.wsdl.MemberType;
 import org.apache.cxf.binding.corba.wsdl.Struct;
 import org.apache.cxf.service.model.ServiceInfo;
@@ -56,7 +59,25 @@ public class CorbaStructListener extends
         depth++;
         if (currentTypeListener == null) {
             QName elName = name;
-            MemberType member = structMembers.get(memberCount);
+            MemberType member = null;
+            while (true) {
+                member = structMembers.get(memberCount++);
+                // if struct members are unwrapped sequences, there's a possibility of skipped
+                // members - we have a chance to "catch up" and add required (empty sequences) members
+                if (member.getName().equals(name.getLocalPart())
+                    || (member.isSetAnonschematype() && member.isAnonschematype())) {
+                    break;
+                } else {
+                    currentTypeListener =
+                        CorbaHandlerUtils.getTypeListener(elName,
+                                                          member.getIdltype(),
+                                                          typeMap,
+                                                          orb,
+                                                          serviceInfo);
+                    currentTypeListener.setNamespaceContext(ctx);
+                    ((CorbaStructHandler)handler).addMember(currentTypeListener.getCorbaObject());
+                }
+            }
             boolean anonType = false;
             if (member.isSetAnonschematype() && member.isAnonschematype()) {
                 anonType = true;
@@ -73,10 +94,22 @@ public class CorbaStructListener extends
                                                   serviceInfo);
             currentTypeListener.setNamespaceContext(ctx);
             ((CorbaStructHandler)handler).addMember(currentTypeListener.getCorbaObject());
-            memberCount++;
             if (anonType) {
                 currentTypeListener.getCorbaObject().setAnonymousType(true);
                 currentTypeListener.processStartElement(name);
+            } else {
+                CorbaTypeImpl type = CorbaUtils.getCorbaType(member.getIdltype(), typeMap);
+                boolean wrapped = true;
+                if (type instanceof Abstractsequence) {
+                    wrapped = ((Abstractsequence)type).isWrapped();
+                } else if (type instanceof Abstractanonsequence) {
+                    wrapped = ((Abstractanonsequence)type).isWrapped();
+                }
+                // process unwrapped types (sequences and arrays) which do not have a chance
+                // to process StartElement of first element of collection
+                if (!wrapped) {
+                    currentTypeListener.processStartElement(name);
+                }
             }
         } else {
             currentTypeListener.processStartElement(name);
@@ -84,10 +117,30 @@ public class CorbaStructListener extends
     }
 
     public void processEndElement(QName name) {
-        if (currentTypeListener != null) {
+        if (depth > 0 && currentTypeListener != null) {
             currentTypeListener.processEndElement(name);
-            depth--;
+        } else if (depth == 0) {
+            // there will be no more nested elements,
+            // but maybe we should produce some minOccurs=0 elements (sequences)?
+            // this is possible if last element(s) of struct are empty sequences (which don't
+            // produce any elements
+            while (memberCount < this.structMembers.size()) {
+                MemberType member = this.structMembers.get(memberCount++);
+                // the "name" is wrong, but here it is irrelevant, as we do not process any XML elements
+                currentTypeListener =
+                    CorbaHandlerUtils.getTypeListener(name,
+                                                      member.getIdltype(),
+                                                      typeMap,
+                                                      orb,
+                                                      serviceInfo);
+                if (currentTypeListener instanceof CorbaSequenceListener) {
+                    // the sequence listener is only used to add empty sequence to the members of ths struct
+                    currentTypeListener.setNamespaceContext(ctx);
+                    ((CorbaStructHandler)handler).addMember(currentTypeListener.getCorbaObject());
+                }
+            }
         }
+        depth--;
     }
 
     public void processCharacters(String text) {

Modified: cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/resources/schemas/wsdl/corba-binding.xsd
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/resources/schemas/wsdl/corba-binding.xsd?rev=1531019&r1=1531018&r2=1531019&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/resources/schemas/wsdl/corba-binding.xsd (original)
+++ cxf/branches/2.7.x-fixes/rt/bindings/corba/src/main/resources/schemas/wsdl/corba-binding.xsd Thu Oct 10 15:22:44 2013
@@ -188,46 +188,56 @@
                         </xs:extension>
                 </xs:complexContent>
         </xs:complexType>
-        <xs:complexType name="anonsequence">
+        <xs:complexType name="abstractanonsequence" abstract="true">
                 <xs:annotation>
-                        <xs:documentation>Anonymous sequence type.</xs:documentation>
+                        <xs:documentation>abstract sequence of elements</xs:documentation>
                 </xs:annotation>
                 <xs:complexContent>
                         <xs:extension base="corba:corbaType">
                                 <xs:attribute name="elemtype" type="xs:QName" use="required"/>
                                 <xs:attribute name="bound" type="corba:ulong" use="required"/>
                                 <xs:attribute name="elemname" type="xs:QName" use="required"/>
+                                <xs:attribute name="wrapped" type="xs:boolean" default="true"/>
                         </xs:extension>
                 </xs:complexContent>
         </xs:complexType>
-        <xs:complexType name="sequence">
+        <xs:complexType name="abstractsequence" abstract="true">
+                <xs:annotation>
+                        <xs:documentation>abstract sequence of elements</xs:documentation>
+                </xs:annotation>
                 <xs:complexContent>
                         <xs:extension base="corba:namedType">
                                 <xs:attribute name="elemtype" type="xs:QName" use="required"/>
                                 <xs:attribute name="bound" type="corba:ulong" use="required"/>
                                 <xs:attribute name="elemname" type="xs:QName" use="required"/>
+                                <xs:attribute name="wrapped" type="xs:boolean" default="true"/>
                         </xs:extension>
                 </xs:complexContent>
         </xs:complexType>
+        <xs:complexType name="anonsequence">
+                <xs:annotation>
+                        <xs:documentation>Anonymous sequence type.</xs:documentation>
+                </xs:annotation>
+                <xs:complexContent>
+                        <xs:extension base="corba:abstractanonsequence" />
+                </xs:complexContent>
+        </xs:complexType>
+        <xs:complexType name="sequence">
+                <xs:complexContent>
+                        <xs:extension base="corba:abstractsequence" />
+                </xs:complexContent>
+        </xs:complexType>
         <xs:complexType name="anonarray">
                 <xs:annotation>
                         <xs:documentation>Anonymous array type.</xs:documentation>
                 </xs:annotation>
                 <xs:complexContent>
-                        <xs:extension base="corba:corbaType">
-                                <xs:attribute name="elemtype" type="xs:QName" use="required"/>
-                                <xs:attribute name="bound" type="corba:ulong" use="required"/>
-                                <xs:attribute name="elemname" type="xs:QName" use="required"/>
-                        </xs:extension>
+                        <xs:extension base="corba:abstractanonsequence" />
                 </xs:complexContent>
         </xs:complexType>
         <xs:complexType name="array">
                 <xs:complexContent>
-                        <xs:extension base="corba:namedType">
-                                <xs:attribute name="elemtype" type="xs:QName" use="required"/>
-                                <xs:attribute name="bound" type="corba:ulong" use="required"/>
-                                <xs:attribute name="elemname" type="xs:QName" use="required"/>
-                        </xs:extension>
+                        <xs:extension base="corba:abstractsequence" />
                 </xs:complexContent>
         </xs:complexType>
         <xs:complexType name="enumerator">

Modified: cxf/branches/2.7.x-fixes/systests/uncategorized/src/test/java/org/apache/cxf/systest/type_test/AbstractTypeTestClient5.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/uncategorized/src/test/java/org/apache/cxf/systest/type_test/AbstractTypeTestClient5.java?rev=1531019&r1=1531018&r2=1531019&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/systests/uncategorized/src/test/java/org/apache/cxf/systest/type_test/AbstractTypeTestClient5.java (original)
+++ cxf/branches/2.7.x-fixes/systests/uncategorized/src/test/java/org/apache/cxf/systest/type_test/AbstractTypeTestClient5.java Thu Oct 10 15:22:44 2013
@@ -18,6 +18,9 @@
  */
 package org.apache.cxf.systest.type_test;
 
+import java.util.Arrays;
+import java.util.List;
+
 import javax.xml.ws.Holder;
 
 import org.apache.type_test.types1.ComplexRestriction;
@@ -25,6 +28,11 @@ import org.apache.type_test.types1.Compl
 import org.apache.type_test.types1.ComplexRestriction3;
 import org.apache.type_test.types1.ComplexRestriction4;
 import org.apache.type_test.types1.ComplexRestriction5;
+import org.apache.type_test.types1.FixedArray;
+import org.apache.type_test.types1.MixedArray;
+import org.apache.type_test.types1.MixedArray.Array10;
+import org.apache.type_test.types1.MixedArray.Array9;
+import org.apache.type_test.types1.UnboundedArray;
 import org.junit.Test;
 
 public abstract class AbstractTypeTestClient5 extends AbstractTypeTestClient4 {
@@ -302,4 +310,203 @@ public abstract class AbstractTypeTestCl
         }
     }
 
+    //org.apache.type_test.types1.MixedArray
+
+    protected boolean equals(MixedArray x, MixedArray y) {
+        boolean simpleArraysEqual = x.getArray1().equals(y.getArray1())
+            && x.getArray3().equals(y.getArray3())
+            && x.getArray5().equals(y.getArray5())
+            && x.getArray7().equals(y.getArray7());
+        boolean complexArraysEqual = x.getArray2().getItem().equals(y.getArray2().getItem())
+            && x.getArray4().getItem().equals(y.getArray4().getItem())
+            && x.getArray6().getItem().equals(y.getArray6().getItem())
+            && x.getArray8().getItem().equals(y.getArray8().getItem())
+            && listsOfArray9equal(x.getArray9(), y.getArray9())
+            && listsOfArray10equal(x.getArray10(), y.getArray10());
+        return simpleArraysEqual && complexArraysEqual;
+    }
+
+    protected boolean listsOfArray9equal(List<Array9> x, List<Array9> y) {
+        if ((x == null && y == null) || (x == y)) {
+            return true;
+        }
+        if (x == null || y == null || x.size() != y.size()) {
+            return false;
+        }
+        for (int i = 0; i < x.size(); i++) {
+            Array9 a1 = x.get(i);
+            Array9 a2 = y.get(i);
+            if (a1 == null && a2 == null) {
+                continue;
+            }
+            if (a1 == null || a2 == null) {
+                return false;
+            }
+            if (a1.getItem() == null && a2.getItem() == null) {
+                continue;
+            }
+            if (a1.getItem() == null || a2.getItem() == null) {
+                return false;
+            }
+            if (!a1.getItem().equals(a2.getItem())) {
+                return false;
+            }
+        }
+        return true;
+    }
+    protected boolean listsOfArray10equal(List<Array10> x, List<Array10> y) {
+        if ((x == null && y == null) || (x == y)) {
+            return true;
+        }
+        if (x == null || y == null || x.size() != y.size()) {
+            return false;
+        }
+        for (int i = 0; i < x.size(); i++) {
+            Array10 a1 = x.get(i);
+            Array10 a2 = y.get(i);
+            if (a1 == null && a2 == null) {
+                continue;
+            }
+            if (a1 == null || a2 == null) {
+                return false;
+            }
+            if (a1.getItem() == null && a2.getItem() == null) {
+                continue;
+            }
+            if (a1.getItem() == null || a2.getItem() == null) {
+                return false;
+            }
+            if (!a1.getItem().equals(a2.getItem())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Test
+    public void testMixedArray() throws Exception {
+        if (!shouldRunTest("MixedArray")) {
+            return;
+        }
+        MixedArray x = new MixedArray();
+        x.getArray1().addAll(Arrays.asList("AAA", "BBB", "CCC"));
+        x.setArray2(new UnboundedArray());
+        x.getArray2().getItem().addAll(Arrays.asList("aaa", "bbb", "ccc"));
+        x.getArray3().addAll(Arrays.asList("DDD", "EEE", "FFF"));
+        x.setArray4(new FixedArray());
+        x.getArray4().getItem().addAll(Arrays.asList(1, 2, 3));
+        x.getArray5().addAll(Arrays.asList("GGG", "HHH", "III"));
+        x.setArray6(new MixedArray.Array6());
+        x.getArray6().getItem().addAll(Arrays.asList("ggg", "hhh", "iii"));
+        x.getArray7().addAll(Arrays.asList("JJJ", "KKK", "LLL"));
+        x.setArray8(new MixedArray.Array8());
+        x.getArray8().getItem().addAll(Arrays.asList(4, 5, 6));
+        Array9 array91 = new MixedArray.Array9();
+        Array9 array92 = new MixedArray.Array9();
+        Array9 array93 = new MixedArray.Array9();
+        array91.setItem("MMM");
+        array92.setItem("NNN");
+        array93.setItem("OOO");
+        x.getArray9().addAll(Arrays.asList(array91, array92, array93));
+        Array10 array101 = new MixedArray.Array10();
+        Array10 array102 = new MixedArray.Array10();
+        Array10 array103 = new MixedArray.Array10();
+        array101.setItem("PPP");
+        array102.setItem("QQQ");
+        array103.setItem("RRR");
+        x.getArray10().addAll(Arrays.asList(array101, array102, array103));
+        x.getArray11().addAll(Arrays.asList("AAA", "BBB", "CCC"));
+
+        MixedArray yOrig = new MixedArray();
+        yOrig.getArray1().addAll(Arrays.asList("XXX", "YYY", "ZZZ"));
+        yOrig.setArray2(new UnboundedArray());
+        yOrig.getArray2().getItem().addAll(Arrays.asList("xxx", "yyy", "zzz"));
+        yOrig.getArray3().addAll(Arrays.asList("DDD", "EEE", "FFF"));
+        yOrig.setArray4(new FixedArray());
+        yOrig.getArray4().getItem().addAll(Arrays.asList(1, 2, 3));
+        yOrig.getArray5().addAll(Arrays.asList("GGG", "HHH", "III"));
+        yOrig.setArray6(new MixedArray.Array6());
+        yOrig.getArray6().getItem().addAll(Arrays.asList("ggg", "hhh", "iii"));
+        yOrig.getArray7().addAll(Arrays.asList("JJJ", "KKK", "LLL"));
+        yOrig.setArray8(new MixedArray.Array8());
+        yOrig.getArray8().getItem().addAll(Arrays.asList(4, 5, 6));
+        array91 = new MixedArray.Array9();
+        array92 = new MixedArray.Array9();
+        array93 = new MixedArray.Array9();
+        array91.setItem("MMM");
+        array92.setItem("NNN");
+        array93.setItem("OOO");
+        yOrig.getArray9().addAll(Arrays.asList(array91, array92, array93));
+        array101 = new MixedArray.Array10();
+        array102 = new MixedArray.Array10();
+        array103 = new MixedArray.Array10();
+        array101.setItem("PPP");
+        array102.setItem("QQQ");
+        array103.setItem("RRR");
+        yOrig.getArray10().addAll(Arrays.asList(array101, array102, array103));
+        yOrig.getArray11().addAll(Arrays.asList("XXX", "YYY", "ZZZ"));
+
+        Holder<MixedArray> y = new Holder<MixedArray>(yOrig);
+        Holder<MixedArray> z = new Holder<MixedArray>();
+        MixedArray ret;
+        if (testDocLiteral) {
+            ret = docClient.testMixedArray(x, y, z);
+        } else if (testXMLBinding) {
+            ret = xmlClient.testMixedArray(x, y, z);
+        } else {
+            ret = rpcClient.testMixedArray(x, y, z);
+        }
+        if (!perfTestOnly) {
+            assertTrue("testMixedArray(): Incorrect value for inout param", equals(x, y.value));
+            assertTrue("testMixedArray(): Incorrect value for out param", equals(yOrig, z.value));
+            assertTrue("testMixedArray(): Incorrect return value", equals(x, ret));
+        }
+
+        // checkstyle complained otherwise...
+        assertEmptyCollectionsHandled(x, yOrig);
+    }
+
+    /**
+     * @param x
+     * @param yOrig
+     */
+    private void assertEmptyCollectionsHandled(MixedArray x, MixedArray yOrig) {
+        Holder<MixedArray> y;
+        Holder<MixedArray> z;
+        MixedArray ret;
+        // empty collections. may be tested only for sequences, i.e., for lists array1, array2, array5, array6,
+        // array9 and array11.
+        // array3, array4, array7, array8 and array10 must have 3 elements
+        // empty them
+        x.getArray1().clear();
+        x.setArray2(new UnboundedArray());
+        x.getArray5().clear();
+        x.setArray6(new MixedArray.Array6());
+        x.getArray9().clear();
+        x.getArray11().clear();
+
+        // empty them
+        yOrig.getArray1().clear();
+        yOrig.setArray2(new UnboundedArray());
+        yOrig.getArray5().clear();
+        yOrig.setArray6(new MixedArray.Array6());
+        yOrig.getArray9().clear();
+        yOrig.getArray11().clear();
+
+        y = new Holder<MixedArray>(yOrig);
+        z = new Holder<MixedArray>();
+        if (testDocLiteral) {
+            ret = docClient.testMixedArray(x, y, z);
+        } else if (testXMLBinding) {
+            ret = xmlClient.testMixedArray(x, y, z);
+        } else {
+            ret = rpcClient.testMixedArray(x, y, z);
+        }
+        if (!perfTestOnly) {
+            assertTrue("testMixedArray(): Incorrect value for inout param", equals(x, y.value));
+            assertTrue("testMixedArray(): Incorrect value for out param", equals(yOrig, z.value));
+            assertTrue("testMixedArray(): Incorrect return value", equals(x, ret));
+        }
+    }
+
 }

Modified: cxf/branches/2.7.x-fixes/testutils/src/main/resources/wsdl/type_test/type_test.xsd
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/testutils/src/main/resources/wsdl/type_test/type_test.xsd?rev=1531019&r1=1531018&r2=1531019&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/testutils/src/main/resources/wsdl/type_test/type_test.xsd (original)
+++ cxf/branches/2.7.x-fixes/testutils/src/main/resources/wsdl/type_test/type_test.xsd Thu Oct 10 15:22:44 2013
@@ -202,6 +202,71 @@
 		     type="string"/>
         </sequence>
     </complexType>
+    <complexType name="MixedArray">
+        <sequence>
+            <!-- unwrapped sequence -->
+            <element maxOccurs="unbounded" minOccurs="0" name="array1"
+		     type="string"/>
+            <!-- wrapped sequence -->
+            <element maxOccurs="1" minOccurs="1" name="array2"
+		     type="x1:UnboundedArray"/>
+            <!-- unwrapped array -->
+            <element maxOccurs="3" minOccurs="3" name="array3"
+		     type="string"/>
+            <!-- wrapped array -->
+            <element maxOccurs="1" minOccurs="1" name="array4"
+		     type="x1:FixedArray"/>
+            <!-- anonymous unwrapped sequence -->
+            <element maxOccurs="unbounded" minOccurs="0" name="array5">
+                <simpleType>
+                    <xsd:restriction base="string" />
+                </simpleType>
+            </element>
+            <!-- anonymous wrapped sequence -->
+            <element maxOccurs="1" minOccurs="1" name="array6">
+                <complexType>
+                    <sequence>
+                        <element maxOccurs="unbounded" minOccurs="0" name="item"
+                            type="string"/>
+                    </sequence>
+                </complexType>
+            </element>
+            <!-- anonymous unwrapped array -->
+            <element maxOccurs="3" minOccurs="3" name="array7">
+                <simpleType>
+                    <xsd:restriction base="string" />
+                </simpleType>
+            </element>
+            <!-- anonymous wrapped array -->
+            <element maxOccurs="1" minOccurs="1" name="array8">
+                <complexType>
+                    <sequence>
+                        <element maxOccurs="3" minOccurs="3" name="item"
+                            type="int"/>
+                    </sequence>
+                </complexType>
+            </element>
+            <!-- anonymous unwrapped, non-primitive sequence -->
+            <element maxOccurs="unbounded" minOccurs="0" name="array9">
+                <complexType>
+                    <sequence>
+                        <element name="item" type="string" />
+                    </sequence>
+                </complexType>
+            </element>
+            <!-- anonymous unwrapped, non-primitive array -->
+            <element maxOccurs="3" minOccurs="3" name="array10">
+                <complexType>
+                    <sequence>
+                        <element name="item" type="string" />
+                    </sequence>
+                </complexType>
+            </element>
+            <!-- unwrapped sequence - last sequence in containing complexType, which might have
+                 0 occurences in XML instance -->
+            <element maxOccurs="unbounded" minOccurs="0" name="array11" type="string"/>
+        </sequence>
+    </complexType>
     <complexType name="NestedArray">
         <sequence>
             <element maxOccurs="unbounded" minOccurs="0" name="subarray"