Author: scheu Date: Wed Dec 8 19:42:20 2010 New Revision: 1043641 URL: http://svn.apache.org/viewvc?rev=1043641&view=rev Log: AXIS2-4907 Contributor:Rich Scheuerle Summary: Added shortcuts to the JAX-WS JAXBWrapperTool to speed-up wrapper bean processing when the wrapper bean has zero or one child properties.
Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java?rev=1043641&r1=1043640&r2=1043641&view=diff ============================================================================== --- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java (original) +++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java Wed Dec 8 19:42:20 2010 @@ -135,8 +135,6 @@ public class DocLitWrappedMethodMarshall wrapperObject = ((JAXBElement)wrapperObject).getValue(); } - // Use the wrapper tool to get the child objects. - JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl(); // Get the list of names for the output parameters List<String> names = new ArrayList<String>(); @@ -150,57 +148,83 @@ public class DocLitWrappedMethodMarshall } } - // The return name is added as the last name - if (isChildReturn && !isNoReturn) { - names.add(operationDesc.getResultPartName()); - } - - // Get the child objects - Object[] objects = wrapperTool.unWrap(wrapperObject, names, - marshalDesc.getPropertyDescriptorMap( - wrapperObject.getClass())); - - // Now create a list of paramValues so that we can populate the signature - List<PDElement> pvList = new ArrayList<PDElement>(); - for (int i = 0; i < pdList.size(); i++) { - ParameterDescription pd = pdList.get(i); - Object value = objects[i]; - // The object in the PDElement must be an element - Element element = null; - QName qName = new QName(pd.getTargetNamespace(), pd.getPartName()); - if (!marshalDesc.getAnnotationDesc(pd.getParameterActualType()).hasXmlRootElement()) - { - element = new Element(value, qName, - pd.getParameterActualType()); + if (pdList.size() == 0) { + // No OUT or INOUT parameters + // Use return only shortcut + if (isNoReturn) { + returnValue = null; + } else if (isChildReturn) { + String returnName = operationDesc.getResultPartName(); + // Use the wrapper tool to get the child objects. + JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl(); + Object object = wrapperTool.unWrap(wrapperObject, + returnName, + marshalDesc.getPropertyDescriptorMap( + wrapperObject.getClass()).get(returnName)); + returnValue = object; } else { - element = new Element(value, qName); + returnValue = wrapperObject; + } + } else { + // There are one or more OUT or INOUT parameters + // The return name is added as the last name + if (isChildReturn && !isNoReturn) { + names.add(operationDesc.getResultPartName()); } - pvList.add(new PDElement(pd, element, null)); - } - // Populate the response Holders in the signature - MethodMarshallerUtils.updateResponseSignatureArgs(pds, pvList, signatureArgs); + // Use the wrapper tool to get the child objects. + JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl(); + + // Get the child objects + Object[] objects = wrapperTool.unWrap(wrapperObject, names, + marshalDesc.getPropertyDescriptorMap( + wrapperObject.getClass())); + + // Now create a list of paramValues so that we can populate the signature + List<PDElement> pvList = new ArrayList<PDElement>(); + for (int i = 0; i < pdList.size(); i++) { + ParameterDescription pd = pdList.get(i); + Object value = objects[i]; + // The object in the PDElement must be an element + Element element = null; + QName qName = new QName(pd.getTargetNamespace(), pd.getPartName()); + if (!marshalDesc.getAnnotationDesc(pd.getParameterActualType()).hasXmlRootElement()) + { + element = new Element(value, qName, + pd.getParameterActualType()); + + } else { + element = new Element(value, qName); + } + pvList.add(new PDElement(pd, element, null)); + } - // Now get the return value - if (isNoReturn) { - returnValue = null; - } else if (isChildReturn) { - returnValue = objects[objects.length - 1]; - // returnValue may be incompatible with JAX-WS signature - if (ConvertUtils.isConvertable(returnValue, returnType)) { - returnValue = ConvertUtils.convert(returnValue, returnType); + // Populate the response Holders in the signature + MethodMarshallerUtils.updateResponseSignatureArgs(pds, pvList, signatureArgs); + + // Now get the return value + if (isNoReturn) { + returnValue = null; + } else if (isChildReturn) { + returnValue = objects[objects.length - 1]; + // returnValue may be incompatible with JAX-WS signature + if (ConvertUtils.isConvertable(returnValue, returnType)) { + returnValue = ConvertUtils.convert(returnValue, returnType); + } else { + String objectClass = + (returnValue == null) ? "null" : returnValue.getClass().getName(); + throw ExceptionFactory.makeWebServiceException( + Messages.getMessage("convertProblem", objectClass, + returnType.getName())); + } } else { - String objectClass = - (returnValue == null) ? "null" : returnValue.getClass().getName(); - throw ExceptionFactory.makeWebServiceException( - Messages.getMessage("convertProblem", objectClass, - returnType.getName())); + returnValue = wrapperObject; } - } else { - returnValue = wrapperObject; } + + return returnValue; } catch (Exception e) { throw ExceptionFactory.makeWebServiceException(e); @@ -366,41 +390,68 @@ public class DocLitWrappedMethodMarshall signatureArgs, false, // output true, false); - + + String wrapperName = marshalDesc.getResponseWrapperClassName(operationDesc); + Class cls = loadClass(wrapperName, endpointDesc); + JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl(); + Object object = null; + + // Add the return object to the nameList and objectList + Class returnType = operationDesc.getResultActualType(); + // Now we want to create a single JAXB element that contains the // ParameterValues. We will use the wrapper tool to do this. // Create the inputs to the wrapper tool - ArrayList<String> nameList = new ArrayList<String>(); - Map<String, Object> objectList = new HashMap<String, Object>(); - Map<String, Class> declaredClassMap = new HashMap<String, Class>(); + if (pdeList.size() == 0) { + if (returnType == void.class) { + // Use the short-cut for void return + object = wrapperTool.wrap(cls, + (String) null, + null, + null, + null); + } else { + // Use the short-cut for a single return + String childName = operationDesc.getResultName(); + object = wrapperTool.wrap(cls, + childName, + returnObject, + returnType, + marshalDesc.getPropertyDescriptorMap(cls).get(childName)); + } + } else { - for (PDElement pde : pdeList) { - String name = pde.getParam().getParameterName(); - - // The object list contains type rendered objects - Object value = pde.getElement().getTypeValue(); - Class dclClass = pde.getParam().getParameterActualType(); - - nameList.add(name); - objectList.put(name, value); - declaredClassMap.put(name, dclClass); - } + // Now we want to create a single JAXB element that contains the + // ParameterValues. We will use the wrapper tool to do this. + // Create the inputs to the wrapper tool + ArrayList<String> nameList = new ArrayList<String>(); + Map<String, Object> objectList = new HashMap<String, Object>(); + Map<String, Class> declaredClassMap = new HashMap<String, Class>(); + + for (PDElement pde : pdeList) { + String name = pde.getParam().getParameterName(); + + // The object list contains type rendered objects + Object value = pde.getElement().getTypeValue(); + Class dclClass = pde.getParam().getParameterActualType(); + + nameList.add(name); + objectList.put(name, value); + declaredClassMap.put(name, dclClass); + } - // Add the return object to the nameList and objectList - Class returnType = operationDesc.getResultActualType(); - if (returnType != void.class) { - String name = operationDesc.getResultName(); - nameList.add(name); - objectList.put(name, returnObject); - declaredClassMap.put(name, returnType); - } + // Add the return type + if (returnType != void.class) { + String name = operationDesc.getResultName(); + nameList.add(name); + objectList.put(name, returnObject); + declaredClassMap.put(name, returnType); + } - // Now create the single JAXB element - String wrapperName = marshalDesc.getResponseWrapperClassName(operationDesc); - Class cls = loadClass(wrapperName, endpointDesc); - JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl(); - Object object = wrapperTool.wrap(cls, nameList, objectList, declaredClassMap, - marshalDesc.getPropertyDescriptorMap(cls)); + + object = wrapperTool.wrap(cls, nameList, objectList, declaredClassMap, + marshalDesc.getPropertyDescriptorMap(cls)); + } QName wrapperQName = new QName(operationDesc.getResponseWrapperTargetNamespace(), operationDesc.getResponseWrapperLocalName()); @@ -478,31 +529,51 @@ public class DocLitWrappedMethodMarshall true, // input true, false); + String wrapperName = marshalDesc.getRequestWrapperClassName(operationDesc); + Class cls = loadClass(wrapperName, endpointDesc); + JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl(); + Object object = null; + // Now we want to create a single JAXB element that contains the // ParameterValues. We will use the wrapper tool to do this. // Create the inputs to the wrapper tool - ArrayList<String> nameList = new ArrayList<String>(); - Map<String, Object> objectList = new HashMap<String, Object>(); - Map<String, Class> declaredClassMap = new HashMap<String, Class>(); - - for (PDElement pv : pvList) { - String name = pv.getParam().getParameterName(); - - // The object list contains type rendered objects - Object value = pv.getElement().getTypeValue(); - Class dclClass = pv.getParam().getParameterActualType(); - nameList.add(name); - objectList.put(name, value); - declaredClassMap.put(name, dclClass); - } + if (pvList.size() == 0) { + // Use the short-cut for 0 children + object = wrapperTool.wrap(cls, + (String) null, + null, + null, + null); + } else if (pvList.size() == 1) { + // Use the short-cut for 1 child + PDElement pde = pvList.get(0); + String childName = pde.getParam().getParameterName(); + object = wrapperTool.wrap(cls, + childName, + pde.getElement().getTypeValue(), + pde.getParam().getParameterActualType(), + marshalDesc.getPropertyDescriptorMap(cls).get(childName)); + + } else { + ArrayList<String> nameList = new ArrayList<String>(); + Map<String, Object> objectList = new HashMap<String, Object>(); + Map<String, Class> declaredClassMap = new HashMap<String, Class>(); + + for (PDElement pv : pvList) { + String name = pv.getParam().getParameterName(); + + // The object list contains type rendered objects + Object value = pv.getElement().getTypeValue(); + Class dclClass = pv.getParam().getParameterActualType(); + nameList.add(name); + objectList.put(name, value); + declaredClassMap.put(name, dclClass); + } - // Now create the single JAXB element - String wrapperName = marshalDesc.getRequestWrapperClassName(operationDesc); - Class cls = loadClass(wrapperName, endpointDesc); - - JAXBWrapperTool wrapperTool = new JAXBWrapperToolImpl(); - Object object = wrapperTool.wrap(cls, nameList, objectList, declaredClassMap, - marshalDesc.getPropertyDescriptorMap(cls)); + + object = wrapperTool.wrap(cls, nameList, objectList, declaredClassMap, + marshalDesc.getPropertyDescriptorMap(cls)); + } QName wrapperQName = new QName(operationDesc.getRequestWrapperTargetNamespace(), operationDesc.getRequestWrapperLocalName()); Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java?rev=1043641&r1=1043640&r2=1043641&view=diff ============================================================================== --- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java (original) +++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java Wed Dec 8 19:42:20 2010 @@ -53,6 +53,17 @@ public interface JAXBWrapperTool { public Object[] unWrap(Object jaxbObject, List<String> childNames) throws JAXBWrapperException; + /** + * Short cut if there is only one Object in the JAXB Object + * + * @param jaxbObject that represents the type + * @param childName xml child names as String + * @param pd PropertyDescriptor + * @return child Object value + */ + public Object unWrap(Object jaxbObject, + String childName, + PropertyDescriptorPlus pd) throws JAXBWrapperException; /** * wrap Creates a jaxb object that is initialized with the child objects. @@ -89,5 +100,23 @@ public interface JAXBWrapperTool { Map<String, Object> childObjects) throws JAXBWrapperException; + /** + * Short Cut for JAXB objects with one child + * wrap Creates a jaxb object that is initialized with one child object. + * <p/> + * Note that the jaxbClass must be the class the represents the complexType. (It should never be + * JAXBElement) + * + * @param jaxbClass + * @param childName xml child name as String or null if no child + * @param childObject component type object + * @param declaredClass declared class + * @param pd PropertyDescriptor for this jaxbObject + */ + public Object wrap(Class jaxbClass, + String childName, + Object childObject, + Class declaredClass, + PropertyDescriptorPlus pd) throws JAXBWrapperException; } Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java?rev=1043641&r1=1043640&r2=1043641&view=diff ============================================================================== --- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java (original) +++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java Wed Dec 8 19:42:20 2010 @@ -103,7 +103,119 @@ public class JAXBWrapperToolImpl impleme return jaxbObjects; } + + /** + * Short cut if there is one Object in the JAXB Object + * + * @param jaxbObject that represents the type + * @param childName xml child names as String + * @param pd PropertyDescriptor + * @return child Object value + */ + public Object unWrap(Object jaxbObject, + String childName, + PropertyDescriptorPlus pd) throws JAXBWrapperException { + + + if (jaxbObject == null) { + throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr1")); + } + if (childName == null) { + throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr2")); + } + + // Get the object that will have the property descriptors (i.e. the object representing the complexType) + Object jaxbComplexTypeObj = jaxbObject; + + if (log.isDebugEnabled()) { + log.debug("Invoking unWrap() method with jaxb object:" + + jaxbComplexTypeObj.getClass().getName()); + log.debug("The input child xmlnames are: " + childName); + } + + // Get the child object from the jaxb bean + Object retValue = null; + if (pd == null) { + throw new JAXBWrapperException( + Messages.getMessage("JAXBWrapperErr6", + jaxbComplexTypeObj.getClass().getName(), + childName)); + } + try { + retValue = pd.get(jaxbComplexTypeObj); + } catch (Throwable e) { + if (log.isDebugEnabled()) { + log.debug("An exception " + e.getClass() + + "occurred while trying to call get() on " + pd); + log.debug("The corresponding xml child name is: " + childName); + } + throw new JAXBWrapperException(e); + } + return retValue; + } + + /** + * wrap Creates a jaxb object that is initialized with one child object. + * <p/> + * Note that the jaxbClass must be the class the represents the complexType. (It should never be + * JAXBElement) + * + * @param jaxbClass + * @param childName xml child name as String or null if no child + * @param childObject component type object + * @param declaredClass declared class + * @param pd PropertyDescriptor for this jaxbObject + */ + public Object wrap(Class jaxbClass, + String childName, + Object childObject, + Class declaredClass, + PropertyDescriptorPlus pd) throws JAXBWrapperException { + + if (log.isDebugEnabled()) { + log.debug("Invoking unwrap() method to create jaxb object:" + jaxbClass.getName()); + log.debug("The input child xmlname is: " + childName); + } + // The jaxb object always has a default constructor. Create the object + Object jaxbObject = null; + try { + jaxbObject = jaxbClass.newInstance(); + } catch (Throwable t) { + if (log.isDebugEnabled()) { + log.debug("An exception " + t.getClass() + + "occurred while trying to create jaxbobject " + jaxbClass.getName()); + } + throw new JAXBWrapperException(t); + } + + + if (childName != null) { + // Now set the child object onto the jaxb object + if (pd == null) { + throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr6", + jaxbClass.getName(), + childName)); + } + try { + pd.set(jaxbObject, childObject, declaredClass); + } catch (Throwable t) { + + if (log.isDebugEnabled()) { + log.debug("An exception " + t.getClass() + + "occurred while trying to call set() on " + pd); + log.debug("The corresponding xml child name is: " + childName); + String name = (childObject == null) ? "<null>" : childObject.getClass().getName(); + log.debug("The corresponding value object is: " + name); + } + throw new JAXBWrapperException(t); + } + } + + // Return the jaxb object + return jaxbObject; + } + /** * wrap Creates a jaxb object that is initialized with the child objects. * <p/>