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 sc...@apache.org on 2002/08/27 01:44:34 UTC

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

scheu       2002/08/26 16:44:34

  Modified:    java/src/org/apache/axis/encoding/ser BeanDeserializer.java
                        SimpleDeserializer.java
               java/test/encoding AttributeBean.java
  Log:
  Problem:
  Each string element or attribute inside of a bean causes a SimpleDeserializer to
  be constructed, registered, processed etc.  This is a performance hit.
  
  Solution:
  If a BeanDeserializer constructs a SimpleDeserializer for a string, it is cached
  and reused.  This prevents a lot of construction/garbage collection.  It also
  speeds up the processing of obtaining string deserializers.
  
  Added two methods to SimpleDeserializer. The method reset() simply resets
  the information for re-use.  The removeValueTargets method() resets the
  value targets without removing the Vector.
  
  I also organized this code under the new BeanDeserializer.getDeserializer method.
  
  I ran some performance tests with Beans containing lots of Strings and
  the BeanDeserializer.onStartChild was reduced 3 times faster.
  
  Future:
  1) I would like to make a similar change for arrays
  
  Revision  Changes    Path
  1.50      +79 -51    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.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- BeanDeserializer.java	24 Aug 2002 01:25:19 -0000	1.49
  +++ BeanDeserializer.java	26 Aug 2002 23:44:33 -0000	1.50
  @@ -100,6 +100,9 @@
       // This counter is updated to deal with deserialize collection properties
       protected int collectionIndex = -1;
   
  +    protected SimpleDeserializer cacheStringDSer = null;
  +    protected QName cacheXMLType = null;
  +
       // Construct BeanSerializer for the indicated class/qname
       public BeanDeserializer(Class javaType, QName xmlType) {
           this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType));
  @@ -247,47 +250,23 @@
                                            localName));
           }
   
  -        // Look at the type attribute specified.  If this fails,
  -        // use the javaType of the property to get the type qname.
  -        QName qn = context.getTypeFromXSITypeAttr(namespace, 
  -                                                  localName,
  -                                                  attributes);
  -
  -        // get the deserializer
  -        Deserializer dSer = null;
  -        if (qn !=null) {
  -            dSer = context.getDeserializerForType(qn);
  -        }
  -
  -        // We don't have a deserializer, the safest thing to do
  -        // is to set up using the DeserializerImpl below.  
  -        // The DeserializerImpl will take care of href/id and
  -        // install the appropriate deserializer, etc.  The problem 
  -        // is that takes a lot of time and will occur 
  -        // all the time if no xsi:types are sent.  Most of the
  -        // time an element of a bean is a simple schema type (i.e. String)
  -        // so the following shortcut is used to get a Deserializer
  -        // for these cases.
  +        // Get the child's xsi:type if available
  +        QName childXMLType = context.getTypeFromXSITypeAttr(namespace, 
  +                                                            localName,
  +                                                            attributes);
  +        
  +        // Get Deserializer for child, default to using DeserializerImpl
  +        Deserializer dSer = getDeserializer(childXMLType, propDesc.getType(), 
  +                                            attributes.getValue("href"),
  +                                            context);
  +        // It is an error if the dSer is not found, the base
  +        // deserializer impl is returned so that it can generate the correct message.
           if (dSer == null) {
  -            Class javaType = propDesc.getType();
  -            TypeMapping tm = context.getTypeMapping();
  -            QName qName = tm.getTypeQName(javaType);
  -            if (qn == null && dSer == null) {
  -                if (qName != null && SchemaUtils.isSimpleSchemaType(qName)) {
  -                    dSer = context.getDeserializer(javaType, qName);
  -                }
  -            }
  -            
  -            // 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 javaType for this child element
  -                dSer.setDefaultType(qName);
  -            }
  +            dSer = new DeserializerImpl();
  +            return (SOAPHandler)dSer;
           }
  -                
  +
  +        // Register value target
           if (propDesc.isWriteable()) {
               // If this is an indexed property, and the deserializer we found
               // was NOT the ArrayDeserializer, this is a non-SOAP array:
  @@ -379,25 +358,20 @@
               if (bpd != null) {
                   if (!bpd.isWriteable() || bpd.isIndexed() ) continue ;
                   
  -                // determine the QName for this child element
  -                TypeMapping tm = context.getTypeMapping();
  -                Class type = bpd.getType();
  -                QName qn = tm.getTypeQName(type);
  -                if (qn == null)
  +                // Get the Deserializer for the attribute
  +                Deserializer dSer = getDeserializer(null, bpd.getType(), 
  +                                                    null, context);
  +
  +                if (dSer == null)
                       throw new SAXException(
                               JavaUtils.getMessage("unregistered00",
  -                                                 type.toString()));
  +                                                 bpd.getType().toString()));
                   
  -                // 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()));
  +                                                 bpd.getType().toString()));
                   
                   // Success!  Create an object from the string and set
                   // it in the bean
  @@ -413,5 +387,59 @@
                   
               } // if
           } // attribute loop
  +    }
  +
  +    /**
  +     * Get the Deserializer for the attribute or child element.
  +     * @param xmlType QName of the attribute/child element or null if not known.
  +     * @param javaType Class of the corresponding property
  +     * @param href String is the value of the href attribute, which is used
  +     *             to determine whether the child element is complete or an 
  +     *             href to another element.
  +     * @param context DeserializationContext
  +     * @return Deserializer or null if not found.
  +    */
  +    protected Deserializer getDeserializer(QName xmlType, 
  +                                           Class javaType, 
  +                                           String href,
  +                                           DeserializationContext context) {
  +        // See if we have a cached deserializer
  +        if (cacheStringDSer != null) {
  +            if (String.class.equals(javaType) &&
  +                (cacheXMLType == null && xmlType == null ||
  +                 cacheXMLType != null && cacheXMLType.equals(xmlType))) {
  +                cacheStringDSer.reset();
  +                return cacheStringDSer;
  +            }
  +        }
  +        
  +        Deserializer dSer = null;
  +
  +        if (xmlType != null) {
  +            // Use the xmlType to get the deserializer.
  +            dSer = context.getDeserializerForType(xmlType);
  +        } else {
  +            // If the xmlType is not set, get a default xmlType
  +            TypeMapping tm = context.getTypeMapping();
  +            QName defaultXMLType = tm.getTypeQName(javaType);
  +            // If there is not href, then get the deserializer
  +            // using the javaType and default XMLType,
  +            // If there is an href, the create the generic
  +            // DeserializerImpl and set its default type (the
  +            // default type is used if the href'd element does 
  +            // not have an xsi:type.
  +            if (href == null) {
  +                dSer = context.getDeserializer(javaType, defaultXMLType);
  +            } else {
  +                dSer = new DeserializerImpl();
  +                dSer.setDefaultType(defaultXMLType);
  +            }
  +        }
  +        if (javaType.equals(String.class) &&
  +            dSer instanceof SimpleDeserializer) {
  +            cacheStringDSer = (SimpleDeserializer) dSer;
  +            cacheXMLType = xmlType;
  +        }
  +        return dSer;
       }
   }
  
  
  
  1.22      +25 -1     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.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- SimpleDeserializer.java	3 Aug 2002 21:25:25 -0000	1.21
  +++ SimpleDeserializer.java	26 Aug 2002 23:44:33 -0000	1.22
  @@ -98,6 +98,8 @@
   
       private TypeDesc typeDesc = null;
   
  +    protected SimpleDeserializer cacheStringDSer = null;
  +    protected QName cacheXMLType = null;
       /**
        * The Deserializer is constructed with the xmlType and 
        * javaType (which could be a java primitive like int.class)
  @@ -141,7 +143,29 @@
               }
           }
       }
  -      
  +
  +    /**
  +     * Reset deserializer for re-use
  +     */
  +    public void reset() {
  +        val.setLength(0); // Reset string buffer back to zero
  +        attributeMap = null; // Remove attribute map
  +        isNil = false; // Don't know if nil
  +        isEnded = false; // Indicate the end of element not yet called
  +    }
  +
  +    /**
  +     * Remove the Value Targets of the Deserializer.
  +     * Simple deserializers may be re-used, so don't
  +     * nullify the vector.
  +     */
  +    public void removeValueTargets() {
  +        if (targets != null) {
  +            targets.clear();
  +            // targets = null;
  +        }
  +    }
  +
       /** 
        * The Factory calls setConstructor.
        */
  
  
  
  1.7       +1 -1      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.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AttributeBean.java	11 Jun 2002 14:54:02 -0000	1.6
  +++ AttributeBean.java	26 Aug 2002 23:44:34 -0000	1.7
  @@ -133,7 +133,7 @@
               return false;
           }
           if (company == null) {
  -            if (company != null) {
  +            if (other.company != null) {
                   return false;
               }
           } else if (!company.equals(other.company)) {