sandholm 2003/02/25 21:18:55
Modified: java/src/org/apache/axis/encoding Tag:
dynamic_deserialization_branch
DeserializationContext.java
DeserializationContextImpl.java
DeserializerImpl.java SerializationContextImpl.java
java/src/org/apache/axis/encoding/ser Tag:
dynamic_deserialization_branch
ArrayDeserializer.java BeanDeserializer.java
SimpleDeserializer.java
java/src/org/apache/axis/message Tag:
dynamic_deserialization_branch MessageElement.java
RPCHandler.java
java/src/org/apache/axis/wsdl/toJava Tag:
dynamic_deserialization_branch
JavaEnumTypeWriter.java
Log:
added support for dynamic deserialization based on class meta data (in separate
branch)
Revision Changes Path
No revision
No revision
1.52.2.1 +24 -0
xml-axis/java/src/org/apache/axis/encoding/DeserializationContext.java
Index: DeserializationContext.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/DeserializationContext.java,v
retrieving revision 1.52
retrieving revision 1.52.2.1
diff -u -r1.52 -r1.52.2.1
--- DeserializationContext.java 11 Dec 2002 22:38:13 -0000 1.52
+++ DeserializationContext.java 26 Feb 2003 05:18:53 -0000 1.52.2.1
@@ -168,6 +168,30 @@
*/
public Deserializer getDeserializerForType(QName xmlType);
+ /**
+ * Convenience method to get the Deserializer for a specific
+ * java class from its meta data.
+ * @param cls is the Class used to find the deserializer
+ * @return Deserializer
+ */
+ public Deserializer getDeserializerForClass(Class cls);
+
+ /**
+ * Allows the destination class to be set so that downstream
+ * deserializers like ArrayDeserializer can pick it up when
+ * deserializing its components using getDeserializerForClass
+ * @param destClass is the Class of the component to be deserialized
+ */
+ public void setDestinationClass(Class destClass);
+
+ /**
+ * Allows the destination class to be retrieved so that downstream
+ * deserializers like ArrayDeserializer can pick it up when
+ * deserializing its components using getDeserializerForClass
+ * @return the Class of the component to be deserialized
+ */
+ public Class getDestinationClass();
+
/**
* Get the TypeMapping for this DeserializationContext
*/
1.74.2.1 +59 -0
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.74
retrieving revision 1.74.2.1
diff -u -r1.74 -r1.74.2.1
--- DeserializationContextImpl.java 18 Feb 2003 13:19:37 -0000 1.74
+++ DeserializationContextImpl.java 26 Feb 2003 05:18:54 -0000 1.74.2.1
@@ -74,6 +74,7 @@
import org.apache.axis.utils.Messages;
import org.apache.axis.utils.NSStack;
import org.apache.axis.utils.XMLUtils;
+import org.apache.axis.description.TypeDesc;
import org.apache.commons.logging.Log;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
@@ -89,6 +90,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.lang.reflect.Method;
/**
* @author Glen Daniels ([EMAIL PROTECTED])
@@ -111,6 +113,10 @@
private Locator locator;
+ // Class used for deserialization using class metadata from
+ // downstream deserializers
+ private Class destClass;
+
// for performance reasons, keep the top of the stack separate from
// the remainder of the handlers, and therefore readily available.
private SOAPHandler topHandler = null;
@@ -136,6 +142,10 @@
private MessageElement curElement;
protected int startOfMappingsPos = -1;
+
+ private static final Class[] DESERIALIZER_CLASSES =
+ new Class[] {String.class, Class.class, QName.class};
+ private static final String DESERIALIZER_METHOD = "getDeserializer";
// This is a hack to associate the first schema namespace we see with
// the correct SchemaVersion. It assumes people won't often be mixing
@@ -455,6 +465,55 @@
}
}
return dser;
+ }
+
+ /**
+ * Convenience method to get the Deserializer for a specific
+ * java class from its meta data.
+ * @param cls is the Class used to find the deserializer
+ * @return Deserializer
+ */
+ public Deserializer getDeserializerForClass(Class cls) {
+ if (cls == null) {
+ cls = destClass;
+ }
+ if (cls == null) {
+ return null;
+ }
+ Deserializer dser = null;
+ try {
+ Method method = cls.getMethod(DESERIALIZER_METHOD,
DESERIALIZER_CLASSES);
+ if (method != null) {
+ TypeDesc typedesc = TypeDesc.getTypeDescForClass(cls);
+ if (typedesc != null) {
+ dser = (Deserializer) method.invoke(null,
+ new Object[] {msgContext.getEncodingStyle(), cls,
typedesc.getXmlType()});
+ }
+ }
+ } catch (Exception e) {
+ log.error(Messages.getMessage("noDeser00", cls.getName()));
+ }
+ return dser;
+ }
+
+ /**
+ * Allows the destination class to be set so that downstream
+ * deserializers like ArrayDeserializer can pick it up when
+ * deserializing its components using getDeserializerForClass
+ * @param destClass is the Class of the component to be deserialized
+ */
+ public void setDestinationClass(Class destClass) {
+ this.destClass = destClass;
+ }
+
+ /**
+ * Allows the destination class to be retrieved so that downstream
+ * deserializers like ArrayDeserializer can pick it up when
+ * deserializing its components using getDeserializerForClass
+ * @return the Class of the component to be deserialized
+ */
+ public Class getDestinationClass() {
+ return destClass;
}
/**
1.33.2.1 +3 -0 xml-axis/java/src/org/apache/axis/encoding/DeserializerImpl.java
Index: DeserializerImpl.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/DeserializerImpl.java,v
retrieving revision 1.33
retrieving revision 1.33.2.1
diff -u -r1.33 -r1.33.2.1
--- DeserializerImpl.java 20 Dec 2002 17:28:21 -0000 1.33
+++ DeserializerImpl.java 26 Feb 2003 05:18:54 -0000 1.33.2.1
@@ -471,6 +471,9 @@
// attribute type qname.
if (type != null) {
Deserializer dser =
(Deserializer)context.getDeserializerForType(type);
+ if (dser == null) {
+ dser = (Deserializer)context.getDeserializerForClass(null);
+ }
if (dser != null) {
// Move the value targets to the new deserializer
dser.moveValueTargets(this);
1.89.2.1 +32 -19
xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java
Index: SerializationContextImpl.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java,v
retrieving revision 1.89
retrieving revision 1.89.2.1
diff -u -r1.89 -r1.89.2.1
--- SerializationContextImpl.java 3 Feb 2003 23:16:36 -0000 1.89
+++ SerializationContextImpl.java 26 Feb 2003 05:18:54 -0000 1.89.2.1
@@ -132,8 +132,9 @@
private boolean pretty = false;
private static QName multirefQName = new QName("","multiRef");
- private static Class[] getSerializerClasses =
+ private static Class[] SERIALIZER_CLASSES =
new Class[] {String.class, Class.class, QName.class};
+ private static final String SERIALIZER_METHOD = "getSerializer";
/**
* Should I write out objects as multi-refs?
@@ -1231,32 +1232,40 @@
// if no serializer was configured try to find one dynamically using
WSDLJava
// generated metadata
- try {
- Method method = value.getClass().getMethod(
- "getSerializer", getSerializerClasses);
- if (method != null) {
- Serializer serializer = (Serializer) method.invoke(value,
- new Object[] {"", value.getClass(), elemQName});
- TypeDesc typedesc =
TypeDesc.getTypeDescForClass(value.getClass());
- if (typedesc != null) {
- QName qname = typedesc.getXmlType();
- if (qname != null) {
- attributes = setTypeAttribute(attributes,
- qname);
- }
+ Class cls = value.getClass();
+ Serializer serializer = getSerializerFromClass(cls, elemQName);
+ if (serializer != null) {
+ TypeDesc typedesc = TypeDesc.getTypeDescForClass(value.getClass());
+ if (typedesc != null) {
+ QName qname = typedesc.getXmlType();
+ if (qname != null) {
+ attributes = setTypeAttribute(attributes,
+ qname);
}
- serializer.serialize(elemQName, attributes, value, this);
- return;
}
- } catch (Exception e) {
+ serializer.serialize(elemQName, attributes, value, this);
+ return;
}
-
throw new IOException(Messages.getMessage("noSerializer00",
value.getClass().getName(), "" + tm));
}
// !!! Write out a generic null, or get type info from somewhere else?
}
+ private Serializer getSerializerFromClass(Class javaType, QName qname) {
+ Serializer serializer = null;
+ try {
+ Method method = javaType.getMethod(
+ SERIALIZER_METHOD, SERIALIZER_CLASSES);
+ if (method != null) {
+ serializer = (Serializer) method.invoke(null,
+ new Object[] {msgContext.getEncodingStyle(), javaType, qname});
+ }
+ } catch (Exception e) {
+ }
+ return serializer;
+ }
+
/**
* Get the currently prefered xmlType
* @return QName of xmlType or null
@@ -1348,7 +1357,11 @@
}
public String getValueAsString(Object value, QName xmlType) throws IOException {
- Serializer ser = getSerializer(value.getClass(), xmlType, null);
+ Class cls = value.getClass();
+ Serializer ser = getSerializer(cls, xmlType, null);
+ if (ser == null) {
+ ser = getSerializerFromClass(cls, xmlType);
+ }
if (!(ser instanceof SimpleValueSerializer)) {
throw new IOException(
Messages.getMessage("needSimpleValueSer",
No revision
No revision
1.35.2.1 +4 -0
xml-axis/java/src/org/apache/axis/encoding/ser/ArrayDeserializer.java
Index: ArrayDeserializer.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/ArrayDeserializer.java,v
retrieving revision 1.35
retrieving revision 1.35.2.1
diff -u -r1.35 -r1.35.2.1
--- ArrayDeserializer.java 24 Feb 2003 19:54:01 -0000 1.35
+++ ArrayDeserializer.java 26 Feb 2003 05:18:54 -0000 1.35.2.1
@@ -299,6 +299,10 @@
}
}
}
+ if (arrayClass == null) {
+ arrayClass = context.getDestinationClass();
+ context.setDestinationClass(arrayClass.getComponentType());
+ }
if (arrayClass == null) {
throw new SAXException(
1.59.2.1 +11 -13
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.59
retrieving revision 1.59.2.1
diff -u -r1.59 -r1.59.2.1
--- BeanDeserializer.java 20 Dec 2002 17:28:20 -0000 1.59
+++ BeanDeserializer.java 26 Feb 2003 05:18:54 -0000 1.59.2.1
@@ -284,18 +284,11 @@
// to deserialize something we have no clue about (no good xsi:type,
// no good metadata).
if (dSer == null) {
-
-// FIXME : Currently this doesn't throw an error solely to enable the
-// "terra" testcase to pass. We should, IMO, fix the test (either
-// to support <xsd:list> or to throw an error when we find such a thing
-// in the WSDL at WSDL2Java time). Once that's done, this should be
-// uncommented and the next two lines deleted.
-//
-// throw new SAXException(Messages.getMessage("noDeser00",
-// childXMLType.toString()));
-
- dSer = new DeserializerImpl();
- return (SOAPHandler)dSer;
+ dSer = context.getDeserializerForClass(propDesc.getType());
+ }
+ if (dSer == null) {
+ throw new SAXException(Messages.getMessage("noDeser00",
+ childXMLType.toString()));
}
// Register value target
@@ -398,7 +391,9 @@
// Get the Deserializer for the attribute
Deserializer dSer = getDeserializer(null, bpd.getType(),
null, context);
-
+ if (dSer == null) {
+ dSer = context.getDeserializerForClass(bpd.getType());
+ }
if (dSer == null)
throw new SAXException(
Messages.getMessage("unregistered00",
@@ -440,6 +435,9 @@
Class javaType,
String href,
DeserializationContext context) {
+ if (javaType.isArray()) {
+ context.setDestinationClass(javaType.getComponentType());
+ }
// See if we have a cached deserializer
if (cacheStringDSer != null) {
if (String.class.equals(javaType) &&
1.31.2.1 +3 -0
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.31
retrieving revision 1.31.2.1
diff -u -r1.31 -r1.31.2.1
--- SimpleDeserializer.java 18 Feb 2003 06:02:00 -0000 1.31
+++ SimpleDeserializer.java 26 Feb 2003 05:18:54 -0000 1.31.2.1
@@ -277,6 +277,9 @@
return new Double(Double.NEGATIVE_INFINITY);
}
}
+ if (constructor == null) {
+ return null;
+ }
return constructor.newInstance(new Object [] { source });
}
No revision
No revision
1.144.2.1 +27 -7 xml-axis/java/src/org/apache/axis/message/MessageElement.java
Index: MessageElement.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/MessageElement.java,v
retrieving revision 1.144
retrieving revision 1.144.2.1
diff -u -r1.144 -r1.144.2.1
--- MessageElement.java 12 Feb 2003 19:01:12 -0000 1.144
+++ MessageElement.java 26 Feb 2003 05:18:55 -0000 1.144.2.1
@@ -498,13 +498,24 @@
* Returns value of the node as an object of registered type.
* @return Object of proper type, or null if no mapping could be found.
*/
- public Object getObjectValue(){
+ public Object getObjectValue() {
+ Object obj = null;
+ try {
+ obj = getObjectValue(null);
+ } catch (Exception e) {
+ log.debug("getValue()", e);
+ }
+ return obj;
+ }
+
+ /**
+ * Returns value of the node as an object of registered type.
+ * @param cls Class that contains top level deserializer metadata
+ * @return Object of proper type, or null if no mapping could be found.
+ */
+ public Object getObjectValue(Class cls) throws Exception {
if (objectValue == null) {
- try {
- objectValue = getValueAsType(getType());
- } catch (Exception e) {
- log.debug("getValue()", e);
- }
+ objectValue = getValueAsType(getType(), cls);
}
return objectValue;
}
@@ -540,10 +551,19 @@
public Object getValueAsType(QName type) throws Exception
{
+ return getValueAsType(type, null);
+ }
+ public Object getValueAsType(QName type, Class cls) throws Exception
+ {
if (context == null)
throw new Exception(Messages.getMessage("noContext00"));
- Deserializer dser = context.getDeserializerForType(type);
+ Deserializer dser = null;
+ if (cls == null) {
+ dser = context.getDeserializerForType(type);
+ } else {
+ dser = context.getDeserializerForClass(cls);
+ }
if (dser == null)
throw new Exception(Messages.getMessage("noDeser00", "" + type));
1.69.2.1 +8 -3 xml-axis/java/src/org/apache/axis/message/RPCHandler.java
Index: RPCHandler.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCHandler.java,v
retrieving revision 1.69
retrieving revision 1.69.2.1
diff -u -r1.69 -r1.69.2.1
--- RPCHandler.java 20 Dec 2002 17:28:22 -0000 1.69
+++ RPCHandler.java 26 Feb 2003 05:18:55 -0000 1.69.2.1
@@ -247,6 +247,9 @@
}
destClass = paramDesc.getJavaType();
+ if ((destClass != null) && (destClass.isArray())) {
+ context.setDestinationClass(destClass);
+ }
// Keep the association so we can use it later
// (see RPCProvider.processMessage())
@@ -294,6 +297,9 @@
}
if (dser == null) {
+ dser = context.getDeserializerForClass(destClass);
+ }
+ if (dser == null) {
throw new SAXException(Messages.getMessage(
"noDeser01", localName,"" + type));
}
@@ -308,10 +314,9 @@
}
}
} else {
- dser = new DeserializerImpl();
+ dser = context.getDeserializerForClass(destClass);
if (dser == null) {
- throw new SAXException(Messages.getMessage(
- "noDeser01", localName,"" + type));
+ dser = new DeserializerImpl();
}
}
}
No revision
No revision
1.20.2.1 +37 -0
xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaEnumTypeWriter.java
Index: JavaEnumTypeWriter.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaEnumTypeWriter.java,v
retrieving revision 1.20
retrieving revision 1.20.2.1
diff -u -r1.20 -r1.20.2.1
--- JavaEnumTypeWriter.java 15 Jan 2003 00:29:14 -0000 1.20
+++ JavaEnumTypeWriter.java 26 Feb 2003 05:18:55 -0000 1.20.2.1
@@ -67,6 +67,7 @@
*/
public class JavaEnumTypeWriter extends JavaClassWriter {
private Vector elements;
+ private TypeEntry type;
/**
* Constructor.
@@ -76,6 +77,7 @@
TypeEntry type, Vector elements) {
super(emitter, type.getName(), "enumType");
this.elements = elements;
+ this.type = type;
} // ctor
/**
@@ -245,6 +247,41 @@
}
pw.println(" public java.lang.Object readResolve() throws
java.io.ObjectStreamException { return fromValue(_value_);}");
+
+ pw.println(" public static org.apache.axis.encoding.Serializer
getSerializer(");
+ pw.println(" java.lang.String mechType, ");
+ pw.println(" java.lang.Class _javaType, ");
+ pw.println(" javax.xml.namespace.QName _xmlType) {");
+ pw.println(" return ");
+ pw.println(" new org.apache.axis.encoding.ser.EnumSerializer(");
+ pw.println(" _javaType, _xmlType);");
+ pw.println(" }");
+ pw.println(" public static org.apache.axis.encoding.Deserializer
getDeserializer(");
+ pw.println(" java.lang.String mechType, ");
+ pw.println(" java.lang.Class _javaType, ");
+ pw.println(" javax.xml.namespace.QName _xmlType) {");
+ pw.println(" return ");
+ pw.println(" new org.apache.axis.encoding.ser.EnumDeserializer(");
+ pw.println(" _javaType, _xmlType);");
+ pw.println(" }");
+
+ pw.println(" // " + Messages.getMessage("typeMeta"));
+ pw.println(" private static org.apache.axis.description.TypeDesc
typeDesc =");
+ pw.println(" new org.apache.axis.description.TypeDesc(" +
+ Utils.getJavaLocalName(type.getName()) + ".class);");
+ pw.println();
+
+ pw.println(" static {");
+ pw.println(" typeDesc.setXmlType(" +
Utils.getNewQName(type.getQName()) + ");");
+ pw.println(" }");
+ pw.println(" /**");
+ pw.println(" * " + Messages.getMessage("returnTypeMeta"));
+ pw.println(" */");
+ pw.println(" public static org.apache.axis.description.TypeDesc
getTypeDesc() {");
+ pw.println(" return typeDesc;");
+ pw.println(" }");
+ pw.println();
+
} // writeFileBody
/**