if (style == Style.MESSAGE) {
int messageOperType = checkMessageMethod(method);
if(messageOperType == OperationDesc.MSG_METHOD_NONCONFORMING) continue;
if (messageOperType == -1) {
throw new InternalException("Couldn't match method to any of the allowable message-style patterns!");
}
oper.setMessageOperationStyle(messageOperType);
// Don't bother checking params if we're message style
possibleMatch = method;
break;
}
// Check params
Class [] paramTypes = method.getParameterTypes();
if (paramTypes.length != oper.getNumParams())
continue;
int j;
boolean conversionNecessary = false;
for (j = 0; j < paramTypes.length; j++) {
Class type = paramTypes[j];
Class actualType = type;
if (Holder.class.isAssignableFrom(type)) {
actualType = JavaUtils.getHolderValueType(type);
}
ParameterDesc param = oper.getParameter(j);
QName typeQName = param.getTypeQName();
if (typeQName == null) {
// No typeQName is available. Set it using
// information from the actual type.
// (Scenarios B and D)
// There is no need to try and match with
// the Method parameter javaType because
// the ParameterDesc is being constructed
// by introspecting the Method.
typeQName = getTypeMapping().getTypeQName(actualType);
param.setTypeQName(typeQName);
} else {
// A type qname is available.
// Ensure that the ParameterDesc javaType
// is convertable to the Method parameter type
//
// Use the available javaType (Scenarios C and E)
// or get one from the TMR (Scenario A).
Class paramClass = param.getJavaType();
if (paramClass != null &&
JavaUtils.getHolderValueType(paramClass) != null) {
paramClass = JavaUtils.getHolderValueType(paramClass);
}
if (paramClass == null) {
paramClass = getTypeMapping().getClassForQName(param.getTypeQName(),
type);
}
if (paramClass != null) {
// This is a match if the paramClass is somehow
// convertable to the "real" parameter type. If not,
// break out of this loop.
if (!JavaUtils.isConvertable(paramClass, actualType)) {
break;
}
if (!actualType.isAssignableFrom(paramClass)) {
// This doesn't fit without conversion
conversionNecessary = true;
}
}
}
// In all scenarios the ParameterDesc javaType is set to
// match the javaType in the corresponding parameter.
// This is essential.
param.setJavaType(type);
}
if (j != paramTypes.length) {
// failed.
continue;
}
// This is our latest possibility
possibleMatch = method;
// If this is exactly it, stop now. Otherwise keep looking
// just in case we find a better match.
if (!conversionNecessary) {
break;
}
}
}
// At this point, we may or may not have a possible match.
// FIXME : Should we prefer an exact match from a base class over
// a with-conversion match from the target class? If so,
// we'll need to change the logic below.
if (possibleMatch != null) {
Class returnClass = possibleMatch.getReturnType();
oper.setReturnClass(returnClass);
QName returnType = oper.getReturnType();
if (returnType == null) {
oper.setReturnType(getTypeMapping().getTypeQName(returnClass));
}
// Do the faults
createFaultMetadata(possibleMatch, oper);
oper.setMethod(possibleMatch);
method2OperationMap.put(possibleMatch, oper);
return;
}
// Didn't find a match. Try the superclass, if appropriate
Class superClass = implClass.getSuperclass();
if (superClass != null &&
!superClass.getName().startsWith("java.") &&
!superClass.getName().startsWith("javax.") &&
(stopClasses == null ||
!stopClasses.contains(superClass.getName()))) {
syncOperationToClass(oper, superClass);
}
// Exception if sync fails to find method for operation
if (oper.getMethod() == null) {
InternalException ie =
new InternalException(Messages.getMessage("serviceDescOperSync00",
oper.getName(),
implClass.getName()));
throw ie;
}
}