cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bimargul...@apache.org
Subject svn commit: r700981 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/common/xmlschema/ rt/javascript/src/main/java/org/apache/cxf/javascript/
Date Thu, 02 Oct 2008 01:30:27 GMT
Author: bimargulies
Date: Wed Oct  1 18:30:27 2008
New Revision: 700981

URL: http://svn.apache.org/viewvc?rev=700981&view=rev
Log:
Incremental creeping toward attribute support in Javascript. As usual, in spite of the XmlSchema
situation.

Added:
    cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/AttributeInfo.java   (with
props)
Modified:
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java
    cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/Messages.properties
    cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NamespacePrefixAccumulator.java
    cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/XmlSchemaUtils.java

Modified: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java?rev=700981&r1=700980&r2=700981&view=diff
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java
(original)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/xmlschema/SchemaCollection.java
Wed Oct  1 18:30:27 2008
@@ -31,8 +31,10 @@
 
 import org.apache.ws.commons.schema.ValidationEventHandler;
 import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
 import org.apache.ws.commons.schema.XmlSchemaCollection;
 import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaObjectTable;
 import org.apache.ws.commons.schema.XmlSchemaSimpleType;
 import org.apache.ws.commons.schema.XmlSchemaType;
 import org.apache.ws.commons.schema.extensions.ExtensionRegistry;
@@ -85,6 +87,20 @@
         return schemaCollection.getElementByQName(qname);
     }
 
+    public XmlSchemaAttribute getAttributeByQName(QName qname) {
+        String uri = qname.getNamespaceURI();
+        for (XmlSchema schema : schemaCollection.getXmlSchemas()) {
+            if (uri.equals(schema.getTargetNamespace())) {
+                XmlSchemaObjectTable attributes = schema.getAttributes();
+                XmlSchemaAttribute attribute = (XmlSchemaAttribute)attributes.getItem(qname);
+                if (attribute != null) {
+                    return attribute;
+                }
+            }
+        }
+        return null;
+    }
+
     public ExtensionRegistry getExtReg() {
         return schemaCollection.getExtReg();
     }

Added: cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/AttributeInfo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/AttributeInfo.java?rev=700981&view=auto
==============================================================================
--- cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/AttributeInfo.java (added)
+++ cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/AttributeInfo.java Wed
Oct  1 18:30:27 2008
@@ -0,0 +1,283 @@
+/**
+ * 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.javascript;
+
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.xmlschema.SchemaCollection;
+import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAnnotated;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaObject;
+import org.apache.ws.commons.schema.XmlSchemaType;
+
+/**
+ * All the information needed to create the JavaScript for an Xml Schema attribute
+ * or xs:anyAttribute.
+ */
+public final class AttributeInfo {
+    private static final Logger LOG = LogUtils.getL7dLogger(AttributeInfo.class);
+    private XmlSchemaAnnotated annotated;
+    private String javascriptName;
+    private String xmlName;
+    private XmlSchemaType containingType;
+    private XmlSchemaType type;
+    private boolean any;
+    private boolean anyType;
+    private String defaultValue;
+    private String fixedValue;
+    private boolean global;
+
+    private AttributeInfo() {
+    }
+
+    /**
+     * Create an elementInfo that stores information about a global, named,
+     * element.
+     * 
+     * @param attribute the element
+     * @param currentSchema the schema it came from.
+     * @param schemaCollection the collection of all schemas.
+     * @param prefixAccumulator the accumulator that assigns prefixes.
+     * @return
+     */
+    public static AttributeInfo forGlobalAttribute(XmlSchemaAttribute attribute, XmlSchema
currentSchema,
+                                                   SchemaCollection schemaCollection,
+                                                   NamespacePrefixAccumulator prefixAccumulator)
{
+        AttributeInfo attributeInfo = new AttributeInfo();
+        attributeInfo.annotated = attribute;
+        attributeInfo.global = true;
+
+        factoryCommon(attribute, currentSchema, schemaCollection, prefixAccumulator, attributeInfo);
+        return attributeInfo;
+    }
+
+    /**
+     * Fill in an ElementInfo for an element or xs:any from a sequence.
+     * 
+     * @param sequenceElement
+     * @param currentSchema
+     * @param schemaCollection
+     * @param prefixAccumulator
+     * @return
+     */
+    public static AttributeInfo forLocalItem(XmlSchemaObject sequenceObject, 
+                                             XmlSchema currentSchema,
+                                            SchemaCollection schemaCollection,
+                                            NamespacePrefixAccumulator prefixAccumulator,
QName contextName) {
+        XmlSchemaAnnotated annotated = XmlSchemaUtils.getObjectAnnotated(sequenceObject,
contextName);
+        AttributeInfo attributeInfo = new AttributeInfo();
+        XmlSchemaAnnotated realParticle = annotated;
+
+        if (annotated instanceof XmlSchemaAttribute) {
+            XmlSchemaAttribute attribute = (XmlSchemaAttribute)annotated;
+
+            if (attribute.getRefName() != null) {
+                XmlSchemaAttribute refElement = schemaCollection
+                    .getAttributeByQName(attribute.getRefName());
+                if (refElement == null) {
+                    Message message = new Message("ATTRIBUTE_DANGLING_REFERENCE", LOG, attribute
+                        .getQName(), attribute.getRefName());
+                    throw new UnsupportedConstruct(message.toString());
+                }
+                realParticle = refElement;
+                attributeInfo.global = true;
+            }
+        }
+
+        factoryCommon(realParticle, currentSchema, schemaCollection, prefixAccumulator, attributeInfo);
+
+        attributeInfo.annotated = realParticle;
+
+        return attributeInfo;
+    }
+
+    private static void factoryCommon(XmlSchemaAnnotated particle, XmlSchema currentSchema,
+                                      SchemaCollection schemaCollection,
+                                      NamespacePrefixAccumulator prefixAccumulator, 
+                                      AttributeInfo attributeInfo) {
+
+        if (particle instanceof XmlSchemaAttribute) {
+            XmlSchemaAttribute attribute = (XmlSchemaAttribute)particle;
+            String attributeNamespaceURI = attribute.getQName().getNamespaceURI();
+            boolean attributeNoNamespace = "".equals(attributeNamespaceURI);
+
+            XmlSchema attributeSchema = null;
+            if (!attributeNoNamespace) {
+                attributeSchema = schemaCollection.getSchemaByTargetNamespace(attributeNamespaceURI);
+                if (attributeSchema == null) {
+                    throw new RuntimeException("Missing schema " + attributeNamespaceURI);
+                }
+            }
+
+            boolean qualified = !attributeNoNamespace
+                                && XmlSchemaUtils.isAttributeQualified(attribute,
true, currentSchema,
+                                                                     attributeSchema);
+            attributeInfo.xmlName = prefixAccumulator.xmlAttributeString(attribute, qualified);
+            // we are assuming here that we are not dealing, in close proximity,
+            // with elements with identical local names and different
+            // namespaces.
+            attributeInfo.javascriptName = attribute.getQName().getLocalPart();
+            attributeInfo.defaultValue = attribute.getDefaultValue();
+            attributeInfo.fixedValue = attribute.getFixedValue();
+            factorySetupType(attribute, schemaCollection, attributeInfo);
+        } else { // any
+            attributeInfo.any = true;
+            attributeInfo.xmlName = null; // unknown until runtime.
+            // TODO: multiple 'any'
+            attributeInfo.javascriptName = "any";
+            attributeInfo.type = null; // runtime for any.
+
+        }
+    }
+
+    private static void factorySetupType(XmlSchemaAttribute element, SchemaCollection schemaCollection,
+                                         AttributeInfo elementInfo) {
+        elementInfo.type = element.getSchemaType();
+        if (elementInfo.type == null) {
+            if (element.getSchemaTypeName().equals(XmlSchemaConstants.ANY_TYPE_QNAME)) {
+                elementInfo.anyType = true;
+            } else {
+                elementInfo.type = schemaCollection.getTypeByQName(element.getSchemaTypeName());
+                if (elementInfo.type == null 
+                    && !element.getSchemaTypeName()
+                            .getNamespaceURI().equals(XmlSchemaConstants.XSD_NAMESPACE_URI))
{
+                    XmlSchemaUtils.unsupportedConstruct("MISSING_TYPE", element.getSchemaTypeName()
+                            .toString(), element.getQName(), element);
+                }
+            }
+        } else if (elementInfo.type.getQName() != null
+            && XmlSchemaConstants.ANY_TYPE_QNAME.equals(elementInfo.type.getQName()))
{
+            elementInfo.anyType = true;
+        }
+    }
+
+    /**
+     * As a general rule, the JavaScript code is organized by types. The
+     * exception is global elements that have anonymous types. In those cases,
+     * the JavaScript code has its functions named according to the element.
+     * This method returns the QName for the type or element, accordingly. If a
+     * schema has a local element with an anonymous, complex, type, this will
+     * throw. This will need to be fixed.
+     * 
+     * @return the qname.
+     */
+    public QName getControllingName() {
+        if (type != null && type.getQName() != null) {
+            return type.getQName();
+        } else if (annotated instanceof XmlSchemaElement) {
+            XmlSchemaElement element = (XmlSchemaElement)annotated;
+            if (element.getQName() != null) {
+                return element.getQName();
+            }
+        }
+        Message message = new Message("IMPOSSIBLE_GLOBAL_ITEM", LOG, XmlSchemaUtils
+            .cleanedUpSchemaSource(annotated));
+        LOG.severe(message.toString());
+        throw new UnsupportedConstruct(message);
+    }
+
+    /**
+     * Return the object for the Attribute or the anyAttribute.
+     * @return
+     */
+    public XmlSchemaAnnotated getAnnotated() {
+        return annotated;
+    }
+
+    public String getJavascriptName() {
+        return javascriptName;
+    }
+
+    public void setJavascriptName(String name) {
+        javascriptName = name;
+    }
+
+    public String getXmlName() {
+        return xmlName;
+    }
+
+    public void setXmlName(String elementXmlName) {
+        this.xmlName = elementXmlName;
+    }
+
+    public XmlSchemaType getContainingType() {
+        return containingType;
+    }
+
+    public void setContainingType(XmlSchemaType containingType) {
+        this.containingType = containingType;
+    }
+
+    public XmlSchemaType getType() {
+        return type;
+    }
+
+    public void setType(XmlSchemaType type) {
+        this.type = type;
+    }
+
+    public boolean isAny() {
+        return any;
+    }
+
+    public boolean isAnyType() {
+        return anyType;
+    }
+
+    /**
+     * *
+     * 
+     * @return Returns the defaultValue.
+     */
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    /**
+     * @param defaultValue The defaultValue to set.
+     */
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    /**
+     * True if this describes a global, named, attribute.
+     * 
+     * @return
+     */
+    public boolean isGlobal() {
+        return global;
+    }
+
+    public String getFixedValue() {
+        return fixedValue;
+    }
+
+    public void setFixedValue(String fixedValue) {
+        this.fixedValue = fixedValue;
+    }
+}

Propchange: cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/AttributeInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/AttributeInfo.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/Messages.properties
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/Messages.properties?rev=700981&r1=700980&r2=700981&view=diff
==============================================================================
--- cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/Messages.properties (original)
+++ cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/Messages.properties Wed
Oct  1 18:30:27 2008
@@ -21,6 +21,8 @@
 NON_SEQUENCE_PARTICLE=JavaScript limitation: Type {0} is not defined as a sequence. {1}
 NON_ELEMENT_CHILD=JavaScript limitation: Non-Element sequence member {0} of {1}. {2}
 NON_PARTICLE_CHILD=JavaScript limitation: Non-particle sequence member {0} of {1}. {2}
+NON_ANNOTATED_ATTRIBUTE=JavaScript limitation: Non-attribute member {0} or {1}. {2}
+EXOTIC_ATTRIBUTE=JavaScript limitation: unsupported non-attribute {0} found in {1}. {2}
 GROUP_CHILD=JavaScript limitation: unsupported xs:group {0} found in {1}. {2}
 ABSTRACT_ELEMENT=JavaScript limitation: Abstract element {0} of {1}. {2}
 ELEMENT_HAS_NO_TYPE=Element {0} has no type in the schema. {1}
@@ -28,3 +30,4 @@
 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}
+ATTRIBUTE_DANGLING_REFERENCE=Attribute {0} refers to undefined attribute {1}.

Modified: cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NamespacePrefixAccumulator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NamespacePrefixAccumulator.java?rev=700981&r1=700980&r2=700981&view=diff
==============================================================================
--- cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NamespacePrefixAccumulator.java
(original)
+++ cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NamespacePrefixAccumulator.java
Wed Oct  1 18:30:27 2008
@@ -27,6 +27,7 @@
 import javax.xml.namespace.QName;
 
 import org.apache.cxf.common.xmlschema.SchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
 import org.apache.ws.commons.schema.XmlSchemaElement;
 
 public class NamespacePrefixAccumulator {
@@ -90,6 +91,24 @@
         return element.getName(); // use the non-qualified name.
     }
     
+    /**
+     * Obtain a suitable name for use in Javascript for an attribute. This function
+     * is purely a tribute to the awful modularity of XmlSchema.
+     * @param attribute
+     * @param qualified
+     * @return
+     */
+    public String xmlAttributeString(XmlSchemaAttribute attribute, boolean qualified) {
+        if (qualified) {
+            // What if there were a prefix in the element's qname? This is not apparently

+            // something that happens in this environment.
+            String prefix = getPrefix(attribute.getQName().getNamespaceURI());
+            collect(prefix, attribute.getQName().getNamespaceURI());
+            return prefix + ":" + attribute.getName();
+        }
+        return attribute.getName(); // use the non-qualified name.
+    }
+    
     public String xmlElementString(QName name) { // used with part concrete names
         if ("".equals(name.getNamespaceURI())) {
             return name.getLocalPart();

Modified: cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/XmlSchemaUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/XmlSchemaUtils.java?rev=700981&r1=700980&r2=700981&view=diff
==============================================================================
--- cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/XmlSchemaUtils.java (original)
+++ cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/XmlSchemaUtils.java Wed
Oct  1 18:30:27 2008
@@ -28,7 +28,10 @@
 import org.apache.cxf.common.xmlschema.SchemaCollection;
 import org.apache.cxf.wsdl.WSDLConstants;
 import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAnnotated;
 import org.apache.ws.commons.schema.XmlSchemaAny;
+import org.apache.ws.commons.schema.XmlSchemaAnyAttribute;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
 import org.apache.ws.commons.schema.XmlSchemaComplexType;
 import org.apache.ws.commons.schema.XmlSchemaElement;
 import org.apache.ws.commons.schema.XmlSchemaForm;
@@ -196,6 +199,19 @@
         return schema.getElementFormDefault().equals(QUALIFIED);
     }
     
+    public static boolean isAttributeNameQualified(XmlSchemaAttribute attribute, XmlSchema
schema) {
+        if (attribute.getRefName() != null) {
+            throw new RuntimeException("isElementNameQualified on element with ref=");
+        }
+        if (attribute.getForm().equals(QUALIFIED)) {
+            return true;
+        }
+        if (attribute.getForm().equals(UNQUALIFIED)) {
+            return false;
+        }
+        return schema.getAttributeFormDefault().equals(QUALIFIED);
+    }
+    
     /**
      * due to a bug, feature, or just plain oddity of JAXB, it isn't good enough
      * to just check the form of an element and of its schema. If schema 'a'
@@ -234,7 +250,45 @@
             return isElementNameQualified(element, elementSchema);
         }
     }
-    
+    /**
+     * due to a bug, feature, or just plain oddity of JAXB, it isn't good enough
+     * to just check the form of an element and of its schema. If schema 'a'
+     * (default unqualified) has a complex type with an element with a ref= to
+     * schema (b) (default unqualified), JAXB seems to expect to see a
+     * qualifier, anyway. <br/> So, if the element is local to a complex type,
+     * all we care about is the default element form of the schema and the local
+     * form of the element. <br/> If, on the other hand, the element is global,
+     * we might need to compare namespaces. <br/>
+     * 
+     * @param attribute the attribute
+     * @param global if this element is a global element (complex type ref= to
+     *                it, or in a part)
+     * @param localSchema the schema of the complex type containing the
+     *                reference, only used for the 'odd case'.
+     * @param elementSchema the schema for the element.
+     * @return if the element needs to be qualified.
+     */
+    public static boolean isAttributeQualified(XmlSchemaAttribute attribute,
+                                             boolean global,
+                                             XmlSchema localSchema,
+                                             XmlSchema attributeSchema) {
+        if (attribute.getQName() == null) {
+            throw new RuntimeException("getSchemaQualifier on anonymous element.");
+        }
+        if (attribute.getRefName() != null) {
+            throw new RuntimeException("getSchemaQualified on the 'from' side of ref=.");
+        }
+            
+
+        if (global) {
+            return isAttributeNameQualified(attribute, attributeSchema)
+                || (localSchema != null 
+                    && !(attribute.getQName().getNamespaceURI().equals(localSchema.getTargetNamespace())));
+        } else {
+            return isAttributeNameQualified(attribute, attributeSchema);
+        }
+    }
+
     /**
      * If the object is an element or an any, return the particle. If it's not a particle,
or it's a group,
      * throw. We're not ready for groups yet.
@@ -258,6 +312,30 @@
         return (XmlSchemaParticle) object;
     }
     
+    /**
+     * If the object is an attribute or an anyAttribute, 
+     * return the 'Annotated'. If it's not one of those, or it's a group,
+     * throw. We're not ready for groups yet.
+     * @param object
+     * @return
+     */
+    public static XmlSchemaAnnotated getObjectAnnotated(XmlSchemaObject object, QName contextName)
{
+        
+        if (!(object instanceof XmlSchemaAnnotated)) {
+            XmlSchemaUtils.unsupportedConstruct("NON_ANNOTATED_ATTRIBUTE", 
+                                                object.getClass().getSimpleName(), 
+                                                contextName, object);
+        }
+        if (!(object instanceof XmlSchemaAttribute)
+            && !(object instanceof XmlSchemaAnyAttribute)) {
+            XmlSchemaUtils.unsupportedConstruct("EXOTIC_ATTRIBUTE", 
+                                                object.getClass().getSimpleName(), contextName,
+                                                object);
+        }
+        
+        return (XmlSchemaAnnotated) object;
+    }
+    
     public static boolean isParticleArray(XmlSchemaParticle particle) {
         return particle.getMaxOccurs() > 1;
     }



Mime
View raw message