You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bi...@apache.org on 2007/10/31 14:33:52 UTC

svn commit: r590664 - in /incubator/cxf/trunk/rt: frontend/simple/src/main/java/org/apache/cxf/service/factory/ javascript/src/main/java/org/apache/cxf/javascript/ javascript/src/main/java/org/apache/cxf/javascript/types/ javascript/src/test/java/org/a...

Author: bimargulies
Date: Wed Oct 31 06:33:52 2007
New Revision: 590664

URL: http://svn.apache.org/viewvc?rev=590664&view=rev
Log:
After a titanous struggle, get the Javascript to generate correct serialization for the cross-namespace element case.
This may be working around mistakes in how the XmlSchema gets built, or it may not. I don't know enought JAXB to tell.


Modified:
    incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
    incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/SimpleMessages.properties
    incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java
    incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties
    incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java
    incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java

Modified: incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java?rev=590664&r1=590663&r2=590664&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java (original)
+++ incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java Wed Oct 31 06:33:52 2007
@@ -182,7 +182,16 @@
 
         return getService();
     }
-
+    
+    /**
+     * Code elsewhere in this function will fill in the name of the type of an element but not the reference
+     * to the type. This function fills in the type references.
+     * 
+     * This does not set the type reference for elements that are declared as refs to other elements.
+     * It is a giant pain to find them, since they are not (generally) root elements and the code would
+     * have to traverse all the types to find all of them. Users should look them up through the collection,
+     * that's what it is for.
+     */
     private void fillInSchemaCrossreferences() {
         Service service = getService();
         for (ServiceInfo serviceInfo : service.getServiceInfos()) {
@@ -212,36 +221,6 @@
                     }
                 }
                 
-            }
-            
-            // second pass. Fill in based on refs.
-            for (SchemaInfo schemaInfo : serviceInfo.getSchemas()) {
-                XmlSchemaObjectTable elementsTable = schemaInfo.getSchema().getElements();
-                Iterator elementsIterator = elementsTable.getNames();
-                while (elementsIterator.hasNext()) {
-                    QName elementName = (QName)elementsIterator.next();
-                    XmlSchemaElement element = schemaInfo.getSchema().getElementByName(elementName);
-                    if (element.getSchemaType() == null) {
-                        QName refElementName = element.getRefName();
-                        if (refElementName != null) {
-                            XmlSchemaElement refElement = 
-                                schemaCollection.getElementByQName(refElementName);
-                            if (refElement == null) {
-                                Message message = new Message("REFERENCE_TO_UNDEFINED_ELEMENT",
-                                                              LOG,
-                                                              element.getQName(),
-                                                              refElementName,
-                                                              service.getName());
-                                LOG.severe(message.toString());
-                            } else {
-                                // it is convenient for other consumers if we put the type in place.
-                                // we trust that anything generating XSD will avoid something stupid like:
-                                // <element ref='x' type='y'/> as a result.
-                                element.setSchemaType(refElement.getSchemaType());
-                            }
-                        }
-                    }
-                }
             }
         }
     }

Modified: incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/SimpleMessages.properties
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/SimpleMessages.properties?rev=590664&r1=590663&r2=590664&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/SimpleMessages.properties (original)
+++ incubator/cxf/trunk/rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/SimpleMessages.properties Wed Oct 31 06:33:52 2007
@@ -25,4 +25,3 @@
   annotations on the real instance are not available.  We suggest overriding the ServiceClass via spring config or \
   other configuration. (serviceClass/implementorClass attributes on the endpoint/server spring config entry)
 REFERENCE_TO_UNDEFINED_TYPE = Schema element {0} references undefined type {1} for service {2}.
-REFERENCE_TO_UNDEFINED_ELEMENT = Schema element {0} references undefined element {1} for service {2}.
\ No newline at end of file

Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java?rev=590664&r1=590663&r2=590664&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java Wed Oct 31 06:33:52 2007
@@ -25,6 +25,11 @@
 import java.util.Set;
 import java.util.Stack;
 
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.wsdl.WSDLConstants;
+import org.apache.ws.commons.schema.XmlSchemaType;
+
 /**
  * 
  */
@@ -53,10 +58,8 @@
         prefixStack.push("    ");
     }
     
-    // the next two functions operate by name to get around XmlSchema quirk.
-    
-    public String getDefaultValueForSimpleType(String typeName) {
-        String val = defaultValueForSimpleType.get(typeName);
+    public String getDefaultValueForSimpleType(XmlSchemaType type) {
+        String val = defaultValueForSimpleType.get(type.getName());
         if (val == null) { // ints and such return the appropriate 0.
             return "''";
         } else {
@@ -64,8 +67,9 @@
         }
     }
     
-    public boolean isStringSimpleType(String typeName) {
-        return !nonStringSimpleTypes.contains(typeName);
+    public boolean isStringSimpleType(QName typeName) {
+        return !(WSDLConstants.NU_SCHEMA_XSD.equals(typeName.getNamespaceURI()) 
+                 && nonStringSimpleTypes.contains(typeName.getLocalPart()));
     }
     
     public void setXmlStringAccumulator(String variableName) {

Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties?rev=590664&r1=590663&r2=590664&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties Wed Oct 31 06:33:52 2007
@@ -22,3 +22,4 @@
 NON_SEQUENCE_PARTICLE=JavaScript limitation: Type {0} is not defined as a sequence. {1}
 ABSTRACT_ELEMENT=JavaScript limitation: Abstract element {0} of {1}. {2}
 NULL_PARTICLE=JavaScript limitation: Type {0} has no particle. {1} 
+ELEMENT_HAS_NO_TYPE= Element {0} has no type in the schema. {1}

Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java?rev=590664&r1=590663&r2=590664&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java Wed Oct 31 06:33:52 2007
@@ -36,6 +36,7 @@
 import org.apache.cxf.javascript.UnsupportedSchemaConstruct;
 import org.apache.cxf.service.model.SchemaInfo;
 import org.apache.cxf.wsdl.WSDLConstants;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
 import org.apache.ws.commons.schema.XmlSchemaComplexType;
 import org.apache.ws.commons.schema.XmlSchemaElement;
 import org.apache.ws.commons.schema.XmlSchemaForm;
@@ -60,12 +61,16 @@
     private static final String XSI_NS_ATTR = WSDLConstants.NP_XMLNS + ":" 
         + WSDLConstants.NP_SCHEMA_XSI + "='" + WSDLConstants.NU_SCHEMA_XSI + "'";
     private static final String NIL_ATTRIBUTES = XSI_NS_ATTR + " xsi:nil='true'";
+    private XmlSchemaCollection xmlSchemaCollection;
     private SchemaInfo schemaInfo;
     private NameManager nameManager;
     private Map<String, String> fallbackNamespacePrefixMap;
     private int nsCounter;
     
-    public SchemaJavascriptBuilder(NameManager nameManager, SchemaInfo schemaInfo) {
+    public SchemaJavascriptBuilder(XmlSchemaCollection schemaCollection,
+                                   NameManager nameManager, 
+                                   SchemaInfo schemaInfo) {
+        this.xmlSchemaCollection = schemaCollection;
         this.nameManager = nameManager;
         this.schemaInfo = schemaInfo;
         fallbackNamespacePrefixMap = new HashMap<String, String>();
@@ -135,8 +140,19 @@
      * @return
      */
     private String xmlElementString(XmlSchemaElement element, NamespacePrefixAccumulator accumulator) {
-        QName qname = element.getQName();
-        if (isElementNameQualified(element)) {
+        QName qname;
+        boolean forceQualification = false;
+        if (element.getRefName() != null) {
+            qname = element.getRefName();
+            forceQualification = !qname.getNamespaceURI().equals(schemaInfo.getNamespaceURI());
+        } else {
+            qname = element.getQName();
+        }
+        // some elements don't have qnames, only local names.
+        // one hopes that we aren't called upon to produce a qualified form for such an element, though
+        // perhaps we're supposed to pull the TNS out of a hat.
+        if (forceQualification || isElementNameQualified(element)) {
+            assert qname != null;
             String prefix = qname.getPrefix();
             if ("".equals(prefix)) { // this is not quite good enough.
                 prefix = getPrefix(qname.getNamespaceURI());
@@ -144,7 +160,7 @@
             accumulator.collect(prefix, qname.getNamespaceURI());
             return prefix + ":" + qname.getLocalPart();
         } else {
-            return qname.getLocalPart();
+            return element.getName(); // use the non-qualified name.
         }
     }
     
@@ -196,20 +212,6 @@
         return code.toString();
     }
     
-    /**
-     * If you ask an XmlSchemaElement for a type object, and the object is of simple type, 
-     * the answer appears to be, in some cases,
-     * null! The name, however, is OK. Since all we need is the name, this function 
-     * encapsulates the workaround. 
-     * @param element
-     * @return
-     */
-    private String getElementSimpleTypeName(XmlSchemaElement element) {
-        QName typeName = element.getSchemaTypeName();
-        assert WSDLConstants.NU_SCHEMA_XSD.equals(typeName.getNamespaceURI());
-        return typeName.getLocalPart();
-    }
-    
     public String complexTypeConstructorAndAccessors(XmlSchemaComplexType type) {
         StringBuffer code = new StringBuffer();
         StringBuffer accessors = new StringBuffer();
@@ -238,8 +240,8 @@
             }
             
             XmlSchemaElement elChild = (XmlSchemaElement)thing;
-            XmlSchemaType elType = elChild.getSchemaType();
-            assert elType != null;
+            XmlSchemaType elType = getElementType(type, elChild);
+
             boolean nillable = elChild.isNillable();
             if (elChild.isAbstract()) { 
                 unsupportedConstruct("ABSTRACT_ELEMENT", elChild.getName(), type);
@@ -274,7 +276,7 @@
                 String defaultValueString = elChild.getDefaultValue();
                 if (defaultValueString == null) {
                     defaultValueString = 
-                        utils.getDefaultValueForSimpleType(getElementSimpleTypeName(elChild));
+                        utils.getDefaultValueForSimpleType(elType);
                 }
                 utils.appendLine(elementName + " = " + defaultValueString + ";");
             }
@@ -284,6 +286,22 @@
     }
     
     /**
+     * Follow a chain of references from element to element until we can obtain a type.
+     * @param element
+     * @return
+     */
+    private XmlSchemaType getElementType(XmlSchemaComplexType containingType, XmlSchemaElement element) {
+        XmlSchemaElement originalElement = element;
+        while (element.getSchemaType() == null && element.getRefName() != null) {
+            element = xmlSchemaCollection.getElementByQName(element.getRefName());
+        }
+        if (element.getSchemaType() == null) {
+            unsupportedConstruct("ELEMENT_HAS_NO_TYPE", originalElement.getName(), containingType);
+        }
+        return element.getSchemaType();
+    }
+
+    /**
      * Produce a serializer function for a type.
      * These functions emit the surrounding element XML if the caller supplies an XML element name.
      * It's not quite as simple as that, though. The element name may need namespace qualification,
@@ -351,7 +369,7 @@
         // XML Schema, please meet Iterable (not).
         for (int i = 0; i < sequence.getItems().getCount(); i++) {
             XmlSchemaElement elChild = (XmlSchemaElement)sequence.getItems().getItem(i);
-            XmlSchemaType elType = elChild.getSchemaType();
+            XmlSchemaType elType = getElementType(type, elChild);
             boolean nillable = elChild.isNillable();
             if (elChild.isAbstract()) {
                 unsupportedConstruct("ABSTRACT_ELEMENT", elChild.getName(), type);
@@ -391,7 +409,7 @@
             if (elType instanceof XmlSchemaComplexType) {
                 utils.appendExpression(elementName + ".serialize(cxfjsutils, " + elementXmlRef + ")");
             } else {
-                String typeName = getElementSimpleTypeName(elChild);
+                QName typeName = elType.getQName();
                 utils.appendString("<" + elementXmlRef + ">");
                 // warning: this assumes that ordinary Javascript serialization is all we need.
                 // except for &gt; ad all of that.

Modified: incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java?rev=590664&r1=590663&r2=590664&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java Wed Oct 31 06:33:52 2007
@@ -150,7 +150,7 @@
         nameManager = new BasicNameManager(serviceInfo);
         for (SchemaInfo schema : schemata) {
             SchemaJavascriptBuilder builder = 
-                new SchemaJavascriptBuilder(nameManager, schema);
+                new SchemaJavascriptBuilder(serviceInfo.getXmlSchemaCollection(), nameManager, schema);
             String allThatJavascript = builder.generateCodeForSchema(schema);
             assertNotNull(allThatJavascript);
             testUtilities.readStringIntoRhino(allThatJavascript, schema.toString() + ".js");