You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by gd...@apache.org on 2002/03/08 06:04:54 UTC

cvs commit: xml-axis/java/test/encoding SimpleBean.java AttributeBean.java TestAttributes.java

gdaniels    02/03/07 21:04:54

  Modified:    java/src/org/apache/axis/encoding
                        DeserializationContextImpl.java
               java/src/org/apache/axis/encoding/ser
                        BaseSerializerFactory.java BeanDeserializer.java
                        BeanSerializer.java SimpleDeserializer.java
                        SimpleSerializer.java
               java/src/org/apache/axis/wsdl/toJava
                        JavaComplexTypeWriter.java
               java/test/encoding AttributeBean.java TestAttributes.java
  Added:       java/src/org/apache/axis/description AttributeDesc.java
                        ElementDesc.java FieldDesc.java TypeDesc.java
               java/test/encoding SimpleBean.java
  Log:
  Implement structured type mapping metadata, part I.
  
  * Define two new classes, TypeDesc and FieldDesc, representing
    metadata about a Java<->XML mapping for a given type.  FieldDesc
    maps a given Java field to/from a particular XML element OR attribute,
    and has two subclasses, ElementDesc and AttributeDesc.  The subclasses
    may be created directly, the FieldDesc root may not.
  
  * Adjust the code in the BeanSerializer/Deserializer and SimpleSerializer/
    Deserializer to look for a static "getTypeDesc()" method on classes to
    obtain metadata instead of looking for the old "getAttributeNames()"
    string array.
  
  * Edit the stub generator to emit the new metadata style.
  
  * Fix up the TestAttributes test to use the new metadata style, test
    more combinations of present + missing metadata, and also add a
    test for a SimpleType with an attribute.
  
  So what does this mean?
  
  The framework is now in place for much smoother data binding, and we
  can eventually move towards supporting an xdoclet-type Javadoc
  syntax for expressing these kinds of mappings.
  
  We now support attributes which are in other namespaces than the
  default.
  
  Next steps:
  
  Get the emitter doing the right thing for XML -> Java name mangling.  In
  other words, if we have to change an XML name when writing a stub
  from WSDL, we should now be able to keep track of the original XML
  name and add it to the metadata instead of relying on the Java -> XML
  reverse name mangling to preserve fidelity.
  
  Get the WSDL emitted for attributes to look correct.  I was a little too
  tired to finish this tonight.
  
  Attempt to refactor the BeanSerializer/SimpleSerializer and equiv.
  deserializers into a common family so they can share all the duplicated
  code that currently lives both places.
  
  Clean up a bit more.
  
  Revision  Changes    Path
  1.1                  xml-axis/java/src/org/apache/axis/description/AttributeDesc.java
  
  Index: AttributeDesc.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.axis.description;
  
  /**
   * An AttributeDesc is a FieldDesc for an Java field mapping to an
   * XML attribute
   *
   * @author Glen Daniels (gdaniels@apache.org)
   */
  public class AttributeDesc extends FieldDesc {
      public AttributeDesc() {
          super(false);
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/description/ElementDesc.java
  
  Index: ElementDesc.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.axis.description;
  
  /**
   * An AttributeDesc is a FieldDesc for an Java field mapping to an
   * XML element
   *
   * @author Glen Daniels (gdaniels@apache.org)
   */
  public class ElementDesc extends FieldDesc {
      public ElementDesc() {
          super(true);
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/description/FieldDesc.java
  
  Index: FieldDesc.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.axis.description;
  
  import javax.xml.rpc.namespace.QName;
  
  /**
   * FieldDescs are metadata objects which control the mapping of a given
   * Java field to/from XML.
   *
   * @author Glen Daniels (gdaniels@apache.org)
   */
  public class FieldDesc {
      /** The name of the Java field in question */
      private String fieldName;
      /** The XML QName this field maps to */
      private QName xmlName;
      /** The XML Type this field maps to/from */
      private QName xmlType;
      /** An indication of whether this should be an element or an attribute */
      // Q : should this be a boolean, or just "instanceof ElementDesc", etc.
      private boolean _isElement = true;
  
      /**
       * Can't construct the base class directly, must construct either an
       * ElementDesc or an AttributeDesc.
       */
      protected FieldDesc(boolean isElement)
      {
          _isElement = isElement;
      }
  
      /**
       * Obtain the field name.
       */
      public String getFieldName() {
          return fieldName;
      }
  
      /**
       * Set the field name.
       */
      public void setFieldName(String fieldName) {
          this.fieldName = fieldName;
      }
  
      /**
       * Obtain the XML QName for this field
       */
      public QName getXmlName() {
          return xmlName;
      }
  
      /**
       * Set the XML QName for this field
       */
      public void setXmlName(QName xmlName) {
          this.xmlName = xmlName;
      }
  
      /**
       * Check if this is an element or an attribute.
       *
       * @return true if this is an ElementDesc, or false if an AttributeDesc
       */
      public boolean isElement() {
          return _isElement;
      }
  }
  
  
  
  1.1                  xml-axis/java/src/org/apache/axis/description/TypeDesc.java
  
  Index: TypeDesc.java
  ===================================================================
  
  package org.apache.axis.description;
  
  import javax.xml.rpc.namespace.QName;
  import java.util.HashMap;
  import java.lang.reflect.Array;
  
  public class TypeDesc {
      private FieldDesc [] fields;
      private HashMap fieldNameMap = new HashMap();
      
      /** Are there any fields which are serialized as attributes? */
      private boolean _hasAttributes = false;
  
      public FieldDesc[] getFields() {
          return fields;
      }
  
      public void setFields(FieldDesc [] newFields)
      {
          fieldNameMap = new HashMap();
          fields = newFields;
          _hasAttributes = false;
          
          for (int i = 0; i < newFields.length; i++) {
              FieldDesc field = newFields[i];
              if (field.isElement()) {
                  fieldNameMap.put(field.getFieldName(), field);
              } else {
                  _hasAttributes = true;
              }
          }
      }
      
      public void addFieldDesc(FieldDesc field)
      {
          if (field == null)
              throw new NullPointerException();
          
          int numFields = 0;
          if (fields != null) {
              numFields = fields.length;
          }
          FieldDesc [] newFields = new FieldDesc[numFields + 1];
          if (fields != null) {
              System.arraycopy(fields, 0, newFields, 0, numFields);
          }
          newFields[numFields] = field;
          fields = newFields;
          
          // Keep track of the field by name for fast lookup
          fieldNameMap.put(field.getFieldName(), field);
          
          if (!_hasAttributes && !field.isElement())
              _hasAttributes = true;
      }
      
      public QName getElementNameForField(String fieldName)
      {
          FieldDesc desc = (FieldDesc)fieldNameMap.get(fieldName);
          if (desc == null || !desc.isElement())
              return null;
          return desc.getXmlName();
      }
      
      public QName getAttributeNameForField(String fieldName)
      {
          FieldDesc desc = (FieldDesc)fieldNameMap.get(fieldName);
          if (desc == null || desc.isElement())
              return null;
          return desc.getXmlName();
      }
      
      public String getFieldNameForElement(QName qname)
      {
          for (int i = 0; i < fields.length; i++) {
              FieldDesc field = fields[i];
              if (field.isElement() && qname.equals(field.getXmlName()))
                  return field.getFieldName();
          }
  
          return null;
      }
      
      public String getFieldNameForAttribute(QName qname)
      {
          String possibleMatch = null;
  
          for (int i = 0; i < fields.length; i++) {
              FieldDesc field = fields[i];
              if (!field.isElement()) {
                  // It's an attribute, so if we have a solid match, return
                  // its name.
                  if (qname.equals(field.getXmlName())) {
                      return field.getFieldName();
                  }
                  // Not a solid match, but it's still possible we might match
                  // the default (i.e. QName("", fieldName))
                  if (qname.getNamespaceURI().equals("") &&
                      qname.getLocalPart().equals(field.getFieldName())) {
                      possibleMatch = field.getFieldName();
                  }
              }
          }
          
          return possibleMatch;
      }
      
      public FieldDesc getFieldByName(String name)
      {
          return (FieldDesc)fieldNameMap.get(name);
      }
  
      public boolean hasAttributes() {
          return _hasAttributes;
      }
  }
  
  
  
  1.15      +7 -6      xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java
  
  Index: DeserializationContextImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- DeserializationContextImpl.java	6 Mar 2002 19:35:49 -0000	1.14
  +++ DeserializationContextImpl.java	8 Mar 2002 05:04:54 -0000	1.15
  @@ -315,6 +315,13 @@
       {
           QName typeQName = null;
           
  +        // Check for type
  +        String type = Constants.getValue(attrs, Constants.URI_CURRENT_SCHEMA_XSI, "type");
  +        if (type != null) {
  +            // Return the type attribute value converted to a QName
  +            return getQNameFromString(type);
  +        }
  +
           if (typeQName == null) {
   
               // If the element is a SOAP-ENC element, the name of the element is the type.
  @@ -351,12 +358,6 @@
           if (typeQName != null)
               return typeQName;
           
  -        // Check for type
  -        String type = Constants.getValue(attrs, Constants.URI_CURRENT_SCHEMA_XSI, "type");
  -        if (type != null) {
  -            // Return the type attribute value converted to a QName
  -            return getQNameFromString(type);
  -        }
   
           /*  Removing this code for now - Glen 2/20/02
           
  
  
  
  1.2       +2 -1      xml-axis/java/src/org/apache/axis/encoding/ser/BaseSerializerFactory.java
  
  Index: BaseSerializerFactory.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BaseSerializerFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BaseSerializerFactory.java	26 Jan 2002 02:40:34 -0000	1.1
  +++ BaseSerializerFactory.java	8 Mar 2002 05:04:54 -0000	1.2
  @@ -127,7 +127,8 @@
                   }
                   ser = (Serializer) 
                       serClassConstructor.newInstance(new Object[] {javaType, xmlType});
  -            } catch (Exception e) {}
  +            } catch (Exception e) {
  +            }
           }
           // If not successfull, try newInstance
           if (ser == null) {
  
  
  
  1.8       +123 -99   xml-axis/java/src/org/apache/axis/encoding/ser/BeanDeserializer.java
  
  Index: BeanDeserializer.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BeanDeserializer.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- BeanDeserializer.java	6 Mar 2002 19:35:49 -0000	1.7
  +++ BeanDeserializer.java	8 Mar 2002 05:04:54 -0000	1.8
  @@ -72,6 +72,7 @@
   import org.apache.axis.encoding.TypeMapping;
   import org.apache.axis.utils.JavaUtils;
   import org.apache.axis.Constants;
  +import org.apache.axis.description.TypeDesc;
   
   import java.beans.IntrospectionException;
   
  @@ -102,6 +103,9 @@
       Class javaType;
       private BeanPropertyDescriptor[] pd = null;
       private HashMap propertyMap = new HashMap();
  +    
  +    /** Type metadata about this class for XML deserialization */
  +    private TypeDesc typeDesc = null;
   
       // This counter is updated to deal with deserialize collection properties
       protected int collectionIndex = -1;
  @@ -117,6 +121,18 @@
               BeanPropertyDescriptor descriptor = pd[i];
               propertyMap.put(descriptor.getName(), descriptor);
           }
  +        
  +        // Get the class' TypeDesc if it provides one
  +        try {
  +            Method getTypeDesc = 
  +                    javaType.getMethod("getTypeDesc",
  +                                       new Class [] {});
  +            // get string array
  +            typeDesc = (TypeDesc)getTypeDesc.invoke(null, 
  +                                                    BeanSerializer.noArgs);
  +        } catch (Exception e) {
  +        }
  +        
           // create a value
           try {
               value=javaType.newInstance();
  @@ -145,58 +161,74 @@
                                       DeserializationContext context)
           throws SAXException
       {
  +        BeanPropertyDescriptor propDesc = null;
  +        
  +        if (typeDesc != null) {
  +            QName elemQName = new QName(namespace, localName);
  +            String fieldName = typeDesc.getFieldNameForElement(elemQName);
  +            propDesc = (BeanPropertyDescriptor)propertyMap.get(fieldName);
  +        }
   
  -        // look for a field by this name.  Assumes the the number of
  -        // properties in a bean is (relatively) small, so uses a linear
  -        // search.  Accept a property if it differs only by the 
  -        // capitalization of the first character.
  -        String localNameUp = BeanSerializer.format(localName, BeanSerializer.FORCE_UPPER);
  -        String localNameLo = BeanSerializer.format(localName, BeanSerializer.FORCE_LOWER);
  -        String mangledName = JavaUtils.xmlNameToJava(localName);
  -        for (int i=0; i<pd.length; i++) {
  -            if (pd[i].getWriteMethod() == null ) continue ;
  -            if (pd[i].getName().equals(localNameUp) ||
  -                pd[i].getName().equals(localNameLo) ||
  -                pd[i].getName().equals(mangledName)) {
  -
  -                // Determine the QName for this child element.
  -                // Look at the type attribute specified.  If this fails,
  -                // use the javaType of the property to get the type qname.
  -                QName qn = context.getTypeFromAttributes(namespace, localName, attributes);
  -
  -                // get the deserializer
  -                Deserializer dSer = context.getDeserializerForType(qn);
  -
  -                // If no deserializer, use the base DeserializerImpl.
  -                // There may not be enough information yet to choose the
  -                // specific deserializer.
  -                if (dSer == null) {
  -                    dSer = new DeserializerImpl();
  -                    // determine a default type for this child element
  -                    TypeMapping tm = context.getTypeMapping();
  -                    Class type = pd[i].getType();
  -                    dSer.setDefaultType(tm.getTypeQName(type));
  -                }
  -                
  -
  -                if (pd[i].getWriteMethod().getParameterTypes().length == 1) {
  -                    // Success!  Register the target and deserializer.
  -                    collectionIndex = -1;
  -                    dSer.registerValueTarget(new BeanPropertyTarget(value, pd[i]));
  -                    return (SOAPHandler) dSer;
  -                } else {
  -                    // Success! This is a collection of properties so use the index
  -                    collectionIndex++;
  -                    dSer.registerValueTarget(new BeanPropertyTarget(value, pd[i], collectionIndex));
  -                    return (SOAPHandler) dSer;
  +        if (propDesc == null) {
  +            // look for a field by this name.  Assumes the the number of
  +            // properties in a bean is (relatively) small, so uses a linear
  +            // search.  Accept a property if it differs only by the 
  +            // capitalization of the first character.
  +            String localNameUp = 
  +                    BeanSerializer.format(localName, 
  +                                          BeanSerializer.FORCE_UPPER);
  +            String localNameLo = 
  +                    BeanSerializer.format(localName, 
  +                                          BeanSerializer.FORCE_LOWER);
  +            String mangledName = JavaUtils.xmlNameToJava(localName);
  +            for (int i=0; i<pd.length; i++) {
  +                if (pd[i].getWriteMethod() == null ) continue ;
  +                if (pd[i].getName().equals(localNameUp) ||
  +                        pd[i].getName().equals(localNameLo) ||
  +                        pd[i].getName().equals(mangledName)) {
  +                    propDesc = pd[i];
                   }
  -                    
               }
           }
  +        
  +        if (propDesc == null) {
  +            // No such field
  +            throw new SAXException(
  +                    JavaUtils.getMessage("badElem00", javaType.getName(), 
  +                                         localName));
  +        }
   
  -        // No such field
  -        throw new SAXException(
  -                JavaUtils.getMessage("badElem00", javaType.getName(), localName));
  +        // Determine the QName for this child element.
  +        // Look at the type attribute specified.  If this fails,
  +        // use the javaType of the property to get the type qname.
  +        QName qn = context.getTypeFromAttributes(namespace, localName, attributes);
  +        
  +        // get the deserializer
  +        Deserializer dSer = context.getDeserializerForType(qn);
  +        
  +        // If no deserializer, use the base DeserializerImpl.
  +        // There may not be enough information yet to choose the
  +        // specific deserializer.
  +        if (dSer == null) {
  +            dSer = new DeserializerImpl();
  +            // determine a default type for this child element
  +            TypeMapping tm = context.getTypeMapping();
  +            Class type = propDesc.getType();
  +            dSer.setDefaultType(tm.getTypeQName(type));
  +        }
  +                
  +        if (propDesc.getWriteMethod().getParameterTypes().length == 1) {
  +            // Success!  Register the target and deserializer.
  +            collectionIndex = -1;
  +            dSer.registerValueTarget(new BeanPropertyTarget(value, propDesc));
  +        } else {
  +            // Success! This is a collection of properties so use the index
  +            collectionIndex++;
  +            dSer.registerValueTarget(new BeanPropertyTarget(value, 
  +                                                            propDesc, 
  +                                                            collectionIndex));
  +        }
  +        return (SOAPHandler)dSer;
       }
   
       /**
  @@ -215,69 +247,61 @@
                                  DeserializationContext context)
               throws SAXException {
   
  -        // get list of properties that are really attributes
  -        Vector beanAttributeNames = BeanSerializer.getBeanAttributes(javaType);
  +        if (typeDesc == null)
  +            return;
           
           // loop through the attributes and set bean properties that 
           // correspond to attributes
  -        if (beanAttributeNames != null && 
  -            beanAttributeNames.size() > 0) {
  -            for (int i=0; i < attributes.getLength(); i++) {
  -                String attrName = attributes.getLocalName(i);
  -                String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
  -                String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
  -                String mangledName = JavaUtils.xmlNameToJava(attrName);
  -
  -                // See if the attribute is a beanAttribute name
  -                if (!beanAttributeNames.contains(attrName) &&
  -                    !beanAttributeNames.contains(attrNameUp) &&
  -                    !beanAttributeNames.contains(attrNameLo))
  -                    continue;
  -
  -                // look for the attribute property
  -                BeanPropertyDescriptor bpd = 
  -                    (BeanPropertyDescriptor) propertyMap.get(attrNameUp);
  -                if (bpd == null)
  -                    bpd = (BeanPropertyDescriptor) propertyMap.get(attrNameLo);
  -                if (bpd == null)
  -                    bpd = (BeanPropertyDescriptor) propertyMap.get(mangledName);
  -                if (bpd != null) {
  -                    if (bpd.getWriteMethod() == null ) continue ;
  -                    
  -                    // determine the QName for this child element
  -                    TypeMapping tm = context.getTypeMapping();
  -                    Class type = bpd.getType();
  -                    QName qn = tm.getTypeQName(type);
  -                    if (qn == null)
  -                        throw new SAXException(
  +        for (int i=0; i < attributes.getLength(); i++) {
  +            QName attrQName = new QName(attributes.getURI(i),
  +                                        attributes.getLocalName(i));
  +            String fieldName = typeDesc.getFieldNameForAttribute(attrQName);
  +            if (fieldName == null)
  +                continue;
  +
  +            String attrName = attributes.getLocalName(i);
  +            String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
  +            String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
  +            String mangledName = JavaUtils.xmlNameToJava(attrName);
  +            
  +            // look for the attribute property
  +            BeanPropertyDescriptor bpd = 
  +                    (BeanPropertyDescriptor) propertyMap.get(fieldName);
  +            if (bpd != null) {
  +                if (bpd.getWriteMethod() == null ) continue ;
  +                
  +                // determine the QName for this child element
  +                TypeMapping tm = context.getTypeMapping();
  +                Class type = bpd.getType();
  +                QName qn = tm.getTypeQName(type);
  +                if (qn == null)
  +                    throw new SAXException(
                               JavaUtils.getMessage("unregistered00", type.toString()));
                   
  -                    // get the deserializer
  -                    Deserializer dSer = context.getDeserializerForType(qn);
  -                    if (dSer == null)
  -                        throw new SAXException(
  +                // get the deserializer
  +                Deserializer dSer = context.getDeserializerForType(qn);
  +                if (dSer == null)
  +                    throw new SAXException(
                               JavaUtils.getMessage("noDeser00", type.toString()));
  -                    if (! (dSer instanceof SimpleDeserializer))
  -                        throw new SAXException(
  +                if (! (dSer instanceof SimpleDeserializer))
  +                    throw new SAXException(
                               JavaUtils.getMessage("AttrNotSimpleType00", 
                                                    bpd.getName(), 
                                                    type.toString()));
                   
  -                    if (bpd.getWriteMethod().getParameterTypes().length == 1) {
  -                        // Success!  Create an object from the string and set
  -                        // it in the bean
  -                        try {
  -                            Object val = ((SimpleDeserializer)dSer).
  +                if (bpd.getWriteMethod().getParameterTypes().length == 1) {
  +                    // Success!  Create an object from the string and set
  +                    // it in the bean
  +                    try {
  +                        Object val = ((SimpleDeserializer)dSer).
                                   makeValue(attributes.getValue(i));
  -                            bpd.getWriteMethod().invoke(value, new Object[] {val} );
  -                        } catch (Exception e) {
  -                            throw new SAXException(e);
  -                        }
  +                        bpd.getWriteMethod().invoke(value, new Object[] {val} );
  +                    } catch (Exception e) {
  +                        throw new SAXException(e);
                       }
  +                }
                   
  -                } // if
  -            } // attribute loop
  -        } // if attributes exist
  -    } // onStartElement
  -
  +            } // if
  +        } // attribute loop
  +    }
   }
  
  
  
  1.14      +120 -48   xml-axis/java/src/org/apache/axis/encoding/ser/BeanSerializer.java
  
  Index: BeanSerializer.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BeanSerializer.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- BeanSerializer.java	6 Mar 2002 19:35:49 -0000	1.13
  +++ BeanSerializer.java	8 Mar 2002 05:04:54 -0000	1.14
  @@ -72,6 +72,8 @@
   import org.apache.axis.encoding.DeserializerImpl;
   import org.apache.axis.InternalException;
   import org.apache.axis.AxisFault;
  +import org.apache.axis.description.TypeDesc;
  +import org.apache.axis.description.FieldDesc;
   import org.apache.axis.utils.JavaUtils;
   import org.apache.axis.wsdl.fromJava.ClassRep;
   import org.apache.axis.wsdl.fromJava.FieldRep;
  @@ -109,7 +111,7 @@
       protected static Log log =
           LogFactory.getLog(BeanSerializer.class.getName());
   
  -    private static final Object[] noArgs = new Object[] {};  // For convenience
  +    public static final Object[] noArgs = new Object[] {};  // For convenience
   
       // When serializing, the property element names passed over the wire
       // are the names of the properties (format=PROPERTY_NAME).
  @@ -126,7 +128,7 @@
       Class javaType;
   
       private BeanPropertyDescriptor[] propertyDescriptor = null;
  -    private Vector beanAttributeNames = null;
  +    private TypeDesc typeDesc = null;
       
   
       // Construct BeanSerializer for the indicated class/qname
  @@ -134,16 +136,22 @@
           this.xmlType = xmlType;
           this.javaType = javaType;
           propertyDescriptor = getPd(javaType);
  -        beanAttributeNames = getBeanAttributes(javaType);
  +
  +        // Get the class' TypeDesc if it provides one
  +        try {
  +            Method getTypeDesc = 
  +                    javaType.getMethod("getTypeDesc",
  +                                       new Class [] {});
  +            // get string array
  +            typeDesc = (TypeDesc)getTypeDesc.invoke(null, noArgs);
  +        } catch (Exception e) {
  +        }
       }
   
       // Construct BeanSerializer for the indicated class/qname and format
       public BeanSerializer(Class javaType, QName xmlType, short format) {
  -        this.xmlType = xmlType;
  -        this.javaType = javaType;
  +        this(javaType, xmlType);
           setElementPropertyFormat(format);
  -        propertyDescriptor = getPd(javaType);
  -        beanAttributeNames = getBeanAttributes(javaType);
       }
   
       /**
  @@ -159,10 +167,11 @@
       {
           boolean isSOAP_ENC = Constants.
                   isSOAP_ENC(context.getMessageContext().getEncodingStyle());
  +        
           // Check for meta-data in the bean that will tell us if any of the
           // properties are actually attributes, add those to the element
           // attribute list
  -        Attributes beanAttrs = getObjectAttributes(value, attributes);
  +        Attributes beanAttrs = getObjectAttributes(value, attributes, context);
           context.startElement(name, beanAttrs);
   
           try {
  @@ -171,16 +180,36 @@
                   String propName = propertyDescriptor[i].getName();
                   if (propName.equals("class")) 
                       continue;
  -                //if (!isSOAP_ENC && beanAttributeNames.contains(propName)) 
  -                if (beanAttributeNames.contains(Utils.xmlNameToJava(propName))) 
  -                    continue;
  -                propName = format(propName, elementPropertyFormat);
   
  +                QName qname = null;
  +                
  +                // If we have type metadata, check to see what we're doing
  +                // with this field.  If it's an attribute, skip it.  If it's
  +                // an element, use whatever qname is in there.  If we can't
  +                // find any of this info, use the default.
  +                
  +                if (typeDesc != null) {
  +                    FieldDesc field = typeDesc.getFieldByName(propName);
  +                    if (field != null) {
  +                        if (!field.isElement())
  +                            continue;
  +                        
  +                        qname = field.getXmlName();
  +                    }
  +                }
  +                
  +                if (qname == null) {
  +                    // Use the default...
  +                    propName = format(propName, elementPropertyFormat);
  +                    qname = new QName("", propName);
  +                }
  +                
                   Method readMethod = propertyDescriptor[i].getReadMethod();
                   if (readMethod != null && readMethod.getParameterTypes().length == 0) {
                       // Normal case: serialize the value
                       Object propValue = propertyDescriptor[i].getReadMethod().invoke(value,noArgs);
  -                    context.serialize(new QName("", propName), null,
  +                    context.serialize(qname,
  +                                      null,
                                         propValue,
                                         propertyDescriptor[i].getReadMethod().getReturnType());
                   } else {
  @@ -196,7 +225,7 @@
                               j = -1;
                           }
                           if (j >= 0) {
  -                            context.serialize(new QName("", propName), null,
  +                            context.serialize(qname, null,
                                                 propValue,
                                                 propertyDescriptor[i].getReadMethod().getReturnType());
                           }
  @@ -225,29 +254,46 @@
           }
           return pd;
       }
  -
  +    
       /**
        * Return a list of properties in the bean which should be attributes
        */ 
  -    static Vector getBeanAttributes(Class javaType) {
  -        // See if this object defined the 'getAttributeElements' function
  -        // which returns a Vector of property names that are attributes
  -        try {
  -            Method getAttributeElements = 
  -                    javaType.getMethod("getAttributeElements",
  -                                       new Class [] {});
  -            // get string array
  -            String[] array = (String[])getAttributeElements.invoke(null, noArgs);
  -
  -            // convert it to a Vector
  -            Vector v = new Vector(array.length);
  -            for (int i = 0; i < array.length; i++) {
  -                v.add(array[i]);
  +    static Vector getBeanAttributes(Class javaType, TypeDesc typeDesc) {
  +        Vector ret = new Vector();
  +        
  +        if (typeDesc == null) {
  +            // !!! Support old-style beanAttributeNames for now
  +            
  +            // See if this object defined the 'getAttributeElements' function
  +            // which returns a Vector of property names that are attributes
  +            try {
  +                Method getAttributeElements = 
  +                        javaType.getMethod("getAttributeElements",
  +                                           new Class [] {});
  +                // get string array
  +                String[] array = (String[])getAttributeElements.invoke(null, noArgs);
  +                
  +                // convert it to a Vector
  +                ret = new Vector(array.length);
  +                for (int i = 0; i < array.length; i++) {
  +                    ret.add(array[i]);
  +                }
  +            } catch (Exception e) {
  +                ret.clear();
  +            }
  +        } else {
  +            FieldDesc [] fields = typeDesc.getFields();
  +            if (fields != null) {
  +                for (int i = 0; i < fields.length; i++) {
  +                    FieldDesc field = fields[i];
  +                    if (!field.isElement()) {
  +                        ret.add(field.getFieldName());
  +                    }
  +                }
               }
  -            return v;
  -        } catch (Exception e) {
  -            return new Vector();  // empty vector
           }
  +        
  +        return ret;
       }
       
       
  @@ -342,17 +388,27 @@
           Vector fields = clsRep.getFields();
           for (int i=0; i < fields.size(); i++) {
               FieldRep field = (FieldRep) fields.elementAt(i);
  +            
  +            if (typeDesc != null) {
  +                FieldDesc fieldDesc = typeDesc.getFieldByName(field.getName());
  +                if (fieldDesc != null) {
  +                    if (!fieldDesc.isElement()) {
  +                        // !!! Need to get the QName right, and can only
  +                        //     pass strings???
  +                        writeAttribute(types, field.getName(),
  +                                       field.getType(), 
  +                                       complexType);
  +                    } else {
  +                        // MEN WORKING!!!!
  +                    }
  +                    return true;
  +                }
  +            }
   
  -            // if bean fields are attributes, write attribute element
  -            if (beanAttributeNames.contains(field.getName()))
  -                writeAttribute(types, field.getName(),
  -                               field.getType(), 
  -                               complexType);
  -            else            
  -                writeField(types, field.getName(), 
  -                           field.getType(), 
  -                           field.getIndexed(), 
  -                           all);
  +            writeField(types, field.getName(), 
  +                       field.getType(), 
  +                       field.getIndexed(), 
  +                       all);
           }
           // done
           return true;
  @@ -418,9 +474,10 @@
        * @return attributes for this element, null if none
        */ 
       private Attributes getObjectAttributes(Object value,
  -                                           Attributes attributes) {
  +                                           Attributes attributes,
  +                                           SerializationContext context) {
           
  -        if (beanAttributeNames.isEmpty())
  +        if (typeDesc == null || !typeDesc.hasAttributes())
               return attributes;
   
           AttributesImpl attrs;
  @@ -436,10 +493,17 @@
                   String propName = propertyDescriptor[i].getName();
                   if (propName.equals("class"))
                       continue;
  -                // skip it if its not in the list
  -                if (!beanAttributeNames.contains(Utils.xmlNameToJava(propName)))
  +                
  +                FieldDesc field = typeDesc.getFieldByName(propName);
  +                // skip it if its not an attribute
  +                if (field == null || field.isElement())
                       continue;
  -                propName = format(propName, elementPropertyFormat);
  +                
  +                QName qname = field.getXmlName();
  +                if (qname == null) {
  +                    qname = new QName("",
  +                                      format(propName, elementPropertyFormat));
  +                }
                   
                   Method readMethod = propertyDescriptor[i].getReadMethod();
                   if (readMethod != null && 
  @@ -450,7 +514,15 @@
                       // NOTE: we will always set the attribute here to something, 
                       // which we may not want (i.e. if null, omit it)
                       String propString = propValue != null ? propValue.toString() : "";
  -                    attrs.addAttribute("", propName, propName, "CDATA", propString);
  +                    
  +                    String namespace = qname.getNamespaceURI();
  +                    String localName = qname.getLocalPart();
  +                    
  +                    attrs.addAttribute(namespace, 
  +                                       localName, 
  +                                       context.qName2String(qname), 
  +                                       "CDATA", 
  +                                       propString);
                   }
               }
           } catch (Exception e) {
  
  
  
  1.5       +66 -60    xml-axis/java/src/org/apache/axis/encoding/ser/SimpleDeserializer.java
  
  Index: SimpleDeserializer.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/SimpleDeserializer.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SimpleDeserializer.java	27 Feb 2002 19:19:44 -0000	1.4
  +++ SimpleDeserializer.java	8 Mar 2002 05:04:54 -0000	1.5
  @@ -59,12 +59,14 @@
   import java.io.IOException;
   import java.lang.reflect.Constructor;
   import java.lang.reflect.InvocationTargetException;
  +import java.lang.reflect.Method;
   import java.util.Vector;
   import java.util.HashMap;
   import java.util.Set;
   import java.util.Iterator;
   
   import org.apache.axis.InternalException;
  +import org.apache.axis.description.TypeDesc;
   import org.apache.axis.message.SOAPHandler;
   import org.apache.axis.utils.JavaUtils;
   
  @@ -103,6 +105,8 @@
       public QName xmlType;
       public Class javaType;
   
  +    private TypeDesc typeDesc = null;
  +
       /**
        * The Deserializer is constructed with the xmlType and 
        * javaType (which could be a java primitive like int.class)
  @@ -119,6 +123,17 @@
                   BeanPropertyDescriptor descriptor = pd[i];
                   propertyMap.put(descriptor.getName(), descriptor);
               }
  +
  +            // Get the class' TypeDesc if it provides one
  +            try {
  +                Method getTypeDesc =
  +                        javaType.getMethod("getTypeDesc",
  +                                           new Class [] {});
  +                // get string array
  +                typeDesc = (TypeDesc)getTypeDesc.invoke(null,
  +                                                        BeanSerializer.noArgs);
  +            } catch (Exception e) {
  +            }
           }
           
       }
  @@ -251,76 +266,66 @@
               throws SAXException 
       {
   
  -        // if this isn't a simpleType bean, wont have attributes
  -        if (! SimpleType.class.isAssignableFrom(javaType))
  +        // If we have no metadata, we have no attributes.  Q.E.D.
  +        if (typeDesc == null)
               return;
           
  -        // get list of properties that are really attributes
  -        Vector beanAttributeNames = BeanSerializer.getBeanAttributes(javaType);
  -        
  -        // loop through the attributes and set bean properties that 
  +        // loop through the attributes and set bean properties that
           // correspond to attributes
  -        if (beanAttributeNames != null && 
  -            beanAttributeNames.size() > 0) {
  -            for (int i=0; i < attributes.getLength(); i++) {
  -                String attrName = attributes.getLocalName(i);
  -                String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
  -                String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
  -                String mangledName = JavaUtils.xmlNameToJava(attrName);
  -
  -                // See if the attribute is a beanAttribute name
  -                if (!beanAttributeNames.contains(attrName) &&
  -                    !beanAttributeNames.contains(attrNameUp) &&
  -                    !beanAttributeNames.contains(attrNameLo))
  -                    continue;
  -
  -                if (attributeMap == null)
  -                    attributeMap = new HashMap();
  -                
  -                // look for the attribute property, save the name
  -                attrName = attrNameUp;
  -                BeanPropertyDescriptor bpd = 
  -                    (BeanPropertyDescriptor) propertyMap.get(attrNameUp);
  -                if (bpd == null) {
  -                    attrName = attrNameLo;
  -                    bpd = (BeanPropertyDescriptor) propertyMap.get(attrNameLo);
  -                }
  -                if (bpd == null) {
  -                    attrName = mangledName;
  -                    bpd = (BeanPropertyDescriptor) propertyMap.get(mangledName);
  -                }
  -                if (bpd != null) {
  -                    // determine the QName for this child element
  -                    TypeMapping tm = context.getTypeMapping();
  -                    Class type = bpd.getType();
  -                    QName qn = tm.getTypeQName(type);
  -                    if (qn == null)
  -                        throw new SAXException(
  +        for (int i=0; i < attributes.getLength(); i++) {
  +            QName attrQName = new QName(attributes.getURI(i),
  +                                        attributes.getLocalName(i));
  +            String fieldName = typeDesc.getFieldNameForAttribute(attrQName);
  +            if (fieldName == null)
  +                continue;
  +
  +            String attrName = attributes.getLocalName(i);
  +            String attrNameUp = BeanSerializer.format(attrName, BeanSerializer.FORCE_UPPER);
  +            String attrNameLo = BeanSerializer.format(attrName, BeanSerializer.FORCE_LOWER);
  +            String mangledName = JavaUtils.xmlNameToJava(attrName);
  +
  +            // look for the attribute property
  +            BeanPropertyDescriptor bpd =
  +                    (BeanPropertyDescriptor) propertyMap.get(fieldName);
  +            if (bpd != null) {
  +                if (bpd.getWriteMethod() == null ) continue ;
  +
  +                // determine the QName for this child element
  +                TypeMapping tm = context.getTypeMapping();
  +                Class type = bpd.getType();
  +                QName qn = tm.getTypeQName(type);
  +                if (qn == null)
  +                    throw new SAXException(
                               JavaUtils.getMessage("unregistered00", type.toString()));
  -                
  -                    // get the deserializer
  -                    Deserializer dSer = context.getDeserializerForType(qn);
  -                    if (dSer == null)
  -                        throw new SAXException(
  +
  +                // get the deserializer
  +                Deserializer dSer = context.getDeserializerForType(qn);
  +                if (dSer == null)
  +                    throw new SAXException(
                               JavaUtils.getMessage("noDeser00", type.toString()));
  -                    if (! (dSer instanceof SimpleDeserializer))
  -                        throw new SAXException(
  -                                JavaUtils.getMessage("AttrNotSimpleType00", 
  -                                        bpd.getName(), 
  -                                        type.toString()));
  -                    
  -                    // Success!  Store name, value in HashMap for later
  +                if (! (dSer instanceof SimpleDeserializer))
  +                    throw new SAXException(
  +                            JavaUtils.getMessage("AttrNotSimpleType00",
  +                                                 bpd.getName(),
  +                                                 type.toString()));
  +
  +                if (bpd.getWriteMethod().getParameterTypes().length == 1) {
  +                    // Success!  Create an object from the string and save
  +                    // it in our attribute map for later.
  +                    if (attributeMap == null) {
  +                        attributeMap = new HashMap();
  +                    }
                       try {
                           Object val = ((SimpleDeserializer)dSer).
                                   makeValue(attributes.getValue(i));
  -                        attributeMap.put(attrName, val);
  +                        attributeMap.put(fieldName, val);
                       } catch (Exception e) {
                           throw new SAXException(e);
                       }
  -                
  -                } // if bpd != null
  -            } // attribute loop
  -        } // if attributes exist
  +                }
  +
  +            } // if
  +        } // attribute loop
       } // onStartElement
   
       /**
  @@ -328,7 +333,8 @@
        */ 
       private void setSimpleTypeAttributes() throws SAXException {
           // if this isn't a simpleType bean, wont have attributes
  -        if (! SimpleType.class.isAssignableFrom(javaType))
  +        if (! SimpleType.class.isAssignableFrom(javaType) ||
  +            attributeMap == null)
               return;
           
           // loop through map
  
  
  
  1.5       +55 -23    xml-axis/java/src/org/apache/axis/encoding/ser/SimpleSerializer.java
  
  Index: SimpleSerializer.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/SimpleSerializer.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SimpleSerializer.java	27 Feb 2002 23:46:32 -0000	1.4
  +++ SimpleSerializer.java	8 Mar 2002 05:04:54 -0000	1.5
  @@ -67,6 +67,8 @@
   
   import org.apache.axis.Constants;
   import org.apache.axis.AxisFault;
  +import org.apache.axis.description.TypeDesc;
  +import org.apache.axis.description.FieldDesc;
   import org.apache.axis.wsdl.fromJava.Types;
   import org.apache.axis.wsdl.fromJava.ClassRep;
   import org.apache.axis.wsdl.fromJava.FieldRep;
  @@ -94,8 +96,8 @@
       public Class javaType;
       
       private BeanPropertyDescriptor[] propertyDescriptor = null;
  -    private Vector beanAttributeNames = null;
  -    
  +    private TypeDesc typeDesc = null;
  +
       public SimpleSerializer(Class javaType, QName xmlType) {
           this.xmlType = xmlType;
           this.javaType = javaType;
  @@ -103,7 +105,16 @@
           if (SimpleType.class.isAssignableFrom(javaType)) {
               // get the bean properties and the list of attributes from the bean
               propertyDescriptor = BeanSerializer.getPd(javaType);
  -            beanAttributeNames = BeanSerializer.getBeanAttributes(javaType);
  +            // Get the class' TypeDesc if it provides one
  +            try {
  +                Method getTypeDesc =
  +                        javaType.getMethod("getTypeDesc",
  +                                           new Class [] {});
  +                // get string array
  +                typeDesc = (TypeDesc)getTypeDesc.invoke(null,
  +                                                        BeanSerializer.noArgs);
  +            } catch (Exception e) {
  +            }
           }
       }
       /**
  @@ -123,7 +134,7 @@
   
           // get any attributes
           if (value instanceof SimpleType)
  -            attributes = getObjectAttributes(value, attributes);
  +            attributes = getObjectAttributes(value, attributes, context);
           
           context.startElement(name, attributes);
           if (value != null) {
  @@ -159,39 +170,55 @@
           context.endElement();
       }
   
  -    private Attributes getObjectAttributes(Object value, Attributes attributes) {
  -        
  -        // if nothing, return
  -        if (beanAttributeNames.isEmpty())
  +    private Attributes getObjectAttributes(Object value,
  +                                           Attributes attributes,
  +                                           SerializationContext context) {
  +        if (typeDesc == null || !typeDesc.hasAttributes())
               return attributes;
  -        
  +
           AttributesImpl attrs;
           if (attributes != null)
               attrs = new AttributesImpl(attributes);
           else
               attrs = new AttributesImpl();
  -        
  +
           try {
  -            // Find each property that is an attribute 
  +            // Find each property that is an attribute
               // and add it to our attribute list
               for (int i=0; i<propertyDescriptor.length; i++) {
                   String propName = propertyDescriptor[i].getName();
                   if (propName.equals("class"))
                       continue;
  -                // skip it if its not in the list
  -                if (!beanAttributeNames.contains(Utils.xmlNameToJava(propName)))
  +
  +                FieldDesc field = typeDesc.getFieldByName(propName);
  +                // skip it if its not an attribute
  +                if (field == null || field.isElement())
                       continue;
  -                
  +
  +                QName qname = field.getXmlName();
  +                if (qname == null) {
  +                    qname = new QName("", Utils.xmlNameToJava(propName));
  +                }
  +
                   Method readMethod = propertyDescriptor[i].getReadMethod();
  -                if (readMethod != null && 
  -                        readMethod.getParameterTypes().length == 0) {
  +                if (readMethod != null &&
  +                    readMethod.getParameterTypes().length == 0) {
                       // add to our attributes
                       Object propValue = propertyDescriptor[i].
  -                            getReadMethod().invoke(value, new Object[]{});
  -                    // NOTE: we will always set the attribute here to something, 
  +                                        getReadMethod().
  +                                        invoke(value,BeanSerializer.noArgs);
  +                    // NOTE: we will always set the attribute here to something,
                       // which we may not want (i.e. if null, omit it)
                       String propString = propValue != null ? propValue.toString() : "";
  -                    attrs.addAttribute("", propName, propName, "CDATA", propString);
  +
  +                    String namespace = qname.getNamespaceURI();
  +                    String localName = qname.getLocalPart();
  +
  +                    attrs.addAttribute(namespace,
  +                                       localName,
  +                                       context.qName2String(qname),
  +                                       "CDATA",
  +                                       propString);
                   }
               }
           } catch (Exception e) {
  @@ -253,17 +280,22 @@
           // allows users to provide their own field mapping.
           ClassRep clsRep = types.getBeanBuilder().build(javaType);
   
  -        // Write out fields
  +        // Write out fields (only attributes are allowed)
  +        if (typeDesc == null || !typeDesc.hasAttributes())
  +            return true;
  +
           Vector fields = clsRep.getFields();
           for (int i=0; i < fields.size(); i++) {
               FieldRep field = (FieldRep) fields.elementAt(i);
   
               String fieldName = field.getName();
  -            
  -            // if bean fields are attributes, write attribute element
  -            if (!beanAttributeNames.contains(fieldName)) {
  +
  +            FieldDesc fieldDesc = typeDesc.getFieldByName(field.getName());
  +            if (fieldDesc == null || fieldDesc.isElement()) {
  +                // Really, it's an error to have element descriptors in there!
                   continue;
               }
  +
               //  write attribute element
               Class fieldType = field.getType();
               
  
  
  
  1.15      +31 -6     xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaComplexTypeWriter.java
  
  Index: JavaComplexTypeWriter.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaComplexTypeWriter.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- JavaComplexTypeWriter.java	28 Feb 2002 19:19:23 -0000	1.14
  +++ JavaComplexTypeWriter.java	8 Mar 2002 05:04:54 -0000	1.15
  @@ -123,6 +123,15 @@
           if (type.isSimpleType())
               implementsText = ", org.apache.axis.encoding.SimpleType";
   
  +        // For now, do the imports only if we have attributes.  This will
  +        // need to happen for any mapping later.
  +        if (attributes != null) {
  +            pw.println("import org.apache.axis.description.FieldDesc;");
  +            pw.println("import org.apache.axis.description.TypeDesc;");
  +            pw.println("import org.apache.axis.description.AttributeDesc;");
  +            pw.println();
  +        }
  +
           pw.println("public class " + className + extendsText +
                      " implements java.io.Serializable" + implementsText + " {");
   
  @@ -223,20 +232,36 @@
          
           // if we have attributes, create metadata function which returns the
           // list of properties that are attributes instead of elements
  +
  +        // Glen 3/7/02 : This is now using the type metadata model which
  +        // provides for arbitrary mapping of XML elements or attributes
  +        // <-> Java fields.  We need to generalize this to support element
  +        // mappings as well, but right now this is just to keep the attribute
  +        // mechanism working.
  +
           if (attributes != null) {
  -            pw.println("    // List of fields that are XML attributes");
  -            pw.println("    private static java.lang.String[] _attrs = new String[] {");
  +            pw.println("    // Type metadata");
  +            pw.println("    private static org.apache.axis.description.TypeDesc typeDesc =");
  +            pw.println("        new org.apache.axis.description.TypeDesc();");
  +            pw.println();
  +            pw.println("    static {");
               for (int i = 0; i < attributes.size(); i += 2) {
  -                pw.println("        \"" + Utils.xmlNameToJava((String) attributes.get(i + 1)) + "\", ");
  +                String fieldName =
  +                        Utils.xmlNameToJava((String) attributes.get(i + 1));
  +                pw.print("        ");
  +                if (i == 0) pw.print("org.apache.axis.description.FieldDesc ");
  +                pw.println("field = new org.apache.axis.description.AttributeDesc();");
  +                pw.println("        field.setFieldName(\"" + fieldName + "\");");
  +                pw.println("        typeDesc.addFieldDesc(field);");
               }
               pw.println("    };");
               pw.println();
   
               pw.println("    /**");
  -            pw.println("     * Return list of bean field names that are attributes");
  +            pw.println("     * Return type metadata object");
               pw.println("     */");
  -            pw.println("    public static java.lang.String[] getAttributeElements() {");
  -            pw.println("        return _attrs;");
  +            pw.println("    public static org.apache.axis.description.TypeDesc getTypeDesc() {");
  +            pw.println("        return typeDesc;");
               pw.println("    }");
               pw.println();
           }
  
  
  
  1.2       +52 -13    xml-axis/java/test/encoding/AttributeBean.java
  
  Index: AttributeBean.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/encoding/AttributeBean.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AttributeBean.java	25 Feb 2002 15:24:14 -0000	1.1
  +++ AttributeBean.java	8 Mar 2002 05:04:54 -0000	1.2
  @@ -53,6 +53,13 @@
   * <http://www.apache.org/>.
   */
   
  +import org.apache.axis.description.AttributeDesc;
  +import org.apache.axis.description.ElementDesc;
  +import org.apache.axis.description.FieldDesc;
  +import org.apache.axis.description.TypeDesc;
  +
  +import javax.xml.rpc.namespace.QName;
  +
   /**
    * Simple Java Bean with fields that should be serialized as attributes
    */ 
  @@ -103,18 +110,50 @@
       public void setMale(boolean male) {
           this.male = male;
       }
  -    
  -    // List of fields that are XML attributes
  -    public static java.lang.String[] _attrs = new String[] {
  -        "name", 
  -        "male", 
  -    };
  -    
  -    /**
  -     * Return list of bean field names that are attributes
  -     */
  -    public static java.lang.String[] getAttributeElements() {
  -        return _attrs;
  +
  +    public boolean equals(Object obj)
  +    {
  +        if (obj == null || !(obj instanceof AttributeBean))
  +            return false;
  +        AttributeBean other = (AttributeBean)obj;
  +        if (other.getAge() != age)
  +            return false;
  +        if (other.getID() != iD)
  +            return false;
  +        if (other.getMale() != male)
  +            return false;
  +        if (name == null)
  +            return other.getName() == null;
  +        return name.equals(other.getName());
  +    }
  +
  +    // Type metadata
  +    private static TypeDesc typeDesc;
  +    
  +    static {
  +        typeDesc = new TypeDesc();
  +        FieldDesc field;
  +
  +        // An attribute with a specified QName
  +        field = new AttributeDesc();
  +        field.setFieldName("name");
  +        field.setXmlName(new QName("foo", "nameAttr"));
  +        typeDesc.addFieldDesc(field);
  +
  +        // An attribute with a default QName
  +        field = new AttributeDesc();
  +        field.setFieldName("male");
  +        typeDesc.addFieldDesc(field);
  +
  +        // An element with a specified QName
  +        field = new ElementDesc();
  +        field.setFieldName("age");
  +        field.setXmlName(new QName("foo", "ageElement"));
  +        typeDesc.addFieldDesc(field);
  +    }
  +    
  +    public static TypeDesc getTypeDesc()
  +    {
  +        return typeDesc;
       }
  -    
   }
  
  
  
  1.2       +83 -52    xml-axis/java/test/encoding/TestAttributes.java
  
  Index: TestAttributes.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/encoding/TestAttributes.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestAttributes.java	25 Feb 2002 15:24:14 -0000	1.1
  +++ TestAttributes.java	8 Mar 2002 05:04:54 -0000	1.2
  @@ -8,9 +8,17 @@
   import org.apache.axis.encoding.SerializationContextImpl;
   import org.apache.axis.encoding.TypeMappingRegistry;
   import org.apache.axis.encoding.TypeMapping;
  +import org.apache.axis.encoding.SimpleType;
   import org.apache.axis.encoding.ser.BeanSerializerFactory;
   import org.apache.axis.encoding.ser.BeanDeserializerFactory;
  +import org.apache.axis.encoding.ser.SimpleDeserializerFactory;
  +import org.apache.axis.encoding.ser.SimpleNonPrimitiveSerializerFactory;
   import org.apache.axis.Constants;
  +import org.apache.axis.Message;
  +import org.apache.axis.description.TypeDesc;
  +import org.apache.axis.description.FieldDesc;
  +import org.apache.axis.description.OperationDesc;
  +import org.apache.axis.description.ServiceDesc;
   import org.apache.axis.utils.XMLUtils;
   import org.apache.axis.client.Call;
   import org.apache.axis.message.RPCElement;
  @@ -25,6 +33,7 @@
   import java.io.StringReader;
   import java.io.StringWriter;
   import java.io.Writer;
  +import java.util.Vector;
   
   import AttributeBean;
   
  @@ -32,6 +41,7 @@
    *  Test the serialization of a bean with attributes
    * 
    * @author Tom Jordahl (tomj@macromedia.com)
  + * @author Glen Daniels (gdaniels@apache.org)
    */
   public class TestAttributes extends TestCase {
       static Log log =
  @@ -43,35 +53,17 @@
       {
           TestAttributes tester = new TestAttributes("TestAttributes");
           tester.testBean();
  +        tester.testSimpleType();
       }
       
       public TestAttributes(String name) {
           super(name);
       }
       
  -    static final String expectedXML =
  -            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
  -            "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
  -            " <SOAP-ENV:Body>\n" +
  -            "  <method1 xmlns=\"urn:myNamespace\">\n" +
  -            "   <struct name=\"James Bond\" male=\"true\">\n" +
  -            "    <ID>1.15</ID>\n" +
  -            "    <age>35</age>\n" +
  -            "   </struct>\n" +
  -            "  </method1>\n" +
  -            " </SOAP-ENV:Body>\n" +
  -            "</SOAP-ENV:Envelope>";
  -    
       public void testBean () throws Exception {
           MessageContext msgContext = new MessageContext(new AxisServer());
           SOAPEnvelope msg = new SOAPEnvelope();
           
  -        // set no encoding (use=literal)
  -        msgContext.setEncodingStyle(null);
  -        // Don't serialize xsi:type attributes
  -        msgContext.setProperty(Call.SEND_TYPE_ATTR, "false" );
  -
  -        
           // Create bean with data
           AttributeBean bean = new AttributeBean();
           bean.setAge(35);
  @@ -93,8 +85,8 @@
           TypeMappingRegistry reg = context.getTypeMappingRegistry();
           TypeMapping tm = (TypeMapping) reg.createTypeMapping();
           // The "" namespace is literal (no encoding).
  -        tm.setSupportedNamespaces(new String[] {""});
  -        reg.register("", tm);
  +        tm.setSupportedNamespaces(new String[] {Constants.URI_CURRENT_SOAP_ENC});
  +        reg.register(Constants.URI_CURRENT_SOAP_ENC, tm);
           
           QName beanQName = new QName("typeNS", "TheBean");
           tm.register(AttributeBean.class, 
  @@ -106,40 +98,79 @@
           msg.output(context);
           // Get the XML as a string
           String msgString = stringWriter.toString();
  -        // verify results
  -        assertEquals("Serialized bean and expected results don't match",
  -                      expectedXML, msgString);
  -        
  +
           log.debug("---");
           log.debug(msgString);
           log.debug("---");
  -/*        
  -        TODO: This part of the test is wrong
  -        
  -        // Now feed the XML in to the deserializer
  -        StringReader reader = new StringReader(msgString);
  -        DeserializationContext dser = new DeserializationContextImpl(
  -            new InputSource(reader), msgContext, org.apache.axis.Message.REQUEST);
  -
  -        // deserialize it
  -        dser.parse();
  -
  -        // get the results
  -        SOAPEnvelope env = dser.getEnvelope();
  -        RPCElement rpcElem = (RPCElement)env.getFirstBody();
  -        RPCParam struct = rpcElem.getParam("struct");
  -        assertNotNull("No <struct> param", struct);
  -        
  -        Object obj = struct.getValue();
  -        System.out.println(obj.toString());
  -        AttributeBean val = (AttributeBean)struct.getValue();
  -        assertNotNull("No value for struct param", val);
  -        
  -        assertEquals("Bean and Val Age members are not equal", bean.getAge(), val.getAge());
  -        assertEquals("Bean and Val ID members are not equal",bean.getID(), bean.getID(), 1.15F);
  -        assertEquals("Bean and Val boolean attributes are not equal",bean.getMale(), bean.getMale());
  -        assertEquals("Bean and Val name attributes are not equal",bean.getName(), bean.getName());
  -*/
  +
  +        Message message = new Message(msgString);
  +        message.setMessageContext(msgContext);
  +        SOAPEnvelope env = message.getSOAPPart().getAsSOAPEnvelope();
  +        RPCElement rpcEl = (RPCElement)env.getFirstBody();
  +        Vector params = rpcEl.getParams();
  +        assertEquals("Wrong # of params in deserialized message!",
  +                     1,
  +                     params.size());
  +
  +        Object obj = ((RPCParam)params.get(0)).getValue();
  +        assertTrue("Deserialized param not an AttributeBean!",
  +                   (obj instanceof AttributeBean));
  +
  +        AttributeBean deserBean = (AttributeBean)obj;
  +        assertTrue("Deserialized bean not equal to expected values!",
  +                   (bean.equals(deserBean)));
       }
   
  +    public void testSimpleType() throws Exception {
  +        SimpleBean bean = new SimpleBean("test value");
  +        bean.temp = 85.0F;
  +
  +        MessageContext msgContext = new MessageContext(new AxisServer());
  +        SOAPEnvelope msg = new SOAPEnvelope();
  +
  +        RPCParam arg = new RPCParam("", "simple", bean);
  +        RPCElement body = new RPCElement("urn:myNamespace", "method1", new Object[]{ arg });
  +        msg.addBodyElement(body);
  +        body.setEncodingStyle(null);
  +
  +        StringWriter writer = new StringWriter();
  +        SerializationContext context = new SerializationContextImpl(writer,
  +                                                                    msgContext);
  +        context.setDoMultiRefs(false);
  +
  +        // Create a TypeMapping and register the Bean serializer/deserializer
  +        TypeMappingRegistry reg = context.getTypeMappingRegistry();
  +        TypeMapping tm = (TypeMapping) reg.createTypeMapping();
  +        // The "" namespace is literal (no encoding).
  +        tm.setSupportedNamespaces(new String[] {Constants.URI_CURRENT_SOAP_ENC});
  +        reg.register(Constants.URI_CURRENT_SOAP_ENC, tm);
  +
  +        QName beanQName = new QName("typeNS", "Bean");
  +        tm.register(SimpleBean.class,
  +                    beanQName,
  +                    new SimpleNonPrimitiveSerializerFactory(SimpleBean.class, beanQName),
  +                    new SimpleDeserializerFactory(SimpleBean.class, beanQName));
  +
  +        // Serialize the bean in to XML
  +        msg.output(context);
  +        // Get the XML as a string
  +        String msgString = writer.toString();
  +
  +        Message message = new Message(msgString);
  +        message.setMessageContext(msgContext);
  +        SOAPEnvelope env = message.getSOAPPart().getAsSOAPEnvelope();
  +        RPCElement rpcEl = (RPCElement)env.getFirstBody();
  +        Vector params = rpcEl.getParams();
  +        assertEquals("Wrong # of params in deserialized message!",
  +                     1,
  +                     params.size());
  +
  +        Object obj = ((RPCParam)params.get(0)).getValue();
  +        assertTrue("Deserialized param not a SimpleBean!",
  +                   (obj instanceof SimpleBean));
  +
  +        SimpleBean deserBean = (SimpleBean)obj;
  +        assertTrue("Deserialized bean not equal to expected values!",
  +                   (bean.equals(deserBean)));
  +    }
   }
  
  
  
  1.1                  xml-axis/java/test/encoding/SimpleBean.java
  
  Index: SimpleBean.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package test.encoding;
  
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.FieldDesc;
  import org.apache.axis.description.TypeDesc;
  import org.apache.axis.encoding.SimpleType;
  
  import javax.xml.rpc.namespace.QName;
  
  /**
   * A simple type with attributes for testing
   */
  public class SimpleBean implements SimpleType {
      public String value;  // Our "actual" value
      public float temp;   // An attribute
  
      private static TypeDesc typeDesc = new TypeDesc();
      static {
          FieldDesc fd = new AttributeDesc();
          fd.setFieldName("temp");
          fd.setXmlName(new QName("foo", "temp"));
          typeDesc.addFieldDesc(fd);
      }
      public static TypeDesc getTypeDesc() { return typeDesc; }
  
      /**
       * String constructor
       */
      public SimpleBean(String val)
      {
          value = val;
      }
  
      public String getValue() {
          return value;
      }
  
      public void setValue(String value) {
          this.value = value;
      }
  
      public float getTemp() {
          return temp;
      }
  
      public void setTemp(float temp) {
          this.temp = temp;
      }
  
      public String toString() {
          return value;
      }
  
      public boolean equals(Object obj)
      {
          if (obj == null || !(obj instanceof SimpleBean))
              return false;
          SimpleBean other = (SimpleBean)obj;
          if (other.getTemp() != temp) {
              return false;
          }
          if (value == null) {
              return other.getValue() == null;
          }
          return value.equals(other.getValue());
      }
  }