Repository: cxf Updated Branches: refs/heads/master 5e865b3f5 -> 4cd282670
[CXF-6162] Added support for group reference elements with nested sequence/choice elements. Also allowed nested sequence elements (still no support of choice/sequence with maxOccurs > 1) Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/4cd28267 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/4cd28267 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/4cd28267 Branch: refs/heads/master Commit: 4cd28267092129b3ea456fc436dd2a4f210b365f Parents: 5e865b3 Author: Andrii Nikitiuk <demonshi...@gmail.com> Authored: Wed Dec 17 16:20:37 2014 +0200 Committer: Daniel Kulp <dk...@apache.org> Committed: Wed Dec 17 14:36:31 2014 -0500 ---------------------------------------------------------------------- .../apache/cxf/javascript/JavascriptUtils.java | 28 +++++++- .../apache/cxf/javascript/Messages.properties | 4 ++ .../org/apache/cxf/javascript/ParticleInfo.java | 67 ++++++++++++++++++-- .../tools/wsdlto/javascript/hello_world.wsdl | 48 ++++++++++++++ 4 files changed, 139 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/4cd28267/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java ---------------------------------------------------------------------- diff --git a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java index 253e586..c22cd9c 100755 --- a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java +++ b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java @@ -38,6 +38,7 @@ import org.apache.cxf.common.xmlschema.SchemaCollection; import org.apache.cxf.common.xmlschema.XmlSchemaUtils; import org.apache.cxf.databinding.source.mime.MimeAttribute; import org.apache.cxf.wsdl.WSDLConstants; +import org.apache.ws.commons.schema.XmlSchema; import org.apache.ws.commons.schema.XmlSchemaAll; import org.apache.ws.commons.schema.XmlSchemaAnnotated; import org.apache.ws.commons.schema.XmlSchemaAny; @@ -49,6 +50,8 @@ import org.apache.ws.commons.schema.XmlSchemaComplexType; import org.apache.ws.commons.schema.XmlSchemaContent; import org.apache.ws.commons.schema.XmlSchemaContentModel; import org.apache.ws.commons.schema.XmlSchemaElement; +import org.apache.ws.commons.schema.XmlSchemaGroup; +import org.apache.ws.commons.schema.XmlSchemaGroupRef; import org.apache.ws.commons.schema.XmlSchemaObject; import org.apache.ws.commons.schema.XmlSchemaParticle; import org.apache.ws.commons.schema.XmlSchemaSequence; @@ -562,16 +565,37 @@ public class JavascriptUtils { * throw. We're not ready for groups yet. * @param object */ - public static XmlSchemaParticle getObjectParticle(XmlSchemaObject object, QName contextName) { + public static XmlSchemaParticle getObjectParticle(XmlSchemaObject object, QName contextName, + XmlSchema currentSchema) { if (!(object instanceof XmlSchemaParticle)) { unsupportedConstruct("NON_PARTICLE_CHILD", object.getClass().getSimpleName(), contextName, object); } + + if (object instanceof XmlSchemaGroupRef) { + QName groupName = ((XmlSchemaGroupRef) object).getRefName(); + XmlSchemaGroup group = currentSchema.getGroupByName(groupName); + if (group == null) { + unsupportedConstruct("MISSING_GROUP", + groupName.toString(), contextName, null); + } + + XmlSchemaParticle groupParticle = group.getParticle(); + + if (!(groupParticle instanceof XmlSchemaSequence)) { + unsupportedConstruct("GROUP_REF_UNSUPPORTED_TYPE", + groupParticle.getClass().getSimpleName(), contextName, groupParticle); + } + + return groupParticle; + } + if (!(object instanceof XmlSchemaElement) && !(object instanceof XmlSchemaAny) - && !(object instanceof XmlSchemaChoice)) { + && !(object instanceof XmlSchemaChoice) + && !(object instanceof XmlSchemaSequence)) { unsupportedConstruct("GROUP_CHILD", object.getClass().getSimpleName(), contextName, object); http://git-wip-us.apache.org/repos/asf/cxf/blob/4cd28267/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/Messages.properties ---------------------------------------------------------------------- diff --git a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/Messages.properties b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/Messages.properties index 120335f..4dea1b0 100644 --- a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/Messages.properties +++ b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/Messages.properties @@ -23,8 +23,12 @@ ABSTRACT_ELEMENT=JavaScript limitation: Abstract element {0} of {1}. {2} ELEMENT_SCHEMA_MISSING=Element {0} contained in missing schema. IMPOSSIBLE_GLOBAL_ITEM= JavaScript limitation: Element or xs:any at {0} used in a context that requires a global name, but it, and its type, are anonymous. MISSING_TYPE=Type {0} is missing from the WSDL schema for element {1}. {2} +MISSING_GROUP=Group {0} is missing from the WSDL schema for element {1}. {2} ELEMENT_DANGLING_REFERENCE= Element {0} refers to undefined element {1}. UNSUPPORTED_ATTRIBUTE_ITEM= Unsupported {0} in {1}. +SEQUENCE_ELEMENT_MULTI_OCCURS=Limitation: unsupported sequence element construct {0} with maxOccours > 1 found. GROUP_ELEMENT_MULTI_OCCURS=Limitation: unsupported group element construct {0} with maxOccours > 1 found. +SEQUENCE_ELEMENT_ANY=Limitation: unsupported any element inside nested sequence element construct {0} GROUP_ELEMENT_ANY=Limitation: unsupported any element inside group element construct {0} GROUP_CHILD=Limitation: unsupported construct {0} found in {1}. {2} +GROUP_REF_UNSUPPORTED_TYPE=Limitation: unsupported group type {0} found ref in {1}. Only allowed xs:sequence with default maxOccurs. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf/blob/4cd28267/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/ParticleInfo.java ---------------------------------------------------------------------- diff --git a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/ParticleInfo.java b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/ParticleInfo.java index 6fee422..0d36566 100644 --- a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/ParticleInfo.java +++ b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/ParticleInfo.java @@ -35,6 +35,8 @@ import org.apache.ws.commons.schema.XmlSchemaChoiceMember; import org.apache.ws.commons.schema.XmlSchemaElement; import org.apache.ws.commons.schema.XmlSchemaObject; import org.apache.ws.commons.schema.XmlSchemaParticle; +import org.apache.ws.commons.schema.XmlSchemaSequence; +import org.apache.ws.commons.schema.XmlSchemaSequenceMember; import org.apache.ws.commons.schema.XmlSchemaType; import org.apache.ws.commons.schema.constants.Constants; @@ -139,10 +141,13 @@ public final class ParticleInfo implements ItemInfo { SchemaCollection schemaCollection, NamespacePrefixAccumulator prefixAccumulator, QName contextName) { XmlSchemaParticle sequenceParticle = - JavascriptUtils.getObjectParticle(sequenceObject, contextName); + JavascriptUtils.getObjectParticle(sequenceObject, contextName, currentSchema); ParticleInfo elementInfo = new ParticleInfo(); XmlSchemaParticle realParticle = sequenceParticle; + elementInfo.setMinOccurs(sequenceParticle.getMinOccurs()); + elementInfo.setMaxOccurs(sequenceParticle.getMaxOccurs()); + if (sequenceParticle instanceof XmlSchemaElement) { XmlSchemaElement sequenceElement = (XmlSchemaElement)sequenceParticle; @@ -170,7 +175,8 @@ public final class ParticleInfo implements ItemInfo { List<XmlSchemaChoiceMember> items = choice.getItems(); for (XmlSchemaChoiceMember item : items) { - XmlSchemaObject schemaObject = (XmlSchemaObject)item; + XmlSchemaObject schemaObject = JavascriptUtils.getObjectParticle((XmlSchemaObject)item, contextName, + currentSchema); ParticleInfo childParticle = ParticleInfo.forLocalItem(schemaObject, currentSchema, schemaCollection, prefixAccumulator, contextName); @@ -180,13 +186,40 @@ public final class ParticleInfo implements ItemInfo { throw new UnsupportedConstruct(message.toString()); } - childParticle.minOccurs = 0; + childParticle.setMinOccurs(0); elementInfo.children.add(childParticle); } - } + } else if (sequenceParticle instanceof XmlSchemaSequence) { + XmlSchemaSequence nestedSequence = (XmlSchemaSequence)sequenceParticle; - elementInfo.minOccurs = sequenceParticle.getMinOccurs(); - elementInfo.maxOccurs = sequenceParticle.getMaxOccurs(); + if (sequenceParticle.getMaxOccurs() > 1) { + Message message = new Message("SEQUENCE_ELEMENT_MULTI_OCCURS", LOG, sequenceParticle + .getClass().getSimpleName()); + throw new UnsupportedConstruct(message.toString()); + } + + elementInfo.children = new LinkedList<>(); + + List<XmlSchemaSequenceMember> items = nestedSequence.getItems(); + for (XmlSchemaSequenceMember item : items) { + XmlSchemaObject schemaObject = JavascriptUtils.getObjectParticle((XmlSchemaObject)item, contextName, + currentSchema); + ParticleInfo childParticle = ParticleInfo.forLocalItem(schemaObject, currentSchema, schemaCollection, + prefixAccumulator, contextName); + + if (childParticle.isAny()) { + Message message = new Message("SEQUENCE_ELEMENT_ANY", LOG, sequenceParticle.getClass() + .getSimpleName()); + throw new UnsupportedConstruct(message.toString()); + } + + if (sequenceParticle.getMinOccurs() == 0) { + childParticle.setMinOccurs(0); + } + elementInfo.children.add(childParticle); + } + + } factoryCommon(realParticle, currentSchema, schemaCollection, prefixAccumulator, elementInfo); @@ -237,6 +270,8 @@ public final class ParticleInfo implements ItemInfo { elementInfo.isGroup = false; } else if (particle instanceof XmlSchemaChoice) { elementInfo.isGroup = true; + } else if (particle instanceof XmlSchemaSequence) { + elementInfo.isGroup = true; } else { // any elementInfo.any = true; elementInfo.xmlName = null; // unknown until runtime. @@ -383,10 +418,30 @@ public final class ParticleInfo implements ItemInfo { return minOccurs; } + private void setMinOccurs(long value) { + minOccurs = value; + + if (isGroup()) { + for (ParticleInfo child : getChildren()) { + child.setMinOccurs(value); + } + } + } + public long getMaxOccurs() { return maxOccurs; } + private void setMaxOccurs(long value) { + maxOccurs = value; + + if (isGroup()) { + for (ParticleInfo child : getChildren()) { + child.setMaxOccurs(value); + } + } + } + public boolean isArray() { return maxOccurs > 1; } http://git-wip-us.apache.org/repos/asf/cxf/blob/4cd28267/tools/wsdlto/frontend/javascript/src/test/resources/org/apache/cxf/tools/wsdlto/javascript/hello_world.wsdl ---------------------------------------------------------------------- diff --git a/tools/wsdlto/frontend/javascript/src/test/resources/org/apache/cxf/tools/wsdlto/javascript/hello_world.wsdl b/tools/wsdlto/frontend/javascript/src/test/resources/org/apache/cxf/tools/wsdlto/javascript/hello_world.wsdl index 35c6baf..c342321 100644 --- a/tools/wsdlto/frontend/javascript/src/test/resources/org/apache/cxf/tools/wsdlto/javascript/hello_world.wsdl +++ b/tools/wsdlto/frontend/javascript/src/test/resources/org/apache/cxf/tools/wsdlto/javascript/hello_world.wsdl @@ -178,6 +178,35 @@ under the License. </sequence> </complexType> </element> + <element name="testGroup"> + <complexType> + <sequence> + <group ref="x1:testGroup1"/> + </sequence> + </complexType> + </element> + <element name="testGroupResponse"> + <complexType> + <sequence> + <choice> + <group ref="x1:testGroup1"/> + <group ref="x1:testGroup2"/> + </choice> + </sequence> + </complexType> + </element> + <group name="testGroup1"> + <sequence> + <element name="arg0" type="string"/> + <element name="arg1" type="string"/> + </sequence> + </group> + <group name="testGroup2"> + <sequence> + <element name="arg2" type="string"/> + <element name="arg3" type="string"/> + </sequence> + </group> </schema> </wsdl:types> <wsdl:message name="sayHiRequest"> @@ -237,6 +266,12 @@ under the License. <wsdl:message name="testChoiceResponse"> <wsdl:part name="out" element="x1:testChoiceResponse"/> </wsdl:message> + <wsdl:message name="testGroupRequest"> + <wsdl:part name="in" element="x1:testGroup"/> + </wsdl:message> + <wsdl:message name="testGroupResponse"> + <wsdl:part name="out" element="x1:testGroupResponse"/> + </wsdl:message> <wsdl:portType name="Greeter"> <wsdl:operation name="sayHi"> @@ -272,6 +307,10 @@ under the License. <wsdl:input name="testChoiceRequest" message="tns:testChoiceRequest"/> <wsdl:output name="testChoiceResponse" message="tns:testChoiceResponse"/> </wsdl:operation> + <wsdl:operation name="testGroup"> + <wsdl:input name="testGroupRequest" message="tns:testGroupRequest"/> + <wsdl:output name="testGroupResponse" message="tns:testGroupResponse"/> + </wsdl:operation> </wsdl:portType> <wsdl:portType name="DocLitBare"> <wsdl:operation name="testDocLitBare"> @@ -356,6 +395,15 @@ under the License. <soap:body use="literal"/> </wsdl:output> </wsdl:operation> + <wsdl:operation name="testGroup"> + <soap:operation style="document"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> </wsdl:binding> <wsdl:binding name="Doc_Lit_Bare_SOAPBinding" type="tns:DocLitBare"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>