snichol 2003/01/08 12:20:44
Modified: java/src/org/apache/soap/server RPCRouter.java
java/src/org/apache/soap/util/xml
XMLJavaMappingRegistry.java
Log:
Oops. The previous commit to SOAPMappingRegistry depended on
uncommitted changes to XMLJavaMappingRegistry. The changes are used by
RPCRouter. I've tested them some. Although I intended more changes in
this area, why not just commit what I've got now.
Revision Changes Path
1.19 +23 -1 xml-soap/java/src/org/apache/soap/server/RPCRouter.java
Index: RPCRouter.java
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/RPCRouter.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- RPCRouter.java 4 Dec 2002 03:33:01 -0000 1.18
+++ RPCRouter.java 8 Jan 2003 20:20:43 -0000 1.19
@@ -10,6 +10,7 @@
import org.apache.soap.*;
import org.apache.soap.rpc.*;
import org.apache.soap.util.StringUtils;
+import org.apache.soap.encoding.soapenc.SoapEncUtils;
/**
* This class is a transport independent SOAP RPC router. However you
@@ -18,6 +19,7 @@
* an object you give me).
*
* @author Sanjiva Weerawarana <[EMAIL PROTECTED]>
+ * @author Scott Nichol ([EMAIL PROTECTED])
*/
public class RPCRouter {
public static Call extractCallFromEnvelope (ServiceManager serviceManager,
@@ -145,7 +147,27 @@
Object ret = m.invoke(targetObject, args);
Class retType = m.getReturnType();
- result = new Bean(retType.isPrimitive() ? retType : ret.getClass(), ret);
+
+ // See if we change return type for polymorphism, doing as little
+ // work as possible in the cases where there is no polymorphism.
+ if (retType != void.class && !retType.isPrimitive()) {
+ Class retClass = ret.getClass();
+ if (retClass != retType) {
+ Hashtable props = dd.getProps();
+ if (props != null) {
+ String val = (String) props.get("PolymorphicSerialization");
+ if (val != null && SoapEncUtils.decodeBooleanValue(val)) {
+ Class serClass = call.getSOAPMappingRegistry()
+ .getCompatibleClassWithSerializer(retClass,
+
respEncStyle);
+ if (serClass != null)
+ retType = serClass;
+ }
+ }
+ }
+ }
+
+ result = new Bean(retType, ret);
} else {
// find the class that provides the BSF services (done
// this way via reflection to avoid a compile-time dependency on BSF)
1.13 +115 -0
xml-soap/java/src/org/apache/soap/util/xml/XMLJavaMappingRegistry.java
Index: XMLJavaMappingRegistry.java
===================================================================
RCS file:
/home/cvs/xml-soap/java/src/org/apache/soap/util/xml/XMLJavaMappingRegistry.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- XMLJavaMappingRegistry.java 18 Nov 2002 20:19:26 -0000 1.12
+++ XMLJavaMappingRegistry.java 8 Jan 2003 20:20:44 -0000 1.13
@@ -58,6 +58,7 @@
package org.apache.soap.util.xml;
import java.io.*;
+import java.lang.reflect.Array;
import java.util.*;
import org.w3c.dom.*;
import org.apache.soap.util.*;
@@ -203,6 +204,27 @@
}
/**
+ * This version returns null if the serializer is not found. It is
+ * intended for internal usage (its used for chaining registries,
+ * for example). It does not check for a default serializer.
+ *
+ * @param javaType The Java type.
+ * @param encodingStyleURI The encoding style.
+ * @return The serializer for the Java type and encoding style, null
+ * if one is not found.
+ */
+ protected Serializer querySerializerNoDefault_(Class javaType,
+ String encodingStyleURI)
+ {
+ Maps maps = getMapsForEncoding(encodingStyleURI);
+ Object java2XMLKey = "";
+ if (javaType != null)
+ java2XMLKey = javaType;
+
+ return (Serializer) maps.sReg.get(java2XMLKey);
+ }
+
+ /**
* This version calls the protected method to do the work and if it's
* not found throws an exception.
*
@@ -252,6 +274,27 @@
}
/**
+ * This version returns null if the deserializer is not found. It is
+ * intended for internal usage (its used for chaining registries,
+ * for example). It does not check for a default deserializer.
+ *
+ * @param elementType The XML type.
+ * @param encodingStyleURI The encoding style.
+ * @return The deserializer for the XML type and encoding style, null
+ * if one is not found.
+ */
+ protected Deserializer queryDeserializerNoDefault_(QName elementType,
+ String encodingStyleURI)
+ {
+ Maps maps = getMapsForEncoding(encodingStyleURI);
+ Object xml2JavaKey = "";
+ if (elementType != null)
+ xml2JavaKey = elementType;
+
+ return (Deserializer) maps.dsReg.get(xml2JavaKey);
+ }
+
+ /**
* This version calls the protected method to do the work and if its
* not found throws an exception.
*
@@ -368,6 +411,78 @@
"' using encoding style '" +
encodingStyleURI + "'.");
}
+ }
+
+ /**
+ * Gets the first class in the inheritance hierarchy that has a serializer.
+ *
+ * @param type The class at the end of the hierarchy.
+ * @param encodingStyle The encoding style.
+ * @return The first class with a serializer, null if none found.
+ */
+ public Class getClassWithSerializer(Class type, String encodingStyle) {
+ boolean isArray = type.isArray();
+ if (isArray)
+ type = type.getComponentType();
+ while (type != null) {
+ if (querySerializer_(type, encodingStyle) != null) {
+ if (isArray)
+ type = Array.newInstance(type, 0).getClass();
+ return type;
+ }
+ type = type.getSuperclass();
+ }
+ return null;
+ }
+
+ /**
+ * Gets the first class in the inheritance hierarchy of an array of classes
+ * that has a serializer.
+ *
+ * @param classes The classes at the ends of the hierarchies.
+ * @param encodingStyle The encoding style.
+ * @return The first class with a serializer, null if none found.
+ */
+ public Class getClassWithSerializer(Class[] classes, String encodingStyle) {
+ boolean done = false;
+ while (!done) {
+ done = true;
+ for (int i = 0; i < classes.length; i++) {
+ Class type = classes[i];
+ if (type != null) {
+ if (type.isArray())
+ throw new IllegalArgumentException("Array classes are not allowed");
+ done = false;
+ if (querySerializer_(type, encodingStyle) != null)
+ return type;
+ classes[i] = type.getSuperclass();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the first compatible class that has a serializer, first searching the
+ * inheritance hierachy, then the hierachies of the implemented interfaces.
+ *
+ * @param type The class at the end of the hierarchy.
+ * @param encodingStyle The encoding style.
+ * @return The first compatible class with a serializer, null if none found.
+ */
+ public Class getCompatibleClassWithSerializer(Class type, String encodingStyle) {
+ boolean isArray = type.isArray();
+ if (isArray)
+ type = type.getComponentType();
+ Class serClass = getClassWithSerializer(type, encodingStyle);
+ if (serClass == null)
+ serClass = getClassWithSerializer(type.getInterfaces(), encodingStyle);
+ if (serClass != null) {
+ if (isArray)
+ serClass = Array.newInstance(serClass, 0).getClass();
+ return serClass;
+ }
+ return null;
}
/**
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>