}
@SuppressWarnings("unchecked")
public static BaseMethodBinding<?> bindMethod(Method theMethod, FhirContext theContext, Object theProvider) {
Read read = theMethod.getAnnotation(Read.class);
Search search = theMethod.getAnnotation(Search.class);
Metadata conformance = theMethod.getAnnotation(Metadata.class);
Create create = theMethod.getAnnotation(Create.class);
Update update = theMethod.getAnnotation(Update.class);
Delete delete = theMethod.getAnnotation(Delete.class);
History history = theMethod.getAnnotation(History.class);
Validate validate = theMethod.getAnnotation(Validate.class);
GetTags getTags = theMethod.getAnnotation(GetTags.class);
AddTags addTags = theMethod.getAnnotation(AddTags.class);
DeleteTags deleteTags = theMethod.getAnnotation(DeleteTags.class);
Transaction transaction = theMethod.getAnnotation(Transaction.class);
// ** if you add another annotation above, also add it to the next line:
if (!verifyMethodHasZeroOrOneOperationAnnotation(theMethod, read, search, conformance, create, update, delete, history, validate, getTags, addTags, deleteTags, transaction)) {
return null;
}
Class<? extends IResource> returnType;
Class<? extends IResource> returnTypeFromRp = null;
if (theProvider instanceof IResourceProvider) {
returnTypeFromRp = ((IResourceProvider) theProvider).getResourceType();
if (!verifyIsValidResourceReturnType(returnTypeFromRp)) {
throw new ConfigurationException("getResourceType() from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returned "
+ toLogString(returnTypeFromRp) + " - Must return a resource type");
}
}
Class<?> returnTypeFromMethod = theMethod.getReturnType();
if (getTags != null) {
if (!TagList.class.equals(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from type " + theMethod.getDeclaringClass().getCanonicalName() + " is annotated with @"
+ GetTags.class.getSimpleName() + " but does not return type " + TagList.class.getName());
}
} else if (MethodOutcome.class.equals(returnTypeFromMethod)) {
// returns a method outcome
} else if (IBundleProvider.class.equals(returnTypeFromMethod)) {
// returns a bundle provider
} else if (Bundle.class.equals(returnTypeFromMethod)) {
// returns a bundle
} else if (void.class.equals(returnTypeFromMethod)) {
// returns a bundle
} else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !IResource.class.equals(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName()
+ " returns a collection with generic type " + toLogString(returnTypeFromMethod)
+ " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List<Patient> )");
}
} else {
if (!IResource.class.equals(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName()
+ " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type (eg Patient, " + Bundle.class.getSimpleName() + ", "
+ IBundleProvider.class.getSimpleName() + ", etc., see the documentation for more details)");
}
}
Class<? extends IResource> returnTypeFromAnnotation = IResource.class;
if (read != null) {
returnTypeFromAnnotation = read.type();
} else if (search != null) {
returnTypeFromAnnotation = search.type();
} else if (history != null) {
returnTypeFromAnnotation = history.type();
} else if (delete != null) {
returnTypeFromAnnotation = delete.type();
} else if (create != null) {
returnTypeFromAnnotation = create.type();
} else if (update != null) {
returnTypeFromAnnotation = update.type();
} else if (validate != null) {
returnTypeFromAnnotation = validate.type();
} else if (getTags != null) {
returnTypeFromAnnotation = getTags.type();
} else if (addTags != null) {
returnTypeFromAnnotation = addTags.type();
} else if (deleteTags != null) {
returnTypeFromAnnotation = deleteTags.type();
}
if (returnTypeFromRp != null) {
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation != IResource.class) {
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type "
+ returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract");
}
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " claims to return type "
+ returnTypeFromAnnotation.getCanonicalName() + " per method annotation - Must return " + returnTypeFromRp.getCanonicalName()
+ " (or a subclass of it) per IResourceProvider contract");
}
returnType = returnTypeFromAnnotation;
} else {
returnType = returnTypeFromRp;
}
} else {
if (returnTypeFromAnnotation != IResource.class) {
if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type "
+ theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation) + " according to annotation - Must return a resource type");
}
returnType = returnTypeFromAnnotation;
} else {
returnType = (Class<? extends IResource>) returnTypeFromMethod;
}
}
if (read != null) {
return new ReadMethodBinding(returnType, theMethod, theContext, theProvider);
} else if (search != null) {
String queryName = search.queryName();
return new SearchMethodBinding(returnType, theMethod, queryName, theContext, theProvider);
} else if (conformance != null) {
return new ConformanceMethodBinding(theMethod, theContext, theProvider);
} else if (create != null) {
return new CreateMethodBinding(theMethod, theContext, theProvider);