body.getName());
operation = serviceDesc.getOperationByElementQName(qname);
}
if (operation == null) {
throw new AxisFault(Messages.getMessage("noSuchOperation",
methodName));
}
// Create the array we'll use to hold the actual parameter
// values. We know how big to make it from the metadata.
Object[] argValues = new Object [operation.getNumParams()];
// A place to keep track of the out params (INOUTs and OUTs)
ArrayList outs = new ArrayList();
// Put the values contained in the RPCParams into an array
// suitable for passing to java.lang.reflect.Method.invoke()
// Make sure we respect parameter ordering if we know about it
// from metadata, and handle whatever conversions are necessary
// (values -> Holders, etc)
for ( int i = 0 ; i < numArgs ; i++ ) {
RPCParam rpcParam = (RPCParam)args.get(i);
Object value = rpcParam.getValue();
// first check the type on the paramter
ParameterDesc paramDesc = rpcParam.getParamDesc();
// if we found some type info try to make sure the value type is
// correct. For instance, if we deserialized a xsd:dateTime in
// to a Calendar and the service takes a Date, we need to convert
if (paramDesc != null && paramDesc.getJavaType() != null) {
// Get the type in the signature (java type or its holder)
Class sigType = paramDesc.getJavaType();
// Convert the value into the expected type in the signature
value = JavaUtils.convert(value,
sigType);
rpcParam.setValue(value);
if (paramDesc.getMode() == ParameterDesc.INOUT) {
outs.add(rpcParam);
}
}
// Put the value (possibly converted) in the argument array
// make sure to use the parameter order if we have it
if (paramDesc == null || paramDesc.getOrder() == -1) {
argValues[i] = value;
} else {
argValues[paramDesc.getOrder()] = value;
}
if (log.isDebugEnabled()) {
log.debug(" " + Messages.getMessage("value00",
"" + argValues[i]) );
}
}
// See if any subclasses want a crack at faulting on a bad operation
// FIXME : Does this make sense here???
String allowedMethods = (String)service.getOption("allowedMethods");
checkMethodName(msgContext, allowedMethods, operation.getName());
// Now create any out holders we need to pass in
if (numArgs < argValues.length) {
ArrayList outParams = operation.getOutParams();
for (int i = 0; i < outParams.size(); i++) {
ParameterDesc param = (ParameterDesc)outParams.get(i);
Class holderClass = param.getJavaType();
if (holderClass != null &&
Holder.class.isAssignableFrom(holderClass)) {
argValues[numArgs + i] = holderClass.newInstance();
// Store an RPCParam in the outs collection so we
// have an easy and consistent way to write these
// back to the client below
RPCParam p = new RPCParam(param.getQName(),
argValues[numArgs + i]);
p.setParamDesc(param);
outs.add(p);
} else {
throw new AxisFault(Messages.getMessage("badOutParameter00",
"" + param.getQName(),
operation.getName()));
}
}
}
// OK! Now we can invoke the method
Object objRes = null;
try {
objRes = invokeMethod(msgContext,
operation.getMethod(),
obj, argValues);
} catch (IllegalArgumentException e) {
String methodSig = operation.getMethod().toString();
String argClasses = "";
for (int i=0; i < argValues.length; i++) {
if (argValues[i] == null) {
argClasses += "null";
} else {
argClasses += argValues[i].getClass().getName();
}
if (i+1 < argValues.length) {
argClasses += ",";
}
}
log.info(Messages.getMessage("dispatchIAE00",
new String[] {methodSig, argClasses}),
e);
throw new AxisFault(Messages.getMessage("dispatchIAE00",
new String[] {methodSig, argClasses}),
e);
}
/* Now put the result in the result SOAPEnvelope */