return null;
}
}
resEnv = resMsg.getSOAPEnvelope();
SOAPBodyElement bodyEl = resEnv.getFirstBody();
if (bodyEl == null) {
return null;
}
if (bodyEl instanceof RPCElement) {
try {
resArgs = ((RPCElement) bodyEl).getParams();
} catch (Exception e) {
log.error(Messages.getMessage("exception00"), e);
throw AxisFault.makeFault(e);
}
if (resArgs != null && resArgs.size() > 0) {
// If there is no return, then we start at index 0 to create the outParams Map.
// If there IS a return, then we start with 1.
int outParamStart = 0;
// If we have resArgs and the returnType is specified, then the first
// resArgs is the return. If we have resArgs and neither returnType
// nor paramXMLTypes are specified, then we assume that the caller is
// following the non-JAX-RPC AXIS shortcut of not having to specify
// the return, in which case we again assume the first resArgs is
// the return.
// NOTE 1: the non-JAX-RPC AXIS shortcut allows a potential error
// to escape notice. If the caller IS NOT following the non-JAX-RPC
// shortcut but instead intentionally leaves returnType and params
// null (ie., a method that takes no parameters and returns nothing)
// then, if we DO receive something it should be an error, but this
// code passes it through. The ideal solution here is to require
// this caller to set the returnType to void, but there's no void
// type in XML.
// NOTE 2: we should probably verify that the resArgs element
// types match the expected returnType and paramXMLTypes, but I'm not
// sure how to do that since the resArgs value is a Java Object
// and the returnType and paramXMLTypes are QNames.
// GD 03/15/02 : We're now checking for invalid metadata
// config at the top of this method, so don't need to do it
// here. Check for void return, though.
boolean findReturnParam = false;
QName returnParamQName = null;
if (operation != null) {
returnParamQName = operation.getReturnQName();
}
if (!XMLType.AXIS_VOID.equals(getReturnType())) {
if (returnParamQName == null) {
// Assume the first param is the return
RPCParam param = (RPCParam)resArgs.get(0);
result = param.getObjectValue();
outParamStart = 1;
} else {
// If the QName of the return value was given to us, look
// through the result arguments to find the right name
findReturnParam = true;
}
}
// The following loop looks at the resargs and
// converts the value to the appropriate return/out parameter
// value. If the return value is found, is value is
// placed in result. The remaining resargs are
// placed in the outParams list (note that if a resArg
// is found that does not match a operation parameter qname,
// it is still placed in the outParms list).
for (int i = outParamStart; i < resArgs.size(); i++) {
RPCParam param = (RPCParam) resArgs.get(i);
Class javaType = getJavaTypeForQName(param.getQName());
Object value = param.getObjectValue();
// Convert type if needed
if (javaType != null && value != null &&
!javaType.isAssignableFrom(value.getClass())) {
value = JavaUtils.convert(value, javaType);
}
// Check if this parameter is our return
// otherwise just add it to our outputs
if (findReturnParam &&
returnParamQName.equals(param.getQName())) {
// found it!
result = value;
findReturnParam = false;
} else {
outParams.put(param.getQName(), value);
outParamsList.add(value);
}
}
// added by scheu:
// If the return param is still not found, that means
// the returned value did not have the expected qname.
// The soap specification indicates that this should be
// accepted (and we also fail interop tests if we are strict here).
// Look through the outParms and find one that
// does not match one of the operation parameters.
if (findReturnParam) {
Iterator it = outParams.keySet().iterator();
while (it.hasNext() && findReturnParam) {
QName qname = (QName) it.next();
ParameterDesc paramDesc =
operation.getOutputParamByQName(qname);
if (paramDesc == null) {
// Doesn't match a paramter, so use this for the return
findReturnParam = false;
result = outParams.remove(qname);
}
}
}
// If we were looking for a particular QName for the return and
// still didn't find it, throw an exception
if (findReturnParam) {
String returnParamName = returnParamQName.toString();
throw new AxisFault(Messages.getMessage("noReturnParam",
returnParamName));
}
}
} else {
// This is a SOAPBodyElement, try to treat it like a return value
try {
result = bodyEl.getValueAsType(getReturnType());
} catch (Exception e) {
// just return the SOAPElement
result = bodyEl;
}