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]>