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)) {