// 3) The name of the data block (m:operationResponse) is defined by the schema.
// It matches the operation name + "Response", and it has a corresponding JAXB element.
// This element is called the wrapper element
// 4) The parameters are (param) are child elements of the wrapper element.
ParameterDescription[] pds = operationDesc.getParameterDescriptions();
MarshalServiceRuntimeDescription marshalDesc =
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
TreeSet<String> packages = marshalDesc.getPackages();
String packagesKey = marshalDesc.getPackagesKey();
// Remember this unmarshal information so that we can speed up processing
// the next time.
MessageContext mc = message.getMessageContext();
if (MethodMarshallerUtils.getUnmarshalInfoParameter(mc) == null &&
shouldRegiserUnmarshalInfo(operationDesc, marshalDesc, endpointDesc)) {
MethodMarshallerUtils.registerUnmarshalInfo(message.getMessageContext(),
packages,
packagesKey);
}
// Determine if a returnValue is expected.
// The return value may be an child element
// The wrapper element
// or null
Object returnValue = null;
Class returnType = operationDesc.getResultActualType();
boolean isChildReturn = !operationDesc.isJAXWSAsyncClientMethod() &&
(operationDesc.getResultPartName() != null);
boolean isNoReturn = (returnType == void.class);
// In usage=WRAPPED, there will be a single JAXB block inside the body.
// Get this block
JAXBBlockContext blockContext = new JAXBBlockContext(packages, packagesKey);
blockContext.setWebServiceNamespace(ed.getTargetNamespace());
// If the wrapper is not a root element, then the process type
// must be set on the context so that "by type" unmarshal is performed.
if (!isResponseWrapperAnXmlRootElement(operationDesc, marshalDesc, endpointDesc)) {
String clsName = marshalDesc.getResponseWrapperClassName(operationDesc);
Class cls = loadClass(clsName,endpointDesc);
blockContext.setProcessType(cls);
}
JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
Block block = message.getBodyBlock(blockContext, factory);
Object wrapperObject = block.getBusinessObject(true);
// The child elements are within the object that
// represents the type
if (wrapperObject instanceof JAXBElement) {
wrapperObject = ((JAXBElement)wrapperObject).getValue();
}
// Get the list of names for the output parameters
List<String> names = new ArrayList<String>();
List<ParameterDescription> pdList = new ArrayList<ParameterDescription>();
for (int i = 0; i < pds.length; i++) {
ParameterDescription pd = pds[i];
if (pd.getMode() == Mode.OUT ||
pd.getMode() == Mode.INOUT) {
names.add(pd.getParameterName());
pdList.add(pd);
}
}
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;
// 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 {
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());
}
// 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 {