(CXF-6148) Added support for basic xsd:choice elements for JS generator. Covered with tests and improved tests. Added log message when not supported exception is raisen.
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/5122b2d0 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/5122b2d0 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/5122b2d0 Branch: refs/heads/3.0.x-fixes Commit: 5122b2d0111216d8fcc64dbdbcafd769413d2b5a Parents: 3c5f5a9 Author: Andrii Nikitiuk <[email protected]> Authored: Tue Dec 9 20:38:32 2014 +0200 Committer: Daniel Kulp <[email protected]> Committed: Fri Dec 12 14:37:01 2014 -0500 ---------------------------------------------------------------------- .../apache/cxf/javascript/JavascriptUtils.java | 12 ++++- .../apache/cxf/javascript/Messages.properties | 3 ++ .../org/apache/cxf/javascript/ParticleInfo.java | 48 +++++++++++++++++++- .../types/SchemaJavascriptBuilder.java | 28 ++++++++++-- .../wsdlto/javascript/WSDLToJavaScriptTest.java | 18 +++++++- .../tools/wsdlto/javascript/hello_world.wsdl | 44 ++++++++++++++++++ 6 files changed, 144 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/5122b2d0/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 a1c4ad9..253e586 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 @@ -338,6 +338,13 @@ public class JavascriptUtils { public void generateCodeToSerializeElement(ParticleInfo elementInfo, String referencePrefix, SchemaCollection schemaCollection) { + if (elementInfo.isGroup()) { + for (ParticleInfo childElement : elementInfo.getChildren()) { + generateCodeToSerializeElement(childElement, referencePrefix, schemaCollection); + } + return; + } + XmlSchemaType type = elementInfo.getType(); boolean nillable = elementInfo.isNillable(); boolean optional = elementInfo.isOptional(); @@ -563,9 +570,10 @@ public class JavascriptUtils { contextName, object); } if (!(object instanceof XmlSchemaElement) - && !(object instanceof XmlSchemaAny)) { + && !(object instanceof XmlSchemaAny) + && !(object instanceof XmlSchemaChoice)) { unsupportedConstruct("GROUP_CHILD", - object.getClass().getSimpleName(), contextName, + object.getClass().getSimpleName(), contextName, object); } http://git-wip-us.apache.org/repos/asf/cxf/blob/5122b2d0/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 1c08adc..120335f 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 @@ -25,3 +25,6 @@ IMPOSSIBLE_GLOBAL_ITEM= JavaScript limitation: Element or xs:any at {0} used in MISSING_TYPE=Type {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}. +GROUP_ELEMENT_MULTI_OCCURS=Limitation: unsupported group element construct {0} with maxOccours > 1 found. +GROUP_ELEMENT_ANY=Limitation: unsupported any element inside group element construct {0} +GROUP_CHILD=Limitation: unsupported construct {0} found in {1}. {2} http://git-wip-us.apache.org/repos/asf/cxf/blob/5122b2d0/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 c8631bd..445cf96 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 @@ -19,6 +19,8 @@ package org.apache.cxf.javascript; +import java.util.List; +import java.util.LinkedList; import java.util.logging.Logger; import javax.xml.namespace.QName; @@ -29,6 +31,8 @@ import org.apache.cxf.common.xmlschema.SchemaCollection; import org.apache.cxf.common.xmlschema.XmlSchemaUtils; import org.apache.ws.commons.schema.XmlSchema; import org.apache.ws.commons.schema.XmlSchemaElement; +import org.apache.ws.commons.schema.XmlSchemaChoice; +import org.apache.ws.commons.schema.XmlSchemaChoiceMember; import org.apache.ws.commons.schema.XmlSchemaObject; import org.apache.ws.commons.schema.XmlSchemaParticle; import org.apache.ws.commons.schema.XmlSchemaType; @@ -47,6 +51,10 @@ public final class ParticleInfo implements ItemInfo { // in the RPC case, we can have a type and no element. private XmlSchemaType type; private boolean empty; + + private boolean isGroup; + private List<ParticleInfo> children; + // These are exactly the same values as we find in the XmlSchemaElement. // there is no rationalization. But the accessors take care of business. private long minOccurs; @@ -149,6 +157,32 @@ public final class ParticleInfo implements ItemInfo { elementInfo.global = true; } elementInfo.nillable = ((XmlSchemaElement)realParticle).isNillable(); + } else if (sequenceParticle instanceof XmlSchemaChoice) { + XmlSchemaChoice choice = (XmlSchemaChoice)sequenceParticle; + + if (sequenceParticle.getMaxOccurs() > 1) { + Message message = new Message("GROUP_ELEMENT_MULTI_OCCURS", LOG, sequenceParticle + .getClass().getSimpleName()); + throw new UnsupportedConstruct(message.toString()); + } + + elementInfo.children = new LinkedList<>(); + + List<XmlSchemaChoiceMember> items = choice.getItems(); + for (XmlSchemaChoiceMember item : items) { + XmlSchemaObject schemaObject = (XmlSchemaObject)item; + ParticleInfo childParticle = ParticleInfo.forLocalItem(schemaObject, currentSchema, schemaCollection, + prefixAccumulator, contextName); + + if (childParticle.isAny()) { + Message message = new Message("GROUP_ELEMENT_ANY", LOG, sequenceParticle.getClass() + .getSimpleName()); + throw new UnsupportedConstruct(message.toString()); + } + + childParticle.minOccurs = 0; + elementInfo.children.add(childParticle); + } } elementInfo.minOccurs = sequenceParticle.getMinOccurs(); @@ -199,13 +233,17 @@ public final class ParticleInfo implements ItemInfo { elementInfo.defaultValue = schemaDefaultValue; factorySetupType(element, schemaCollection, elementInfo); + + elementInfo.isGroup = false; + } else if (particle instanceof XmlSchemaChoice) { + elementInfo.isGroup = true; } else { // any elementInfo.any = true; elementInfo.xmlName = null; // unknown until runtime. // TODO: multiple 'any' elementInfo.javascriptName = "any"; elementInfo.type = null; // runtime for any. - + elementInfo.isGroup = false; } } @@ -325,6 +363,14 @@ public final class ParticleInfo implements ItemInfo { this.type = type; } + public boolean isGroup() { + return isGroup; + } + + public List<ParticleInfo> getChildren() { + return children; + } + public boolean isEmpty() { return empty; } http://git-wip-us.apache.org/repos/asf/cxf/blob/5122b2d0/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java ---------------------------------------------------------------------- diff --git a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java index 403766a..3292672 100755 --- a/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java +++ b/rt/javascript/javascript-rt/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java @@ -156,6 +156,7 @@ public class SchemaJavascriptBuilder { domDeserializerFunction(element.getQName(), complexType); } } catch (UnsupportedConstruct usc) { + LOG.warning(usc.getMessage()); continue; // it could be empty, but the style checker // would complain. } @@ -189,7 +190,7 @@ public class SchemaJavascriptBuilder { for (XmlSchemaObject thing : items) { ParticleInfo itemInfo = ParticleInfo.forLocalItem(thing, xmlSchema, xmlSchemaCollection, prefixAccumulator, type.getQName()); - constructOneItem(type, elementPrefix, typeObjectName, itemInfo); + constructItem(type, elementPrefix, typeObjectName, itemInfo); } for (XmlSchemaAnnotated thing : attrs) { @@ -202,6 +203,18 @@ public class SchemaJavascriptBuilder { code.append(accessors.toString()); } + private void constructItem(XmlSchemaComplexType type, final String elementPrefix, + String typeObjectName, ParticleInfo itemInfo) { + if (!itemInfo.isGroup()) { + constructOneItem(type, elementPrefix, typeObjectName, itemInfo); + return; + } + + for (ParticleInfo childInfo : itemInfo.getChildren()) { + constructItem(type, elementPrefix, typeObjectName, childInfo); + } + } + private void constructOneItem(XmlSchemaComplexType type, final String elementPrefix, String typeObjectName, ItemInfo itemInfo) { @@ -396,7 +409,7 @@ public class SchemaJavascriptBuilder { } deserializeAny(type, itemInfo, nextItem); } else { - deserializeElement(type, contentElement); + deserializeElement(type, itemInfo); } } utils.appendLine("return newobject;"); @@ -528,9 +541,14 @@ public class SchemaJavascriptBuilder { utils.appendLine("newobject.setAny(anyHolder);"); } - private void deserializeElement(XmlSchemaComplexType type, XmlSchemaObject thing) { - ParticleInfo itemInfo = ParticleInfo.forLocalItem(thing, xmlSchema, xmlSchemaCollection, - prefixAccumulator, type.getQName()); + private void deserializeElement(XmlSchemaComplexType type, ParticleInfo itemInfo) { + if (itemInfo.isGroup()) { + for (ParticleInfo childElement : itemInfo.getChildren()) { + deserializeElement(type, childElement); + } + return; + } + XmlSchemaType itemType = itemInfo.getType(); boolean simple = itemType instanceof XmlSchemaSimpleType || JavascriptUtils.notVeryComplexType(itemType); http://git-wip-us.apache.org/repos/asf/cxf/blob/5122b2d0/tools/wsdlto/frontend/javascript/src/test/java/org/apache/cxf/tools/wsdlto/javascript/WSDLToJavaScriptTest.java ---------------------------------------------------------------------- diff --git a/tools/wsdlto/frontend/javascript/src/test/java/org/apache/cxf/tools/wsdlto/javascript/WSDLToJavaScriptTest.java b/tools/wsdlto/frontend/javascript/src/test/java/org/apache/cxf/tools/wsdlto/javascript/WSDLToJavaScriptTest.java index 15af869..872661c 100644 --- a/tools/wsdlto/frontend/javascript/src/test/java/org/apache/cxf/tools/wsdlto/javascript/WSDLToJavaScriptTest.java +++ b/tools/wsdlto/frontend/javascript/src/test/java/org/apache/cxf/tools/wsdlto/javascript/WSDLToJavaScriptTest.java @@ -32,7 +32,17 @@ import org.junit.Test; * */ public class WSDLToJavaScriptTest extends ProcessorTestBase { - + + public int countChar(String text, char symbol) { + int count = 0; + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) == symbol) { + count++; + } + } + return count; + } + // just run with a minimum of fuss. @Test public void testGeneration() throws Exception { @@ -52,6 +62,9 @@ public class WSDLToJavaScriptTest extends ProcessorTestBase { FileInputStream fis = new FileInputStream(resultFile); String javascript = IOUtils.readStringFromStream(fis); assertTrue(javascript.contains("xmlns:murble='http://apache.org/hello_world_soap_http'")); + assertEquals("Number of '{' does not match number of '}' in generated JavaScript.", + countChar(javascript, '{'), + countChar(javascript, '}')); } @Test @@ -72,6 +85,9 @@ public class WSDLToJavaScriptTest extends ProcessorTestBase { FileInputStream fis = new FileInputStream(resultFile); String javascript = IOUtils.readStringFromStream(fis); assertTrue(javascript.contains("xmlns:murble='http://apache.org/hello_world_soap_http'")); + assertEquals("Number of '{' does not match number of '}' in generated JavaScript.", + countChar(javascript, '{'), + countChar(javascript, '}')); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/5122b2d0/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 0378931..35c6baf 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 @@ -154,6 +154,30 @@ under the License. <attribute name="id" type="int"/> </complexType> </element> + <element name="testChoice"> + <complexType> + <sequence> + <element name="arg0" type="string"/> + <element name="arg1" type="string"/> + <choice> + <element name="arg2" type="string"/> + <element name="arg3" type="string"/> + </choice> + </sequence> + </complexType> + </element> + <element name="testChoiceResponse"> + <complexType> + <sequence> + <element name="arg0" type="string"/> + <element name="arg1" type="string"/> + <choice> + <element name="arg2" type="string"/> + <element name="arg3" type="string"/> + </choice> + </sequence> + </complexType> + </element> </schema> </wsdl:types> <wsdl:message name="sayHiRequest"> @@ -207,6 +231,13 @@ under the License. <wsdl:message name="testDocLitBareResponse"> <wsdl:part name="out" element="x1:BareDocumentResponse"/> </wsdl:message> + <wsdl:message name="testChoiceRequest"> + <wsdl:part name="in" element="x1:testChoice"/> + </wsdl:message> + <wsdl:message name="testChoiceResponse"> + <wsdl:part name="out" element="x1:testChoiceResponse"/> + </wsdl:message> + <wsdl:portType name="Greeter"> <wsdl:operation name="sayHi"> <wsdl:input name="sayHiRequest" message="tns:sayHiRequest"/> @@ -237,6 +268,10 @@ under the License. <wsdl:fault name="NoSuchCodeLitFault" message="tns:NoSuchCodeLitFault"/> <wsdl:fault name="BadRecordLitFault" message="tns:BadRecordLitFault"/> </wsdl:operation> + <wsdl:operation name="testChoice"> + <wsdl:input name="testChoiceRequest" message="tns:testChoiceRequest"/> + <wsdl:output name="testChoiceResponse" message="tns:testChoiceResponse"/> + </wsdl:operation> </wsdl:portType> <wsdl:portType name="DocLitBare"> <wsdl:operation name="testDocLitBare"> @@ -312,6 +347,15 @@ under the License. <soap:fault name="BadRecordLitFault" use="literal"/> </wsdl:fault> </wsdl:operation> + <wsdl:operation name="testChoice"> + <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"/>
