Keep working on refactor

This commit is contained in:
James 2017-07-05 08:08:40 -04:00
parent f1d2ee9092
commit c520e60ac1
57 changed files with 843 additions and 1512 deletions

View File

@ -92,34 +92,6 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.rest.param; package ca.uhn.fhir.rest.param;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/* /*
@ -27,14 +29,22 @@ import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.IntegerDt; import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.util.ReflectionUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
public class ParameterUtil { public class ParameterUtil {
private static final Set<Class<?>> BINDABLE_INTEGER_TYPES; private static final Set<Class<?>> BINDABLE_INTEGER_TYPES;
private static final String LABEL = "label=\"";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParameterUtil.class);
private static final String SCHEME = "scheme=\"";
static { static {
HashSet<Class<?>> intTypes = new HashSet<Class<?>>(); HashSet<Class<?>> intTypes = new HashSet<Class<?>>();
@ -44,9 +54,15 @@ public class ParameterUtil {
} }
// public static Integer findSinceParameterIndex(Method theMethod) { @SuppressWarnings("unchecked")
// return findParamIndex(theMethod, Since.class); public static <T extends IIdType> T convertIdToType(IIdType value, Class<T> theIdParamType) {
// } if (value != null && !theIdParamType.isAssignableFrom(value.getClass())) {
IIdType newValue = ReflectionUtil.newInstance(theIdParamType);
newValue.setValue(value.getValue());
value = newValue;
}
return (T) value;
}
/** /**
* Escapes a string according to the rules for parameter escaping specified in the <a href="http://www.hl7.org/implement/standards/fhir/search.html#escaping">FHIR Specification Escaping * Escapes a string according to the rules for parameter escaping specified in the <a href="http://www.hl7.org/implement/standards/fhir/search.html#escaping">FHIR Specification Escaping
@ -116,6 +132,10 @@ public class ParameterUtil {
return index; return index;
} }
// public static Integer findSinceParameterIndex(Method theMethod) {
// return findParamIndex(theMethod, Since.class);
// }
public static Integer findParamAnnotationIndex(Method theMethod, Class<?> toFind) { public static Integer findParamAnnotationIndex(Method theMethod, Class<?> toFind) {
int paramIndex = 0; int paramIndex = 0;
for (Annotation[] annotations : theMethod.getParameterAnnotations()) { for (Annotation[] annotations : theMethod.getParameterAnnotations()) {
@ -170,6 +190,134 @@ public class ParameterUtil {
return -1; return -1;
} }
public static String parseETagValue(String value) {
String eTagVersion;
value = value.trim();
if (value.length() > 1) {
if (value.charAt(value.length() - 1) == '"') {
if (value.charAt(0) == '"') {
eTagVersion = value.substring(1, value.length() - 1);
} else if (value.length() > 3 && value.charAt(0) == 'W' && value.charAt(1) == '/'
&& value.charAt(2) == '"') {
eTagVersion = value.substring(3, value.length() - 1);
} else {
eTagVersion = value;
}
} else {
eTagVersion = value;
}
} else {
eTagVersion = value;
}
return eTagVersion;
}
@Deprecated
public static void parseTagValue(TagList tagList, String nextTagComplete) {
StringBuilder next = new StringBuilder(nextTagComplete);
parseTagValue(tagList, nextTagComplete, next);
}
@Deprecated
private static void parseTagValue(TagList theTagList, String theCompleteHeaderValue, StringBuilder theBuffer) {
int firstSemicolon = theBuffer.indexOf(";");
int deleteTo;
if (firstSemicolon == -1) {
firstSemicolon = theBuffer.indexOf(",");
if (firstSemicolon == -1) {
firstSemicolon = theBuffer.length();
deleteTo = theBuffer.length();
} else {
deleteTo = firstSemicolon;
}
} else {
deleteTo = firstSemicolon + 1;
}
String term = theBuffer.substring(0, firstSemicolon);
String scheme = null;
String label = null;
if (isBlank(term)) {
return;
}
theBuffer.delete(0, deleteTo);
while (theBuffer.length() > 0 && theBuffer.charAt(0) == ' ') {
theBuffer.deleteCharAt(0);
}
while (theBuffer.length() > 0) {
boolean foundSomething = false;
if (theBuffer.length() > SCHEME.length() && theBuffer.substring(0, SCHEME.length()).equals(SCHEME)) {
int closeIdx = theBuffer.indexOf("\"", SCHEME.length());
scheme = theBuffer.substring(SCHEME.length(), closeIdx);
theBuffer.delete(0, closeIdx + 1);
foundSomething = true;
}
if (theBuffer.length() > LABEL.length() && theBuffer.substring(0, LABEL.length()).equals(LABEL)) {
int closeIdx = theBuffer.indexOf("\"", LABEL.length());
label = theBuffer.substring(LABEL.length(), closeIdx);
theBuffer.delete(0, closeIdx + 1);
foundSomething = true;
}
// TODO: support enc2231-string as described in
// http://tools.ietf.org/html/draft-johnston-http-category-header-02
// TODO: support multiple tags in one header as described in
// http://hl7.org/implement/standards/fhir/http.html#tags
while (theBuffer.length() > 0 && (theBuffer.charAt(0) == ' ' || theBuffer.charAt(0) == ';')) {
theBuffer.deleteCharAt(0);
}
if (!foundSomething) {
break;
}
}
if (theBuffer.length() > 0 && theBuffer.charAt(0) == ',') {
theBuffer.deleteCharAt(0);
while (theBuffer.length() > 0 && theBuffer.charAt(0) == ' ') {
theBuffer.deleteCharAt(0);
}
theTagList.add(new Tag(scheme, term, label));
parseTagValue(theTagList, theCompleteHeaderValue, theBuffer);
} else {
theTagList.add(new Tag(scheme, term, label));
}
if (theBuffer.length() > 0) {
ourLog.warn("Ignoring extra text at the end of " + Constants.HEADER_CATEGORY + " tag '"
+ theBuffer.toString() + "' - Complete tag value was: " + theCompleteHeaderValue);
}
}
public static IQueryParameterOr<?> singleton(final IQueryParameterType theParam, final String theParamName) {
return new IQueryParameterOr<IQueryParameterType>() {
private static final long serialVersionUID = 1L;
@Override
public List<IQueryParameterType> getValuesAsQueryTokens() {
return Collections.singletonList(theParam);
}
@Override
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName,
QualifiedParamList theParameters) {
if (theParameters.isEmpty()) {
return;
}
if (theParameters.size() > 1) {
throw new IllegalArgumentException(
"Type " + theParam.getClass().getCanonicalName() + " does not support multiple values");
}
theParam.setValueAsQueryToken(theContext, theParamName, theParameters.getQualifier(),
theParameters.get(0));
}
};
}
static List<String> splitParameterString(String theInput, boolean theUnescapeComponents) { static List<String> splitParameterString(String theInput, boolean theUnescapeComponents) {
return splitParameterString(theInput, ',', theUnescapeComponents); return splitParameterString(theInput, ',', theUnescapeComponents);
} }

View File

@ -17,7 +17,10 @@ import ca.uhn.fhir.rest.annotation.TagListParam;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.server.exceptions.*; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding<Void> { abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding<Void> {
@ -38,9 +41,9 @@ abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding<Void>
myResourceName = theContext.getResourceDefinition(myType).getName(); myResourceName = theContext.getResourceDefinition(myType).getName();
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
myVersionIdParamIndex = MethodUtil.findVersionIdParameterIndex(theMethod); myVersionIdParamIndex = ParameterUtil.findVersionIdParameterIndex(theMethod);
myTagListParamIndex = MethodUtil.findTagListParameterIndex(theMethod); myTagListParamIndex = ParameterUtil.findTagListParameterIndex(theMethod);
if (myIdParamIndex == null) { if (myIdParamIndex == null) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' does not have an @" + IdParam.class.getSimpleName() + " parameter."); throw new ConfigurationException("Method '" + theMethod.getName() + "' does not have an @" + IdParam.class.getSimpleName() + " parameter.");

View File

@ -28,6 +28,7 @@ import java.util.List;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -49,7 +50,7 @@ abstract class BaseJavaPrimitiveBinder<T>implements IParamBinder<T> {
if (isBlank(retVal)) { if (isBlank(retVal)) {
return Collections.emptyList(); return Collections.emptyList();
} }
List<?> retValList = Collections.singletonList(MethodUtil.singleton(new StringParam(retVal), null)); List<?> retValList = Collections.singletonList(ParameterUtil.singleton(new StringParam(retVal), null));
return (List<IQueryParameterOr<?>>) retValList; return (List<IQueryParameterOr<?>>) retValList;
} }

View File

@ -24,9 +24,14 @@ import java.lang.reflect.Method;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.*; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
//TODO Use of a deprecated method should be resolved //TODO Use of a deprecated method should be resolved
import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.VersionIdParam;
import ca.uhn.fhir.rest.param.ParameterUtil;
public abstract class BaseOutcomeReturningMethodBindingWithResourceIdButNoResourceBody extends BaseOutcomeReturningMethodBinding { public abstract class BaseOutcomeReturningMethodBindingWithResourceIdButNoResourceBody extends BaseOutcomeReturningMethodBinding {
@ -45,12 +50,12 @@ public abstract class BaseOutcomeReturningMethodBindingWithResourceIdButNoResour
"Can not determine resource type for method '" + theMethod.getName() + "' on type " + theMethod.getDeclaringClass().getCanonicalName() + " - Did you forget to include the resourceType() value on the @" + Delete.class.getSimpleName() + " method annotation?"); "Can not determine resource type for method '" + theMethod.getName() + "' on type " + theMethod.getDeclaringClass().getCanonicalName() + " - Did you forget to include the resourceType() value on the @" + Delete.class.getSimpleName() + " method annotation?");
} }
myIdParameterIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParameterIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
if (myIdParameterIndex == null) { if (myIdParameterIndex == null) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has no parameter annotated with the @" + IdParam.class.getSimpleName() + " annotation"); throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has no parameter annotated with the @" + IdParam.class.getSimpleName() + " annotation");
} }
Integer versionIdParameterIndex = MethodUtil.findVersionIdParameterIndex(theMethod); Integer versionIdParameterIndex = ParameterUtil.findVersionIdParameterIndex(theMethod);
if (versionIdParameterIndex != null) { if (versionIdParameterIndex != null) {
//TODO Use of a deprecated method should be resolved //TODO Use of a deprecated method should be resolved
throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has a parameter annotated with the @" + VersionIdParam.class.getSimpleName() + " annotation but delete methods may not have this annotation"); throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has a parameter annotated with the @" + VersionIdParam.class.getSimpleName() + " annotation but delete methods may not have this annotation");

View File

@ -19,6 +19,7 @@ import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -38,8 +39,8 @@ public class GetTagsMethodBinding extends BaseMethodBinding<TagList> {
myResourceName = theContext.getResourceDefinition(myType).getName(); myResourceName = theContext.getResourceDefinition(myType).getName();
} }
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
myVersionIdParamIndex = MethodUtil.findVersionIdParameterIndex(theMethod); myVersionIdParamIndex = ParameterUtil.findVersionIdParameterIndex(theMethod);
if (myIdParamIndex != null && myType.equals(IResource.class)) { if (myIdParamIndex != null && myType.equals(IResource.class)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' does not specify a resource type, but has an @" + IdParam.class.getSimpleName() throw new ConfigurationException("Method '" + theMethod.getName() + "' does not specify a resource type, but has an @" + IdParam.class.getSimpleName()

View File

@ -37,6 +37,7 @@ import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
public class HistoryMethodBinding extends BaseResourceReturningMethodBinding { public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
@ -48,7 +49,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
public HistoryMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { public HistoryMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
super(toReturnType(theMethod, theProvider), theMethod, theContext, theProvider); super(toReturnType(theMethod, theProvider), theMethod, theContext, theProvider);
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
History historyAnnotation = theMethod.getAnnotation(History.class); History historyAnnotation = theMethod.getAnnotation(History.class);
Class<? extends IBaseResource> type = historyAnnotation.type(); Class<? extends IBaseResource> type = historyAnnotation.type();

View File

@ -1,6 +1,5 @@
package ca.uhn.fhir.rest.client.method; package ca.uhn.fhir.rest.client.method;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.*; import java.io.*;
@ -49,12 +48,10 @@ import ca.uhn.fhir.util.*;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class MethodUtil { public class MethodUtil {
private static final String LABEL = "label=\"";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MethodUtil.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MethodUtil.class);
private static final Set<String> ourServletRequestTypes = new HashSet<String>(); private static final Set<String> ourServletRequestTypes = new HashSet<String>();
private static final Set<String> ourServletResponseTypes = new HashSet<String>(); private static final Set<String> ourServletResponseTypes = new HashSet<String>();
private static final String SCHEME = "scheme=\"";
static { static {
ourServletRequestTypes.add("javax.servlet.ServletRequest"); ourServletRequestTypes.add("javax.servlet.ServletRequest");
ourServletResponseTypes.add("javax.servlet.ServletResponse"); ourServletResponseTypes.add("javax.servlet.ServletResponse");
@ -80,16 +77,6 @@ public class MethodUtil {
} }
} }
@SuppressWarnings("unchecked")
public static <T extends IIdType> T convertIdToType(IIdType value, Class<T> theIdParamType) {
if (value != null && !theIdParamType.isAssignableFrom(value.getClass())) {
IIdType newValue = ReflectionUtil.newInstance(theIdParamType);
newValue.setValue(value.getValue());
value = newValue;
}
return (T) value;
}
public static HttpGetClientInvocation createConformanceInvocation(FhirContext theContext) { public static HttpGetClientInvocation createConformanceInvocation(FhirContext theContext) {
return new HttpGetClientInvocation(theContext, "metadata"); return new HttpGetClientInvocation(theContext, "metadata");
} }
@ -98,7 +85,8 @@ public class MethodUtil {
return createCreateInvocation(theResource, null, null, theContext); return createCreateInvocation(theResource, null, null, theContext);
} }
public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody, String theId, FhirContext theContext) { public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody,
String theId, FhirContext theContext) {
RuntimeResourceDefinition def = theContext.getResourceDefinition(theResource); RuntimeResourceDefinition def = theContext.getResourceDefinition(theResource);
String resourceName = def.getName(); String resourceName = def.getName();
@ -132,32 +120,38 @@ public class MethodUtil {
return retVal; return retVal;
} }
public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody, String theId, FhirContext theContext, public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody,
Map<String, List<String>> theIfNoneExistParams) { String theId, FhirContext theContext, Map<String, List<String>> theIfNoneExistParams) {
HttpPostClientInvocation retVal = createCreateInvocation(theResource, theResourceBody, theId, theContext); HttpPostClientInvocation retVal = createCreateInvocation(theResource, theResourceBody, theId, theContext);
retVal.setIfNoneExistParams(theIfNoneExistParams); retVal.setIfNoneExistParams(theIfNoneExistParams);
return retVal; return retVal;
} }
public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody, String theId, FhirContext theContext, String theIfNoneExistUrl) { public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody,
String theId, FhirContext theContext, String theIfNoneExistUrl) {
HttpPostClientInvocation retVal = createCreateInvocation(theResource, theResourceBody, theId, theContext); HttpPostClientInvocation retVal = createCreateInvocation(theResource, theResourceBody, theId, theContext);
retVal.setIfNoneExistString(theIfNoneExistUrl); retVal.setIfNoneExistString(theIfNoneExistUrl);
return retVal; return retVal;
} }
public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, IIdType theId, PatchTypeEnum thePatchType, String theBody) { public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, IIdType theId,
PatchTypeEnum thePatchType, String theBody) {
return PatchMethodBinding.createPatchInvocation(theContext, theId, thePatchType, theBody); return PatchMethodBinding.createPatchInvocation(theContext, theId, thePatchType, theBody);
} }
public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, String theUrl, PatchTypeEnum thePatchType, String theBody) { public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, String theUrl,
PatchTypeEnum thePatchType, String theBody) {
return PatchMethodBinding.createPatchInvocation(theContext, theUrl, thePatchType, theBody); return PatchMethodBinding.createPatchInvocation(theContext, theUrl, thePatchType, theBody);
} }
public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, PatchTypeEnum thePatchType, String theBody, String theResourceType, Map<String, List<String>> theMatchParams) { public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, PatchTypeEnum thePatchType,
return PatchMethodBinding.createPatchInvocation(theContext, thePatchType, theBody, theResourceType, theMatchParams); String theBody, String theResourceType, Map<String, List<String>> theMatchParams) {
return PatchMethodBinding.createPatchInvocation(theContext, thePatchType, theBody, theResourceType,
theMatchParams);
} }
public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource, String theResourceBody, Map<String, List<String>> theMatchParams) { public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource,
String theResourceBody, Map<String, List<String>> theMatchParams) {
String resourceType = theContext.getResourceDefinition(theResource).getName(); String resourceType = theContext.getResourceDefinition(theResource).getName();
StringBuilder b = createUrl(resourceType, theMatchParams); StringBuilder b = createUrl(resourceType, theMatchParams);
@ -192,7 +186,8 @@ public class MethodUtil {
return b; return b;
} }
public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource, String theResourceBody, String theMatchUrl) { public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource,
String theResourceBody, String theMatchUrl) {
HttpPutClientInvocation retVal; HttpPutClientInvocation retVal;
if (StringUtils.isBlank(theResourceBody)) { if (StringUtils.isBlank(theResourceBody)) {
retVal = new HttpPutClientInvocation(theContext, theResource, theMatchUrl); retVal = new HttpPutClientInvocation(theContext, theResource, theMatchUrl);
@ -205,7 +200,8 @@ public class MethodUtil {
return retVal; return retVal;
} }
public static HttpPutClientInvocation createUpdateInvocation(IBaseResource theResource, String theResourceBody, IIdType theId, FhirContext theContext) { public static HttpPutClientInvocation createUpdateInvocation(IBaseResource theResource, String theResourceBody,
IIdType theId, FhirContext theContext) {
String resourceName = theContext.getResourceDefinition(theResource).getName(); String resourceName = theContext.getResourceDefinition(theResource).getName();
StringBuilder urlBuilder = new StringBuilder(); StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(resourceName); urlBuilder.append(resourceName);
@ -257,7 +253,8 @@ public class MethodUtil {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<IParameter> getResourceParameters(final FhirContext theContext, Method theMethod, Object theProvider, RestOperationTypeEnum theRestfulOperationTypeEnum) { public static List<IParameter> getResourceParameters(final FhirContext theContext, Method theMethod,
Object theProvider, RestOperationTypeEnum theRestfulOperationTypeEnum) {
List<IParameter> parameters = new ArrayList<IParameter>(); List<IParameter> parameters = new ArrayList<IParameter>();
Class<?>[] parameterTypes = theMethod.getParameterTypes(); Class<?>[] parameterTypes = theMethod.getParameterTypes();
@ -282,7 +279,8 @@ public class MethodUtil {
parameterType = ReflectionUtil.getGenericCollectionTypeOfMethodParameter(theMethod, paramIndex); parameterType = ReflectionUtil.getGenericCollectionTypeOfMethodParameter(theMethod, paramIndex);
} }
if (Collection.class.isAssignableFrom(parameterType)) { if (Collection.class.isAssignableFrom(parameterType)) {
throw new ConfigurationException("Argument #" + paramIndex + " of Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() throw new ConfigurationException("Argument #" + paramIndex + " of Method '" + theMethod.getName()
+ "' in type '" + theMethod.getDeclaringClass().getCanonicalName()
+ "' is of an invalid generic type (can not be a collection of a collection of a collection)"); + "' is of an invalid generic type (can not be a collection of a collection of a collection)");
} }
} }
@ -301,7 +299,8 @@ public class MethodUtil {
parameter.setRequired(true); parameter.setRequired(true);
parameter.setDeclaredTypes(((RequiredParam) nextAnnotation).targetTypes()); parameter.setDeclaredTypes(((RequiredParam) nextAnnotation).targetTypes());
parameter.setCompositeTypes(((RequiredParam) nextAnnotation).compositeTypes()); parameter.setCompositeTypes(((RequiredParam) nextAnnotation).compositeTypes());
parameter.setChainlists(((RequiredParam) nextAnnotation).chainWhitelist(), ((RequiredParam) nextAnnotation).chainBlacklist()); parameter.setChainlists(((RequiredParam) nextAnnotation).chainWhitelist(),
((RequiredParam) nextAnnotation).chainBlacklist());
parameter.setType(theContext, parameterType, innerCollectionType, outerCollectionType); parameter.setType(theContext, parameterType, innerCollectionType, outerCollectionType);
MethodUtil.extractDescription(parameter, annotations); MethodUtil.extractDescription(parameter, annotations);
param = parameter; param = parameter;
@ -311,7 +310,8 @@ public class MethodUtil {
parameter.setRequired(false); parameter.setRequired(false);
parameter.setDeclaredTypes(((OptionalParam) nextAnnotation).targetTypes()); parameter.setDeclaredTypes(((OptionalParam) nextAnnotation).targetTypes());
parameter.setCompositeTypes(((OptionalParam) nextAnnotation).compositeTypes()); parameter.setCompositeTypes(((OptionalParam) nextAnnotation).compositeTypes());
parameter.setChainlists(((OptionalParam) nextAnnotation).chainWhitelist(), ((OptionalParam) nextAnnotation).chainBlacklist()); parameter.setChainlists(((OptionalParam) nextAnnotation).chainWhitelist(),
((OptionalParam) nextAnnotation).chainBlacklist());
parameter.setType(theContext, parameterType, innerCollectionType, outerCollectionType); parameter.setType(theContext, parameterType, innerCollectionType, outerCollectionType);
MethodUtil.extractDescription(parameter, annotations); MethodUtil.extractDescription(parameter, annotations);
param = parameter; param = parameter;
@ -324,15 +324,20 @@ public class MethodUtil {
if (parameterType == String.class) { if (parameterType == String.class) {
instantiableCollectionType = null; instantiableCollectionType = null;
specType = String.class; specType = String.class;
} else if ((parameterType != Include.class) || innerCollectionType == null || outerCollectionType != null) { } else if ((parameterType != Include.class) || innerCollectionType == null
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + IncludeParam.class.getSimpleName() + " but has a type other than Collection<" || outerCollectionType != null) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @"
+ IncludeParam.class.getSimpleName() + " but has a type other than Collection<"
+ Include.class.getSimpleName() + ">"); + Include.class.getSimpleName() + ">");
} else { } else {
instantiableCollectionType = (Class<? extends Collection<Include>>) CollectionBinder.getInstantiableCollectionType(innerCollectionType, "Method '" + theMethod.getName() + "'"); instantiableCollectionType = (Class<? extends Collection<Include>>) CollectionBinder
.getInstantiableCollectionType(innerCollectionType,
"Method '" + theMethod.getName() + "'");
specType = parameterType; specType = parameterType;
} }
param = new IncludeParameter((IncludeParam) nextAnnotation, instantiableCollectionType, specType); param = new IncludeParameter((IncludeParam) nextAnnotation, instantiableCollectionType,
specType);
} else if (nextAnnotation instanceof ResourceParam) { } else if (nextAnnotation instanceof ResourceParam) {
if (IBaseResource.class.isAssignableFrom(parameterType)) { if (IBaseResource.class.isAssignableFrom(parameterType)) {
// good // good
@ -362,10 +367,12 @@ public class MethodUtil {
param = new ElementsParameter(); param = new ElementsParameter();
} else if (nextAnnotation instanceof Since) { } else if (nextAnnotation instanceof Since) {
param = new SinceParameter(); param = new SinceParameter();
((SinceParameter) param).setType(theContext, parameterType, innerCollectionType, outerCollectionType); ((SinceParameter) param).setType(theContext, parameterType, innerCollectionType,
outerCollectionType);
} else if (nextAnnotation instanceof At) { } else if (nextAnnotation instanceof At) {
param = new AtParameter(); param = new AtParameter();
((AtParameter) param).setType(theContext, parameterType, innerCollectionType, outerCollectionType); ((AtParameter) param).setType(theContext, parameterType, innerCollectionType,
outerCollectionType);
} else if (nextAnnotation instanceof Count) { } else if (nextAnnotation instanceof Count) {
param = new CountParameter(); param = new CountParameter();
} else if (nextAnnotation instanceof Sort) { } else if (nextAnnotation instanceof Sort) {
@ -373,20 +380,24 @@ public class MethodUtil {
} else if (nextAnnotation instanceof TransactionParam) { } else if (nextAnnotation instanceof TransactionParam) {
param = new TransactionParameter(theContext); param = new TransactionParameter(theContext);
} else if (nextAnnotation instanceof ConditionalUrlParam) { } else if (nextAnnotation instanceof ConditionalUrlParam) {
param = new ConditionalParamBinder(theRestfulOperationTypeEnum, ((ConditionalUrlParam) nextAnnotation).supportsMultiple()); param = new ConditionalParamBinder(theRestfulOperationTypeEnum,
((ConditionalUrlParam) nextAnnotation).supportsMultiple());
} else if (nextAnnotation instanceof OperationParam) { } else if (nextAnnotation instanceof OperationParam) {
Operation op = theMethod.getAnnotation(Operation.class); Operation op = theMethod.getAnnotation(Operation.class);
param = new OperationParameter(theContext, op.name(), ((OperationParam) nextAnnotation)); param = new OperationParameter(theContext, op.name(), ((OperationParam) nextAnnotation));
} else if (nextAnnotation instanceof Validate.Mode) { } else if (nextAnnotation instanceof Validate.Mode) {
if (parameterType.equals(ValidationModeEnum.class) == false) { if (parameterType.equals(ValidationModeEnum.class) == false) {
throw new ConfigurationException( throw new ConfigurationException("Parameter annotated with @"
"Parameter annotated with @" + Validate.class.getSimpleName() + "." + Validate.Mode.class.getSimpleName() + " must be of type " + ValidationModeEnum.class.getName()); + Validate.class.getSimpleName() + "." + Validate.Mode.class.getSimpleName()
+ " must be of type " + ValidationModeEnum.class.getName());
} }
param = new OperationParameter(theContext, Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_MODE, 0, 1).setConverter(new IOperationParamConverter() { param = new OperationParameter(theContext, Constants.EXTOP_VALIDATE,
Constants.EXTOP_VALIDATE_MODE, 0, 1).setConverter(new IOperationParamConverter() {
@Override @Override
public Object incomingServer(Object theObject) { public Object incomingServer(Object theObject) {
if (isNotBlank(theObject.toString())) { if (isNotBlank(theObject.toString())) {
ValidationModeEnum retVal = ValidationModeEnum.forCode(theObject.toString()); ValidationModeEnum retVal = ValidationModeEnum
.forCode(theObject.toString());
if (retVal == null) { if (retVal == null) {
OperationParameter.throwInvalidMode(theObject.toString()); OperationParameter.throwInvalidMode(theObject.toString());
} }
@ -397,15 +408,18 @@ public class MethodUtil {
@Override @Override
public Object outgoingClient(Object theObject) { public Object outgoingClient(Object theObject) {
return ParametersUtil.createString(theContext, ((ValidationModeEnum) theObject).getCode()); return ParametersUtil.createString(theContext,
((ValidationModeEnum) theObject).getCode());
} }
}); });
} else if (nextAnnotation instanceof Validate.Profile) { } else if (nextAnnotation instanceof Validate.Profile) {
if (parameterType.equals(String.class) == false) { if (parameterType.equals(String.class) == false) {
throw new ConfigurationException( throw new ConfigurationException("Parameter annotated with @"
"Parameter annotated with @" + Validate.class.getSimpleName() + "." + Validate.Profile.class.getSimpleName() + " must be of type " + String.class.getName()); + Validate.class.getSimpleName() + "." + Validate.Profile.class.getSimpleName()
+ " must be of type " + String.class.getName());
} }
param = new OperationParameter(theContext, Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_PROFILE, 0, 1).setConverter(new IOperationParamConverter() { param = new OperationParameter(theContext, Constants.EXTOP_VALIDATE,
Constants.EXTOP_VALIDATE_PROFILE, 0, 1).setConverter(new IOperationParamConverter() {
@Override @Override
public Object incomingServer(Object theObject) { public Object incomingServer(Object theObject) {
return theObject.toString(); return theObject.toString();
@ -425,8 +439,9 @@ public class MethodUtil {
} }
if (param == null) { if (param == null) {
throw new ConfigurationException( throw new ConfigurationException("Parameter #" + ((paramIndex + 1)) + "/" + (parameterTypes.length)
"Parameter #" + ((paramIndex + 1)) + "/" + (parameterTypes.length) + " of method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + " of method '" + theMethod.getName() + "' on type '"
+ theMethod.getDeclaringClass().getCanonicalName()
+ "' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter"); + "' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter");
} }
@ -438,7 +453,8 @@ public class MethodUtil {
return parameters; return parameters;
} }
public static void parseClientRequestResourceHeaders(IIdType theRequestedId, Map<String, List<String>> theHeaders, IBaseResource resource) { public static void parseClientRequestResourceHeaders(IIdType theRequestedId, Map<String, List<String>> theHeaders,
IBaseResource resource) {
List<String> lmHeaders = theHeaders.get(Constants.HEADER_LAST_MODIFIED_LOWERCASE); List<String> lmHeaders = theHeaders.get(Constants.HEADER_LAST_MODIFIED_LOWERCASE);
if (lmHeaders != null && lmHeaders.size() > 0 && StringUtils.isNotBlank(lmHeaders.get(0))) { if (lmHeaders != null && lmHeaders.size() > 0 && StringUtils.isNotBlank(lmHeaders.get(0))) {
String headerValue = lmHeaders.get(0); String headerValue = lmHeaders.get(0);
@ -484,7 +500,7 @@ public class MethodUtil {
List<String> eTagHeaders = theHeaders.get(Constants.HEADER_ETAG_LC); List<String> eTagHeaders = theHeaders.get(Constants.HEADER_ETAG_LC);
String eTagVersion = null; String eTagVersion = null;
if (eTagHeaders != null && eTagHeaders.size() > 0) { if (eTagHeaders != null && eTagHeaders.size() > 0) {
eTagVersion = parseETagValue(eTagHeaders.get(0)); eTagVersion = ParameterUtil.parseETagValue(eTagHeaders.get(0));
} }
if (isNotBlank(eTagVersion)) { if (isNotBlank(eTagVersion)) {
if (existing == null || existing.isEmpty()) { if (existing == null || existing.isEmpty()) {
@ -504,7 +520,7 @@ public class MethodUtil {
if (categoryHeaders != null && categoryHeaders.size() > 0 && StringUtils.isNotBlank(categoryHeaders.get(0))) { if (categoryHeaders != null && categoryHeaders.size() > 0 && StringUtils.isNotBlank(categoryHeaders.get(0))) {
TagList tagList = new TagList(); TagList tagList = new TagList();
for (String header : categoryHeaders) { for (String header : categoryHeaders) {
parseTagValue(tagList, header); ParameterUtil.parseTagValue(tagList, header);
} }
if (resource instanceof IResource) { if (resource instanceof IResource) {
ResourceMetadataKeyEnum.TAG_LIST.put((IResource) resource, tagList); ResourceMetadataKeyEnum.TAG_LIST.put((IResource) resource, tagList);
@ -517,31 +533,11 @@ public class MethodUtil {
} }
} }
public static String parseETagValue(String value) {
String eTagVersion;
value = value.trim();
if (value.length() > 1) {
if (value.charAt(value.length() - 1) == '"') {
if (value.charAt(0) == '"') {
eTagVersion = value.substring(1, value.length() - 1);
} else if (value.length() > 3 && value.charAt(0) == 'W' && value.charAt(1) == '/' && value.charAt(2) == '"') {
eTagVersion = value.substring(3, value.length() - 1);
} else {
eTagVersion = value;
}
} else {
eTagVersion = value;
}
} else {
eTagVersion = value;
}
return eTagVersion;
}
/** /**
* This is a utility method intended provided to help the JPA module. * This is a utility method intended provided to help the JPA module.
*/ */
public static IQueryParameterAnd<?> parseQueryParams(FhirContext theContext, RuntimeSearchParam theParamDef, String theUnqualifiedParamName, List<QualifiedParamList> theParameters) { public static IQueryParameterAnd<?> parseQueryParams(FhirContext theContext, RuntimeSearchParam theParamDef,
String theUnqualifiedParamName, List<QualifiedParamList> theParameters) {
RestSearchParameterTypeEnum paramType = theParamDef.getParamType(); RestSearchParameterTypeEnum paramType = theParamDef.getParamType();
return parseQueryParams(theContext, paramType, theUnqualifiedParamName, theParameters); return parseQueryParams(theContext, paramType, theUnqualifiedParamName, theParameters);
} }
@ -549,34 +545,43 @@ public class MethodUtil {
/** /**
* This is a utility method intended provided to help the JPA module. * This is a utility method intended provided to help the JPA module.
*/ */
public static IQueryParameterAnd<?> parseQueryParams(FhirContext theContext, RestSearchParameterTypeEnum paramType, String theUnqualifiedParamName, List<QualifiedParamList> theParameters) { public static IQueryParameterAnd<?> parseQueryParams(FhirContext theContext, RestSearchParameterTypeEnum paramType,
String theUnqualifiedParamName, List<QualifiedParamList> theParameters) {
QueryParameterAndBinder binder = null; QueryParameterAndBinder binder = null;
switch (paramType) { switch (paramType) {
case COMPOSITE: case COMPOSITE:
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
case DATE: case DATE:
binder = new QueryParameterAndBinder(DateAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(DateAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
case NUMBER: case NUMBER:
binder = new QueryParameterAndBinder(NumberAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(NumberAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
case QUANTITY: case QUANTITY:
binder = new QueryParameterAndBinder(QuantityAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(QuantityAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
case REFERENCE: case REFERENCE:
binder = new QueryParameterAndBinder(ReferenceAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(ReferenceAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
case STRING: case STRING:
binder = new QueryParameterAndBinder(StringAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(StringAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
case TOKEN: case TOKEN:
binder = new QueryParameterAndBinder(TokenAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(TokenAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
case URI: case URI:
binder = new QueryParameterAndBinder(UriAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(UriAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
case HAS: case HAS:
binder = new QueryParameterAndBinder(HasAndListParam.class, Collections.<Class<? extends IQueryParameterType>> emptyList()); binder = new QueryParameterAndBinder(HasAndListParam.class,
Collections.<Class<? extends IQueryParameterType>> emptyList());
break; break;
} }
@ -584,84 +589,8 @@ public class MethodUtil {
return binder.parse(theContext, theUnqualifiedParamName, theParameters); return binder.parse(theContext, theUnqualifiedParamName, theParameters);
} }
public static void parseTagValue(TagList tagList, String nextTagComplete) { public static MethodOutcome process2xxResponse(FhirContext theContext, int theResponseStatusCode,
StringBuilder next = new StringBuilder(nextTagComplete); String theResponseMimeType, Reader theResponseReader, Map<String, List<String>> theHeaders) {
parseTagValue(tagList, nextTagComplete, next);
}
private static void parseTagValue(TagList theTagList, String theCompleteHeaderValue, StringBuilder theBuffer) {
int firstSemicolon = theBuffer.indexOf(";");
int deleteTo;
if (firstSemicolon == -1) {
firstSemicolon = theBuffer.indexOf(",");
if (firstSemicolon == -1) {
firstSemicolon = theBuffer.length();
deleteTo = theBuffer.length();
} else {
deleteTo = firstSemicolon;
}
} else {
deleteTo = firstSemicolon + 1;
}
String term = theBuffer.substring(0, firstSemicolon);
String scheme = null;
String label = null;
if (isBlank(term)) {
return;
}
theBuffer.delete(0, deleteTo);
while (theBuffer.length() > 0 && theBuffer.charAt(0) == ' ') {
theBuffer.deleteCharAt(0);
}
while (theBuffer.length() > 0) {
boolean foundSomething = false;
if (theBuffer.length() > SCHEME.length() && theBuffer.substring(0, SCHEME.length()).equals(SCHEME)) {
int closeIdx = theBuffer.indexOf("\"", SCHEME.length());
scheme = theBuffer.substring(SCHEME.length(), closeIdx);
theBuffer.delete(0, closeIdx + 1);
foundSomething = true;
}
if (theBuffer.length() > LABEL.length() && theBuffer.substring(0, LABEL.length()).equals(LABEL)) {
int closeIdx = theBuffer.indexOf("\"", LABEL.length());
label = theBuffer.substring(LABEL.length(), closeIdx);
theBuffer.delete(0, closeIdx + 1);
foundSomething = true;
}
// TODO: support enc2231-string as described in
// http://tools.ietf.org/html/draft-johnston-http-category-header-02
// TODO: support multiple tags in one header as described in
// http://hl7.org/implement/standards/fhir/http.html#tags
while (theBuffer.length() > 0 && (theBuffer.charAt(0) == ' ' || theBuffer.charAt(0) == ';')) {
theBuffer.deleteCharAt(0);
}
if (!foundSomething) {
break;
}
}
if (theBuffer.length() > 0 && theBuffer.charAt(0) == ',') {
theBuffer.deleteCharAt(0);
while (theBuffer.length() > 0 && theBuffer.charAt(0) == ' ') {
theBuffer.deleteCharAt(0);
}
theTagList.add(new Tag(scheme, term, label));
parseTagValue(theTagList, theCompleteHeaderValue, theBuffer);
} else {
theTagList.add(new Tag(scheme, term, label));
}
if (theBuffer.length() > 0) {
ourLog.warn("Ignoring extra text at the end of " + Constants.HEADER_CATEGORY + " tag '" + theBuffer.toString() + "' - Complete tag value was: " + theCompleteHeaderValue);
}
}
public static MethodOutcome process2xxResponse(FhirContext theContext, int theResponseStatusCode, String theResponseMimeType, Reader theResponseReader, Map<String, List<String>> theHeaders) {
List<String> locationHeaders = new ArrayList<String>(); List<String> locationHeaders = new ArrayList<String>();
List<String> lh = theHeaders.get(Constants.HEADER_LOCATION_LC); List<String> lh = theHeaders.get(Constants.HEADER_LOCATION_LC);
if (lh != null) { if (lh != null) {
@ -706,34 +635,16 @@ public class MethodUtil {
} }
} else { } else {
BaseOutcomeReturningMethodBinding.ourLog.debug("Ignoring response content of type: {}", theResponseMimeType); BaseOutcomeReturningMethodBinding.ourLog.debug("Ignoring response content of type: {}",
theResponseMimeType);
} }
} }
return retVal; return retVal;
} }
public static IQueryParameterOr<?> singleton(final IQueryParameterType theParam, final String theParamName) {
return new IQueryParameterOr<IQueryParameterType>() {
@Override public static void addAcceptHeaderToRequest(EncodingEnum theEncoding, IHttpRequest theHttpRequest,
public List<IQueryParameterType> getValuesAsQueryTokens() { FhirContext theContext) {
return Collections.singletonList(theParam);
}
@Override
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters) {
if (theParameters.isEmpty()) {
return;
}
if (theParameters.size() > 1) {
throw new IllegalArgumentException("Type " + theParam.getClass().getCanonicalName() + " does not support multiple values");
}
theParam.setValueAsQueryToken(theContext, theParamName, theParameters.getQualifier(), theParameters.get(0));
}
};
}
public static void addAcceptHeaderToRequest(EncodingEnum theEncoding, IHttpRequest theHttpRequest, FhirContext theContext) {
if (theEncoding == null) { if (theEncoding == null) {
if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2_1) == false) { if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2_1) == false) {
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY); theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY);

View File

@ -50,6 +50,7 @@ import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.FhirTerser;
@ -75,7 +76,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
myBundleType = theBundleType; myBundleType = theBundleType;
myIdempotent = theIdempotent; myIdempotent = theIdempotent;
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
if (myIdParamIndex != null) { if (myIdParamIndex != null) {
for (Annotation next : theMethod.getParameterAnnotations()[myIdParamIndex]) { for (Annotation next : theMethod.getParameterAnnotations()[myIdParamIndex]) {
if (next instanceof IdParam) { if (next instanceof IdParam) {

View File

@ -29,6 +29,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -42,7 +43,7 @@ final class QueryParameterTypeBinder extends BaseBinder<IQueryParameterType> imp
@Override @Override
public List<IQueryParameterOr<?>> encode(FhirContext theContext, IQueryParameterType theValue) throws InternalErrorException { public List<IQueryParameterOr<?>> encode(FhirContext theContext, IQueryParameterType theValue) throws InternalErrorException {
IQueryParameterType param = theValue; IQueryParameterType param = theValue;
List<?> retVal = Collections.singletonList(MethodUtil.singleton(param, null)); List<?> retVal = Collections.singletonList(ParameterUtil.singleton(param, null));
return (List<IQueryParameterOr<?>>) retVal; return (List<IQueryParameterOr<?>>) retVal;
} }

View File

@ -23,11 +23,16 @@ package ca.uhn.fhir.rest.client.method;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
@ -35,8 +40,11 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.annotation.Elements;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
public class ReadMethodBinding extends BaseResourceReturningMethodBinding implements IClientResponseHandlerHandlesBinary<Object> { public class ReadMethodBinding extends BaseResourceReturningMethodBinding implements IClientResponseHandlerHandlesBinary<Object> {
@ -51,8 +59,8 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
Validate.notNull(theMethod, "Method must not be null"); Validate.notNull(theMethod, "Method must not be null");
Integer idIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); Integer idIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
Integer versionIdIndex = MethodUtil.findVersionIdParameterIndex(theMethod); Integer versionIdIndex = ParameterUtil.findVersionIdParameterIndex(theMethod);
Class<?>[] parameterTypes = theMethod.getParameterTypes(); Class<?>[] parameterTypes = theMethod.getParameterTypes();

View File

@ -23,7 +23,10 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -35,8 +38,11 @@ import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.SearchStyleEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -51,7 +57,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
Search search = theMethod.getAnnotation(Search.class); Search search = theMethod.getAnnotation(Search.class);
this.myQueryName = StringUtils.defaultIfBlank(search.queryName(), null); this.myQueryName = StringUtils.defaultIfBlank(search.queryName(), null);
this.myCompartmentName = StringUtils.defaultIfBlank(search.compartmentName(), null); this.myCompartmentName = StringUtils.defaultIfBlank(search.compartmentName(), null);
this.myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); this.myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
Description desc = theMethod.getAnnotation(Description.class); Description desc = theMethod.getAnnotation(Description.class);
if (desc != null) { if (desc != null) {

View File

@ -16,6 +16,7 @@ import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam { public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam {
@ -25,7 +26,7 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
public UpdateMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { public UpdateMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
super(theMethod, theContext, Update.class, theProvider); super(theMethod, theContext, Update.class, theProvider);
myIdParameterIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParameterIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
} }

View File

@ -30,8 +30,11 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Validate; import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ParameterUtil;
public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindingWithResourceParam { public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindingWithResourceParam {
@ -40,7 +43,7 @@ public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindin
public ValidateMethodBindingDstu1(Method theMethod, FhirContext theContext, Object theProvider) { public ValidateMethodBindingDstu1(Method theMethod, FhirContext theContext, Object theProvider) {
super(theMethod, theContext, Validate.class, theProvider); super(theMethod, theContext, Validate.class, theProvider);
myIdParameterIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParameterIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
} }
@Override @Override

View File

@ -27,6 +27,39 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!--
Spring is added as an optional dependency just so that it
can be used for CORS
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -3,7 +3,6 @@ package ca.uhn.fhir.rest.api.server;
import ca.uhn.fhir.context.api.BundleInclusionRule; import ca.uhn.fhir.context.api.BundleInclusionRule;
import ca.uhn.fhir.rest.server.IPagingProvider; import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.IRestfulServerDefaults; import ca.uhn.fhir.rest.server.IRestfulServerDefaults;
import ca.uhn.fhir.rest.server.method.RequestDetails;
/* /*
* #%L * #%L
@ -26,6 +25,7 @@ import ca.uhn.fhir.rest.server.method.RequestDetails;
*/ */
public interface IRestfulServer<T extends RequestDetails> extends IRestfulServerDefaults { public interface IRestfulServer<T extends RequestDetails> extends IRestfulServerDefaults {
@Override
IPagingProvider getPagingProvider(); IPagingProvider getPagingProvider();
BundleInclusionRule getBundleInclusionRule(); BundleInclusionRule getBundleInclusionRule();

View File

@ -2,9 +2,11 @@ package ca.uhn.fhir.rest.api.server;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.*; import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -24,18 +26,101 @@ import java.nio.charset.Charset;
* limitations under the License. * limitations under the License.
* #L% * #L%
*/ */
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.server.IRestfulServerDefaults; import ca.uhn.fhir.rest.server.IRestfulServerDefaults;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.IServerOperationInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerOperationInterceptor;
public abstract class RequestDetails implements IRequestDetails { public abstract class RequestDetails {
private class RequestOperationCallback implements IRequestOperationCallback {
private List<IServerInterceptor> getInterceptors() {
if (getServer() == null) {
return Collections.emptyList();
}
return getServer().getInterceptors();
}
@Override
public void resourceCreated(IBaseResource theResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceCreated(RequestDetails.this, theResource);
}
}
}
@Override
public void resourceDeleted(IBaseResource theResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceDeleted(RequestDetails.this, theResource);
}
}
}
@Override
public void resourcesCreated(Collection<? extends IBaseResource> theResource) {
for (IBaseResource next : theResource) {
resourceCreated(next);
}
}
@Override
public void resourcesDeleted(Collection<? extends IBaseResource> theResource) {
for (IBaseResource next : theResource) {
resourceDeleted(next);
}
}
/**
* @deprecated Deprecated in HAPI FHIR 2.6 - Use {@link IRequestOperationCallback#resourceUpdated(IBaseResource, IBaseResource)} instead
*/
@Deprecated
public void resourcesUpdated(Collection<? extends IBaseResource> theResource) {
for (IBaseResource next : theResource) {
resourceUpdated(next);
}
}
/**
* @deprecated Deprecated in HAPI FHIR 2.6 - Use {@link IRequestOperationCallback#resourceUpdated(IBaseResource, IBaseResource)} instead
*/
@Deprecated
@Override
public void resourceUpdated(IBaseResource theResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceUpdated(RequestDetails.this, theResource);
}
}
}
@Override
public void resourceUpdated(IBaseResource theOldResource, IBaseResource theNewResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceUpdated(RequestDetails.this, theOldResource, theNewResource);
}
}
}
}
private String myCompartmentName; private String myCompartmentName;
private String myCompleteUrl; private String myCompleteUrl;
private String myFhirServerBase; private String myFhirServerBase;
@ -54,6 +139,7 @@ public abstract class RequestDetails implements IRequestDetails {
private boolean mySubRequest; private boolean mySubRequest;
private Map<String, List<String>> myUnqualifiedToQualifiedNames; private Map<String, List<String>> myUnqualifiedToQualifiedNames;
private Map<Object, Object> myUserData; private Map<Object, Object> myUserData;
protected abstract byte[] getByteStreamRequestContents(); protected abstract byte[] getByteStreamRequestContents();
/** /**
@ -64,10 +150,10 @@ public abstract class RequestDetails implements IRequestDetails {
public String getCompartmentName() { public String getCompartmentName() {
return myCompartmentName; return myCompartmentName;
} }
public String getCompleteUrl() { public String getCompleteUrl() {
return myCompleteUrl; return myCompleteUrl;
} }
/** /**
* Returns the <b>conditional URL</b> if this request has one, or <code>null</code> otherwise. For an * Returns the <b>conditional URL</b> if this request has one, or <code>null</code> otherwise. For an
* update or delete method, this is the part of the URL after the <code>?</code>. For a create, this * update or delete method, this is the part of the URL after the <code>?</code>. For a create, this
@ -102,6 +188,11 @@ public abstract class RequestDetails implements IRequestDetails {
return this.getResourceName() + this.getCompleteUrl().substring(questionMarkIndex); return this.getResourceName() + this.getCompleteUrl().substring(questionMarkIndex);
} }
/**
* Returns the HAPI FHIR Context associated with this request
*/
public abstract FhirContext getFhirContext();
/** /**
* The fhir server base url, independant of the query being executed * The fhir server base url, independant of the query being executed
* *
@ -347,80 +438,4 @@ public abstract class RequestDetails implements IRequestDetails {
mySubRequest = theSubRequest; mySubRequest = theSubRequest;
} }
private class RequestOperationCallback implements IRequestOperationCallback {
private List<IServerInterceptor> getInterceptors() {
if (getServer() == null) {
return Collections.emptyList();
}
return getServer().getInterceptors();
}
@Override
public void resourceCreated(IBaseResource theResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceCreated(RequestDetails.this, theResource);
}
}
}
@Override
public void resourceDeleted(IBaseResource theResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceDeleted(RequestDetails.this, theResource);
}
}
}
@Override
public void resourcesCreated(Collection<? extends IBaseResource> theResource) {
for (IBaseResource next : theResource) {
resourceCreated(next);
}
}
@Override
public void resourcesDeleted(Collection<? extends IBaseResource> theResource) {
for (IBaseResource next : theResource) {
resourceDeleted(next);
}
}
/**
* @deprecated Deprecated in HAPI FHIR 2.6 - Use {@link IRequestOperationCallback#resourceUpdated(IBaseResource, IBaseResource)} instead
*/
@Deprecated
public void resourcesUpdated(Collection<? extends IBaseResource> theResource) {
for (IBaseResource next : theResource) {
resourceUpdated(next);
}
}
/**
* @deprecated Deprecated in HAPI FHIR 2.6 - Use {@link IRequestOperationCallback#resourceUpdated(IBaseResource, IBaseResource)} instead
*/
@Deprecated
@Override
public void resourceUpdated(IBaseResource theResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceUpdated(RequestDetails.this, theResource);
}
}
}
@Override
public void resourceUpdated(IBaseResource theOldResource, IBaseResource theNewResource) {
for (IServerInterceptor next : getInterceptors()) {
if (next instanceof IServerOperationInterceptor) {
((IServerOperationInterceptor) next).resourceUpdated(RequestDetails.this, theOldResource, theNewResource);
}
}
}
}
} }

View File

@ -22,24 +22,47 @@ package ca.uhn.fhir.rest.server;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.*; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.*; import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.PreferReturnEnum;
import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.api.server.IRestfulResponse; import ca.uhn.fhir.rest.api.server.IRestfulResponse;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;

View File

@ -46,13 +46,32 @@ import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.annotation.AddTags;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.DeleteTags;
import ca.uhn.fhir.rest.annotation.GetPage;
import ca.uhn.fhir.rest.annotation.GetTags;
import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.Patch;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.server.BundleProviders;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
import ca.uhn.fhir.rest.server.*; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -67,7 +86,7 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetai
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.ReflectionUtil; import ca.uhn.fhir.util.ReflectionUtil;
public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>, IServerMethodBinding { public abstract class BaseMethodBinding<T> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseMethodBinding.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseMethodBinding.class);
private FhirContext myContext; private FhirContext myContext;
@ -232,8 +251,6 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>,
public abstract boolean incomingServerRequestMatchesMethod(RequestDetails theRequest); public abstract boolean incomingServerRequestMatchesMethod(RequestDetails theRequest);
public abstract BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException;
public abstract Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException; public abstract Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException;
protected final Object invokeServerMethod(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) { protected final Object invokeServerMethod(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) {

View File

@ -21,13 +21,10 @@ package ca.uhn.fhir.rest.server.method;
*/ */
import java.io.IOException; import java.io.IOException;
import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -39,12 +36,19 @@ import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.*; import ca.uhn.fhir.rest.api.PreferReturnEnum;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.api.server.IRestfulResponse;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
@ -77,8 +81,6 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
return false; return false;
} }
protected abstract BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource resource);
/** /**
* For servers, this method will match only incoming requests that match the given operation, or which have no * For servers, this method will match only incoming requests that match the given operation, or which have no
* operation in the URL if this method returns null. * operation in the URL if this method returns null.
@ -148,18 +150,6 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
return true; return true;
} }
@Override
public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
if (theResponseStatusCode >= 200 && theResponseStatusCode < 300) {
if (myReturnVoid) {
return null;
}
MethodOutcome retVal = MethodUtil.process2xxResponse(getContext(), theResponseStatusCode, theResponseMimeType, theResponseReader, theHeaders);
return retVal;
}
throw processNon2xxResponseAndReturnExceptionToThrow(theResponseStatusCode, theResponseMimeType, theResponseReader);
}
@Override @Override
public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException {

View File

@ -24,13 +24,10 @@ import java.lang.reflect.Method;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.IdParam;
//TODO Use of a deprecated method should be resolved //TODO Use of a deprecated method should be resolved
import ca.uhn.fhir.rest.annotation.VersionIdParam; import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
public abstract class BaseOutcomeReturningMethodBindingWithResourceIdButNoResourceBody extends BaseOutcomeReturningMethodBinding { public abstract class BaseOutcomeReturningMethodBindingWithResourceIdButNoResourceBody extends BaseOutcomeReturningMethodBinding {
@ -55,12 +52,12 @@ public abstract class BaseOutcomeReturningMethodBindingWithResourceIdButNoResour
} }
} }
myIdParameterIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParameterIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
if (myIdParameterIndex == null) { if (myIdParameterIndex == null) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has no parameter annotated with the @" + IdParam.class.getSimpleName() + " annotation"); throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has no parameter annotated with the @" + IdParam.class.getSimpleName() + " annotation");
} }
Integer versionIdParameterIndex = MethodUtil.findVersionIdParameterIndex(theMethod); Integer versionIdParameterIndex = ParameterUtil.findVersionIdParameterIndex(theMethod);
if (versionIdParameterIndex != null) { if (versionIdParameterIndex != null) {
//TODO Use of a deprecated method should be resolved //TODO Use of a deprecated method should be resolved
throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has a parameter annotated with the @" + VersionIdParam.class.getSimpleName() + " annotation but delete methods may not have this annotation"); throw new ConfigurationException("Method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName() + "' has a parameter annotated with the @" + VersionIdParam.class.getSimpleName() + " annotation but delete methods may not have this annotation");

View File

@ -31,13 +31,10 @@ import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.annotation.ResourceParam; import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOutcomeReturningMethodBinding { abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOutcomeReturningMethodBinding {
@ -82,7 +79,7 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
} }
myResourceName = theContext.getResourceDefinition(myResourceType).getName(); myResourceName = theContext.getResourceDefinition(myResourceType).getName();
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
if (myIdParamIndex != null) { if (myIdParamIndex != null) {
myIdParamType = (Class<? extends IIdType>) theMethod.getParameterTypes()[myIdParamIndex]; myIdParamType = (Class<? extends IIdType>) theMethod.getParameterTypes()[myIdParamIndex];
} }
@ -96,7 +93,7 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
@Override @Override
protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) { protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) {
if (myIdParamIndex != null) { if (myIdParamIndex != null) {
theParams[myIdParamIndex] = MethodUtil.convertIdToType(theRequest.getId(), myIdParamType); theParams[myIdParamIndex] = ParameterUtil.convertIdToType(theRequest.getId(), myIdParamType);
} }
if (myResourceParameterIndex != -1) { if (myResourceParameterIndex != -1) {
IBaseResource resource = ((IBaseResource) theParams[myResourceParameterIndex]); IBaseResource resource = ((IBaseResource) theParams[myResourceParameterIndex]);
@ -124,17 +121,6 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
return myResourceName; return myResourceName;
} }
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
IResource resource = (IResource) theArgs[myResourceParameterIndex]; // TODO: use IBaseResource
if (resource == null) {
throw new NullPointerException("Resource can not be null");
}
BaseHttpClientInvocation retVal = createClientInvocation(theArgs, resource);
return retVal;
}
@Override @Override
protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) { protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) {
super.populateActionRequestDetailsForInterceptor(theRequestDetails, theDetails, theMethodParams); super.populateActionRequestDetailsForInterceptor(theRequestDetails, theDetails, theMethodParams);

View File

@ -1,7 +1,5 @@
package ca.uhn.fhir.rest.server.method; package ca.uhn.fhir.rest.server.method;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -23,15 +21,17 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/ */
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import org.hl7.fhir.instance.model.api.IBaseResource; import java.util.List;
import java.util.Set;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.server.IRequestDetails; import ca.uhn.fhir.rest.api.server.IRequestDetails;
import ca.uhn.fhir.rest.api.server.IServerMethodBinding; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.QualifierDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -74,7 +74,7 @@ public abstract class BaseQueryParameter implements IParameter {
public abstract Object parse(FhirContext theContext, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException; public abstract Object parse(FhirContext theContext, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException;
private void parseParams(IRequestDetails theRequest, List<QualifiedParamList> paramList, String theQualifiedParamName, String theQualifier) { private void parseParams(RequestDetails theRequest, List<QualifiedParamList> paramList, String theQualifiedParamName, String theQualifier) {
QualifierDetails qualifiers = QualifierDetails.extractQualifiersFromParameterName(theQualifier); QualifierDetails qualifiers = QualifierDetails.extractQualifiersFromParameterName(theQualifier);
if (!qualifiers.passes(getQualifierWhitelist(), getQualifierBlacklist())) { if (!qualifiers.passes(getQualifierWhitelist(), getQualifierBlacklist())) {
return; return;
@ -92,40 +92,9 @@ public abstract class BaseQueryParameter implements IParameter {
} }
} }
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
if (theSourceClientArgument == null) {
if (isRequired()) {
throw new NullPointerException("SearchParameter '" + getName() + "' is required and may not be null");
}
} else {
List<QualifiedParamList> value = encode(theContext, theSourceClientArgument);
for (QualifiedParamList nextParamEntry : value) {
StringBuilder b = new StringBuilder();
for (String str : nextParamEntry) {
if (b.length() > 0) {
b.append(",");
}
b.append(str);
}
String qualifier = nextParamEntry.getQualifier();
String paramName = isNotBlank(qualifier) ? getName() + qualifier : getName();
List<String> paramValues = theTargetQueryArguments.get(paramName);
if (paramValues == null) {
paramValues = new ArrayList<String>(value.size());
theTargetQueryArguments.put(paramName, paramValues);
}
paramValues.add(b.toString());
}
}
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(IRequestDetails theRequest, IServerMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
List<QualifiedParamList> paramList = new ArrayList<QualifiedParamList>(); List<QualifiedParamList> paramList = new ArrayList<QualifiedParamList>();
String name = getName(); String name = getName();

View File

@ -22,37 +22,24 @@ package ca.uhn.fhir.rest.server.method;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException; import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.server.*;
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException; import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.*;
import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding; import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor; import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.ReflectionUtil; import ca.uhn.fhir.util.ReflectionUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
@ -76,10 +63,8 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
} }
private MethodReturnTypeEnum myMethodReturnType; private MethodReturnTypeEnum myMethodReturnType;
private Class<?> myResourceListCollectionType;
private String myResourceName; private String myResourceName;
private Class<? extends IBaseResource> myResourceType; private Class<? extends IBaseResource> myResourceType;
private List<Class<? extends IBaseResource>> myPreferTypesList;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public BaseResourceReturningMethodBinding(Class<?> theReturnResourceType, Method theMethod, FhirContext theContext, Object theProvider) { public BaseResourceReturningMethodBinding(Class<?> theReturnResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
@ -96,7 +81,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
"Method " + theMethod.getDeclaringClass().getSimpleName() + "#" + theMethod.getName() + " returns an invalid collection generic type: " + collectionType); "Method " + theMethod.getDeclaringClass().getSimpleName() + "#" + theMethod.getName() + " returns an invalid collection generic type: " + collectionType);
} }
} }
myResourceListCollectionType = collectionType;
} else if (IBaseResource.class.isAssignableFrom(methodReturnType)) { } else if (IBaseResource.class.isAssignableFrom(methodReturnType)) {
if (Modifier.isAbstract(methodReturnType.getModifiers()) == false && theContext.getResourceDefinition((Class<? extends IBaseResource>) methodReturnType).isBundle()) { if (Modifier.isAbstract(methodReturnType.getModifiers()) == false && theContext.getResourceDefinition((Class<? extends IBaseResource>) methodReturnType).isBundle()) {
@ -126,7 +110,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
} }
} }
myPreferTypesList = createPreferTypesList();
} }
public MethodReturnTypeEnum getMethodReturnType() { public MethodReturnTypeEnum getMethodReturnType() {
@ -145,19 +128,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
public abstract ReturnTypeEnum getReturnType(); public abstract ReturnTypeEnum getReturnType();
@SuppressWarnings("unchecked")
private List<Class<? extends IBaseResource>> createPreferTypesList() {
List<Class<? extends IBaseResource>> preferTypes = null;
if (myResourceListCollectionType != null && IBaseResource.class.isAssignableFrom(myResourceListCollectionType)) {
preferTypes = new ArrayList<Class<? extends IBaseResource>>(1);
preferTypes.add((Class<? extends IBaseResource>) myResourceListCollectionType);
// } else if (myResourceType != null) {
// preferTypes = new ArrayList<Class<? extends IBaseResource>>(1);
// preferTypes.add((Class<? extends IBaseResource>) myResourceListCollectionType);
}
return preferTypes;
}
@Override @Override
public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException {

View File

@ -22,18 +22,13 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam; import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -51,7 +46,8 @@ class ConditionalParamBinder implements IParameter {
@Override @Override
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) { public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
if (theOuterCollectionType != null || theInnerCollectionType != null || theParameterType.equals(String.class) == false) { if (theOuterCollectionType != null || theInnerCollectionType != null || theParameterType.equals(String.class) == false) {
throw new ConfigurationException("Parameters annotated with @" + ConditionalUrlParam.class.getSimpleName() + " must be of type String, found incorrect parameteter in method \"" + theMethod + "\""); throw new ConfigurationException(
"Parameters annotated with @" + ConditionalUrlParam.class.getSimpleName() + " must be of type String, found incorrect parameteter in method \"" + theMethod + "\"");
} }
} }
@ -59,11 +55,6 @@ class ConditionalParamBinder implements IParameter {
return mySupportsMultiple; return mySupportsMultiple;
} }
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
throw new UnsupportedOperationException("Can not use @" + getClass().getName() + " annotated parameters in client");
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
return theRequest.getConditionalUrl(myOperationType); return theRequest.getConditionalUrl(myOperationType);

View File

@ -28,12 +28,13 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.SimpleBundleProvider; import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding { public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding {
@ -41,9 +42,9 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
public ConformanceMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { public ConformanceMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
super(theMethod.getReturnType(), theMethod, theContext, theProvider); super(theMethod.getReturnType(), theMethod, theContext, theProvider);
// if (Modifier.isAbstract(theMethod.getReturnType().getModifiers())) { // if (Modifier.isAbstract(theMethod.getReturnType().getModifiers())) {
// throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' must not be abstract"); // throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' must not be abstract");
// } // }
MethodReturnTypeEnum methodReturnType = getMethodReturnType(); MethodReturnTypeEnum methodReturnType = getMethodReturnType();
Class<?> genericReturnType = (Class<?>) theMethod.getGenericReturnType(); Class<?> genericReturnType = (Class<?>) theMethod.getGenericReturnType();
if (methodReturnType != MethodReturnTypeEnum.RESOURCE || !IBaseConformance.class.isAssignableFrom(genericReturnType)) { if (methodReturnType != MethodReturnTypeEnum.RESOURCE || !IBaseConformance.class.isAssignableFrom(genericReturnType)) {
@ -57,20 +58,6 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
return ReturnTypeEnum.RESOURCE; return ReturnTypeEnum.RESOURCE;
} }
@Override
public HttpGetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
HttpGetClientInvocation retVal = MethodUtil.createConformanceInvocation(getContext());
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
}
return retVal;
}
@Override @Override
public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws BaseServerResponseException { public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws BaseServerResponseException {
IBaseResource conf = (IBaseResource) invokeServerMethod(theServer, theRequest, theMethodParams); IBaseResource conf = (IBaseResource) invokeServerMethod(theServer, theRequest, theMethodParams);

View File

@ -22,21 +22,15 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.primitive.IntegerDt; import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.annotation.Since; import ca.uhn.fhir.rest.annotation.Since;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -45,16 +39,6 @@ public class CountParameter implements IParameter {
private Class<?> myType; private Class<?> myType;
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
if (theSourceClientArgument != null) {
IntegerDt since = ParameterUtil.toInteger(theSourceClientArgument);
if (since.isEmpty() == false) {
theTargetQueryArguments.put(Constants.PARAM_COUNT, Collections.singletonList(since.getValueAsString()));
}
}
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
String[] sinceParams = theRequest.getParameters().get(Constants.PARAM_COUNT); String[] sinceParams = theRequest.getParameters().get(Constants.PARAM_COUNT);

View File

@ -31,12 +31,9 @@ import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.annotation.Create; import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam { public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam {
@ -45,22 +42,6 @@ public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
super(theMethod, theContext, Create.class, theProvider); super(theMethod, theContext, Create.class, theProvider);
} }
@Override
protected BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource theResource) {
FhirContext context = getContext();
BaseHttpClientInvocation retVal = MethodUtil.createCreateInvocation(theResource, context);
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
}
return retVal;
}
@Override @Override
protected String getMatchingOperation() { protected String getMatchingOperation() {
return null; return null;
@ -77,18 +58,21 @@ public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
} }
@Override @Override
protected void validateResourceIdAndUrlIdForNonConditionalOperation(IBaseResource theResource, String theResourceId, String theUrlId, String theMatchUrl) { protected void validateResourceIdAndUrlIdForNonConditionalOperation(IBaseResource theResource, String theResourceId,
String theUrlId, String theMatchUrl) {
if (isNotBlank(theUrlId)) { if (isNotBlank(theUrlId)) {
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "idInUrlForCreate", theUrlId); String msg = getContext().getLocalizer()
.getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "idInUrlForCreate", theUrlId);
throw new InvalidRequestException(msg); throw new InvalidRequestException(msg);
} }
if (getContext().getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { if (getContext().getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) {
if (isNotBlank(theResourceId)) { if (isNotBlank(theResourceId)) {
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "idInBodyForCreate", theResourceId); String msg = getContext().getLocalizer().getMessage(
BaseOutcomeReturningMethodBindingWithResourceParam.class, "idInBodyForCreate", theResourceId);
throw new InvalidRequestException(msg); throw new InvalidRequestException(msg);
} }
} else { } else {
theResource.setId((IIdType)null); theResource.setId((IIdType) null);
} }
} }

View File

@ -22,21 +22,13 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.annotation.Delete; import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceIdButNoResourceBody { public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceIdButNoResourceBody {
@ -54,47 +46,11 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
return Collections.singleton(RequestTypeEnum.DELETE); return Collections.singleton(RequestTypeEnum.DELETE);
} }
@Override
protected BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource theResource) {
StringBuilder urlExtension = new StringBuilder();
urlExtension.append(getContext().getResourceDefinition(theResource).getName());
return new HttpPostClientInvocation(getContext(), theResource, urlExtension.toString());
}
@Override @Override
protected boolean allowVoidReturnType() { protected boolean allowVoidReturnType() {
return true; return true;
} }
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
IIdType idDt = (IIdType) theArgs[getIdParameterIndex()];
if (idDt == null) {
throw new NullPointerException("ID can not be null");
}
if (idDt.hasResourceType() == false) {
idDt = idDt.withResourceType(getResourceName());
} else if (getResourceName().equals(idDt.getResourceType()) == false) {
throw new InvalidRequestException("ID parameter has the wrong resource type, expected '" + getResourceName() + "', found: " + idDt.getResourceType());
}
HttpDeleteClientInvocation retVal = createDeleteInvocation(getContext(), idDt);
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
return retVal;
}
public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, IIdType theId) {
HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theContext, theId);
return retVal;
}
@Override @Override
protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) { protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) {
theParams[getIdParameterIndex()] = theRequest.getId(); theParams[getIdParameterIndex()] = theRequest.getId();
@ -105,13 +61,4 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
return null; return null;
} }
public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, String theSearchUrl) {
HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theContext, theSearchUrl);
return retVal;
}
public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, String theResourceType, Map<String, List<String>> theParams) {
return new HttpDeleteClientInvocation(theContext, theResourceType, theParams);
}
} }

View File

@ -31,20 +31,25 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider; import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBinding { public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBinding {
private IDynamicSearchResourceProvider myProvider; private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DynamicSearchMethodBinding.class);
private List<RuntimeSearchParam> mySearchParameters;
private HashSet<String> myParamNames;
private Integer myIdParamIndex; private Integer myIdParamIndex;
private HashSet<String> myParamNames;
private IDynamicSearchResourceProvider myProvider;
private List<RuntimeSearchParam> mySearchParameters;
public DynamicSearchMethodBinding(Class<? extends IBaseResource> theReturnResourceType, Method theMethod, FhirContext theContext, IDynamicSearchResourceProvider theProvider) { public DynamicSearchMethodBinding(Class<? extends IBaseResource> theReturnResourceType, Method theMethod, FhirContext theContext, IDynamicSearchResourceProvider theProvider) {
super(theReturnResourceType, theMethod, theContext, theProvider); super(theReturnResourceType, theMethod, theContext, theProvider);
@ -57,16 +62,10 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
myParamNames.add(next.getName()); myParamNames.add(next.getName());
} }
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
} }
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
@Override @Override
public List<IParameter> getParameters() { public List<IParameter> getParameters() {
List<IParameter> retVal = new ArrayList<IParameter>(super.getParameters()); List<IParameter> retVal = new ArrayList<IParameter>(super.getParameters());
@ -79,18 +78,8 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
} }
@Override @Override
public ReturnTypeEnum getReturnType() { protected BundleTypeEnum getResponseBundleType() {
return ReturnTypeEnum.BUNDLE; return BundleTypeEnum.SEARCHSET;
}
@Override
public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
if (myIdParamIndex != null) {
theMethodParams[myIdParamIndex] = theRequest.getId();
}
Object response = invokeServerMethod(theServer, theRequest, theMethodParams);
return toResourceList(response);
} }
@Override @Override
@ -98,12 +87,19 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
return RestOperationTypeEnum.SEARCH_TYPE; return RestOperationTypeEnum.SEARCH_TYPE;
} }
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DynamicSearchMethodBinding.class); @Override
public ReturnTypeEnum getReturnType() {
return ReturnTypeEnum.BUNDLE;
}
public Collection<? extends RuntimeSearchParam> getSearchParams() {
return mySearchParameters;
}
@Override @Override
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
if (!theRequest.getResourceName().equals(getResourceName())) { if (!theRequest.getResourceName().equals(getResourceName())) {
ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() } ); ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() });
return false; return false;
} }
if (theRequest.getId() != null && myIdParamIndex == null) { if (theRequest.getId() != null && myIdParamIndex == null) {
@ -153,13 +149,13 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
} }
@Override @Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
// there should be no way to call this.... if (myIdParamIndex != null) {
throw new UnsupportedOperationException("Dynamic search methods are only used for server implementations"); theMethodParams[myIdParamIndex] = theRequest.getId();
} }
public Collection<? extends RuntimeSearchParam> getSearchParams() { Object response = invokeServerMethod(theServer, theRequest, theMethodParams);
return mySearchParameters; return toResourceList(response);
} }
} }

View File

@ -22,23 +22,15 @@ package ca.uhn.fhir.rest.server.method;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.*;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.CollectionBinder; import ca.uhn.fhir.rest.param.CollectionBinder;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -47,28 +39,6 @@ public class ElementsParameter implements IParameter {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private Class<? extends Collection> myInnerCollectionType; private Class<? extends Collection> myInnerCollectionType;
@SuppressWarnings("unchecked")
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
if (theSourceClientArgument instanceof Collection) {
StringBuilder values = new StringBuilder();
for (String next : (Collection<String>) theSourceClientArgument) {
if (isNotBlank(next)) {
if (values.length() > 0) {
values.append(',');
}
values.append(next);
}
}
theTargetQueryArguments.put(Constants.PARAM_ELEMENTS, Collections.singletonList(values.toString()));
} else {
String elements = (String) theSourceClientArgument;
if (elements != null) {
theTargetQueryArguments.put(Constants.PARAM_ELEMENTS, Collections.singletonList(elements));
}
}
}
@Override @Override
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
@ -121,7 +91,8 @@ public class ElementsParameter implements IParameter {
@Override @Override
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) { public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
if (theOuterCollectionType != null) { if (theOuterCollectionType != null) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of type " + SummaryEnum.class + " but can not be a collection of collections"); throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of type " + SummaryEnum.class
+ " but can not be a collection of collections");
} }
if (theInnerCollectionType != null) { if (theInnerCollectionType != null) {
myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, SummaryEnum.class.getSimpleName()); myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, SummaryEnum.class.getSimpleName());

View File

@ -21,11 +21,8 @@ package ca.uhn.fhir.rest.server.method;
*/ */
import java.io.IOException; import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
@ -33,17 +30,17 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.GetTags; import ca.uhn.fhir.rest.annotation.GetTags;
import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.ParseAction;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
public class GetTagsMethodBinding extends BaseMethodBinding<TagList> { public class GetTagsMethodBinding extends BaseMethodBinding<TagList> {
@ -66,8 +63,8 @@ public class GetTagsMethodBinding extends BaseMethodBinding<TagList> {
myResourceName = theContext.getResourceDefinition(myType).getName(); myResourceName = theContext.getResourceDefinition(myType).getName();
} }
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
myVersionIdParamIndex = MethodUtil.findVersionIdParameterIndex(theMethod); myVersionIdParamIndex = ParameterUtil.findVersionIdParameterIndex(theMethod);
if (myIdParamIndex != null && myType.equals(IResource.class)) { if (myIdParamIndex != null && myType.equals(IResource.class)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' does not specify a resource type, but has an @" + IdParam.class.getSimpleName() throw new ConfigurationException("Method '" + theMethod.getName() + "' does not specify a resource type, but has an @" + IdParam.class.getSimpleName()
@ -104,60 +101,9 @@ public class GetTagsMethodBinding extends BaseMethodBinding<TagList> {
if ((myIdParamIndex != null) != (theRequest.getId() != null)) { if ((myIdParamIndex != null) != (theRequest.getId() != null)) {
return false; return false;
} }
// if ((myVersionIdParamIndex != null) != (theRequest.getVersionId() != null)) {
// return false;
// }
return true; return true;
} }
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
HttpGetClientInvocation retVal;
IdDt id = null;
IdDt versionId = null;
if (myIdParamIndex != null) {
id = (IdDt) theArgs[myIdParamIndex];
if (myVersionIdParamIndex != null) {
versionId = (IdDt) theArgs[myVersionIdParamIndex];
}
}
if (myType != IResource.class) {
if (id != null) {
if (versionId != null) {
retVal = new HttpGetClientInvocation(getContext(), getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, versionId.getValue(), Constants.PARAM_TAGS);
} else if (id.hasVersionIdPart()) {
retVal = new HttpGetClientInvocation(getContext(), getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, id.getVersionIdPart(), Constants.PARAM_TAGS);
} else {
retVal = new HttpGetClientInvocation(getContext(), getResourceName(), id.getIdPart(), Constants.PARAM_TAGS);
}
} else {
retVal = new HttpGetClientInvocation(getContext(), getResourceName(), Constants.PARAM_TAGS);
}
} else {
retVal = new HttpGetClientInvocation(getContext(), Constants.PARAM_TAGS);
}
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
}
return retVal;
}
@Override
public TagList invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
if (theResponseStatusCode == Constants.STATUS_HTTP_200_OK) {
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theResponseStatusCode, null);
TagList retVal = parser.parseTagList(theResponseReader);
return retVal;
}
throw processNon2xxResponseAndReturnExceptionToThrow(theResponseStatusCode, theResponseMimeType, theResponseReader);
}
@Override @Override
public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException {
Object[] params = createParametersForServerRequest(theRequest); Object[] params = createParametersForServerRequest(theRequest);

View File

@ -20,7 +20,6 @@ package ca.uhn.fhir.rest.server.method;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@ -37,11 +36,13 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.History; import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.server.*; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -54,7 +55,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
public HistoryMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { public HistoryMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
super(toReturnType(theMethod, theProvider), theMethod, theContext, theProvider); super(toReturnType(theMethod, theProvider), theMethod, theContext, theProvider);
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
History historyAnnotation = theMethod.getAnnotation(History.class); History historyAnnotation = theMethod.getAnnotation(History.class);
Class<? extends IBaseResource> type = historyAnnotation.type(); Class<? extends IBaseResource> type = historyAnnotation.type();
@ -128,29 +129,6 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
return true; return true;
} }
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
IdDt id = null;
String resourceName = myResourceName;
if (myIdParamIndex != null) {
id = (IdDt) theArgs[myIdParamIndex];
if (id == null || isBlank(id.getValue())) {
throw new NullPointerException("ID can not be null");
}
}
String historyId = id != null ? id.getIdPart() : null;
HttpGetClientInvocation retVal = createHistoryInvocation(getContext(), resourceName, historyId, null, null);
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], retVal.getParameters(), null);
}
}
return retVal;
}
@Override @Override
public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
@ -210,34 +188,6 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
}; };
} }
public static HttpGetClientInvocation createHistoryInvocation(FhirContext theContext, String theResourceName, String theId, IPrimitiveType<Date> theSince, Integer theLimit) {
StringBuilder b = new StringBuilder();
if (theResourceName != null) {
b.append(theResourceName);
if (isNotBlank(theId)) {
b.append('/');
b.append(theId);
}
}
if (b.length() > 0) {
b.append('/');
}
b.append(Constants.PARAM_HISTORY);
boolean haveParam = false;
if (theSince != null && !theSince.isEmpty()) {
haveParam = true;
b.append('?').append(Constants.PARAM_SINCE).append('=').append(theSince.getValueAsString());
}
if (theLimit != null) {
b.append(haveParam ? '&' : '?');
b.append(Constants.PARAM_COUNT).append('=').append(theLimit);
}
HttpGetClientInvocation retVal = new HttpGetClientInvocation(theContext, b.toString());
return retVal;
}
private static Class<? extends IBaseResource> toReturnType(Method theMethod, Object theProvider) { private static Class<? extends IBaseResource> toReturnType(Method theMethod, Object theProvider) {
if (theProvider instanceof IResourceProvider) { if (theProvider instanceof IResourceProvider) {
return ((IResourceProvider) theProvider).getResourceType(); return ((IResourceProvider) theProvider).getResourceType();

View File

@ -24,8 +24,7 @@ import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.api.server.IRequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.IServerMethodBinding;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -42,7 +41,7 @@ public interface IParameter {
* @param theMethodBinding TODO * @param theMethodBinding TODO
* @return Returns the argument object as it will be passed to the IResourceProvider method. * @return Returns the argument object as it will be passed to the IResourceProvider method.
*/ */
Object translateQueryParametersIntoServerArgument(IRequestDetails theRequest, IServerMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException; Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException;
void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType); void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType);

View File

@ -32,8 +32,9 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.annotation.IncludeParam; import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.param.BaseQueryParameter; import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;

View File

@ -22,23 +22,13 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
class NullParameter implements IParameter { class NullParameter implements IParameter {
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
//nothing
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {

View File

@ -28,17 +28,10 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
@ -49,15 +42,15 @@ import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.FhirTerser;
public class OperationMethodBinding extends BaseResourceReturningMethodBinding { public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
@ -81,7 +74,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
myBundleType = theBundleType; myBundleType = theBundleType;
myIdempotent = theIdempotent; myIdempotent = theIdempotent;
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
if (myIdParamIndex != null) { if (myIdParamIndex != null) {
for (Annotation next : theMethod.getParameterAnnotations()[myIdParamIndex]) { for (Annotation next : theMethod.getParameterAnnotations()[myIdParamIndex]) {
if (next instanceof IdParam) { if (next instanceof IdParam) {
@ -245,24 +238,6 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
return true; return true;
} }
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
String id = null;
if (myIdParamIndex != null) {
IIdType idDt = (IIdType) theArgs[myIdParamIndex];
id = idDt.getValue();
}
IBaseParameters parameters = (IBaseParameters) getContext().getResourceDefinition("Parameters").newInstance();
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, parameters);
}
}
return createOperationInvocation(getContext(), getResourceName(), id, myName, parameters, false);
}
@Override @Override
public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException {

View File

@ -33,15 +33,20 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory;
import ca.uhn.fhir.rest.server.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding; import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.util.CoverageIgnore;
public class PageMethodBinding extends BaseResourceReturningMethodBinding { public class PageMethodBinding extends BaseResourceReturningMethodBinding {
@ -144,31 +149,6 @@ public class PageMethodBinding extends BaseResourceReturningMethodBinding {
return bundle; return bundle;
} }
return bundleFactory.getResourceBundle(); return bundleFactory.getResourceBundle();
// if (bundle != null) {
// for (int i = getInterceptors().size() - 1; i >= 0; i--) {
// IServerInterceptor next = getInterceptors().get(i);
// boolean continueProcessing = next.outgoingResponse(theRequest, bundle, theRequest.getServletRequest(),
// theRequest.getServletResponse());
// if (!continueProcessing) {
// ourLog.debug("Interceptor {} returned false, not continuing processing");
// return;
// }
// }
// theRequest.getResponse().streamResponseAsBundle(bundle, summaryMode, respondGzip, requestIsBrowser);
// } else {
// IBaseResource resBundle = bundleFactory.getResourceBundle();
// for (int i = getInterceptors().size() - 1; i >= 0; i--) {
// IServerInterceptor next = getInterceptors().get(i);
// boolean continueProcessing = next.outgoingResponse(theRequest, resBundle, theRequest.getServletRequest(),
// theRequest.getServletResponse());
// if (!continueProcessing) {
// ourLog.debug("Interceptor {} returned false, not continuing processing");
// return;
// }
// }
// theRequest.getResponse().streamResponseAsResource(resBundle, prettyPrint, summaryMode,
// Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), false);
// }
} }
@Override @Override
@ -188,10 +168,5 @@ public class PageMethodBinding extends BaseResourceReturningMethodBinding {
return true; return true;
} }
@CoverageIgnore
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
throw new UnsupportedOperationException();
}
} }

View File

@ -22,21 +22,21 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.Arrays;
import java.util.Collections;
import java.util.ListIterator;
import java.util.Set;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.annotation.Patch; import ca.uhn.fhir.rest.annotation.Patch;
import ca.uhn.fhir.rest.annotation.ResourceParam; import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.PatchTypeEnum;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
/** /**
* Base class for an operation that has a resource type but not a resource body in the * Base class for an operation that has a resource type but not a resource body in the
@ -91,54 +91,7 @@ public class PatchMethodBinding extends BaseOutcomeReturningMethodBindingWithRes
return Collections.singleton(RequestTypeEnum.PATCH); return Collections.singleton(RequestTypeEnum.PATCH);
} }
@Override
protected BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource theResource) {
StringBuilder urlExtension = new StringBuilder();
urlExtension.append(getContext().getResourceDefinition(theResource).getName());
return new HttpPostClientInvocation(getContext(), theResource, urlExtension.toString());
}
@Override
protected boolean allowVoidReturnType() {
return true;
}
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
IIdType idDt = (IIdType) theArgs[getIdParameterIndex()];
if (idDt == null) {
throw new NullPointerException("ID can not be null");
}
if (idDt.hasResourceType() == false) {
idDt = idDt.withResourceType(getResourceName());
} else if (getResourceName().equals(idDt.getResourceType()) == false) {
throw new InvalidRequestException("ID parameter has the wrong resource type, expected '" + getResourceName() + "', found: " + idDt.getResourceType());
}
PatchTypeEnum patchType = (PatchTypeEnum) theArgs[myPatchTypeParameterIndex];
String body = (String) theArgs[myResourceParamIndex];
HttpPatchClientInvocation retVal = createPatchInvocation(getContext(), idDt, patchType, body);
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
return retVal;
}
public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, IIdType theId, PatchTypeEnum thePatchType, String theBody) {
HttpPatchClientInvocation retVal = new HttpPatchClientInvocation(theContext, theId, thePatchType.getContentType(), theBody);
return retVal;
}
public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, String theUrlPath, PatchTypeEnum thePatchType, String theBody) {
HttpPatchClientInvocation retVal = new HttpPatchClientInvocation(theContext, theUrlPath, thePatchType.getContentType(), theBody);
return retVal;
}
@Override @Override
protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) { protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) {
@ -152,11 +105,5 @@ public class PatchMethodBinding extends BaseOutcomeReturningMethodBindingWithRes
return null; return null;
} }
public static HttpPatchClientInvocation createPatchInvocation(FhirContext theContext, PatchTypeEnum thePatchType, String theBody, String theResourceType, Map<String, List<String>> theMatchParams) {
StringBuilder urlBuilder = MethodUtil.createUrl(theResourceType, theMatchParams);
String url = urlBuilder.toString();
HttpPatchClientInvocation retVal = new HttpPatchClientInvocation(theContext, url, thePatchType.getContentType(), theBody);
return retVal;
}
} }

View File

@ -24,23 +24,14 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.PatchTypeEnum;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
class PatchTypeParameter implements IParameter { class PatchTypeParameter implements IParameter {
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
// nothing
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {

View File

@ -28,15 +28,12 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.annotation.RawParam; import ca.uhn.fhir.rest.annotation.RawParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.param.QualifierDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.method.SearchMethodBinding.QualifierDetails;
public class RawParamsParmeter implements IParameter { public class RawParamsParmeter implements IParameter {
@ -46,11 +43,6 @@ public class RawParamsParmeter implements IParameter {
myAllMethodParameters = theParameters; myAllMethodParameters = theParameters;
} }
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource)
throws InternalErrorException {
// not supported on client for now
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {

View File

@ -2,51 +2,41 @@ package ca.uhn.fhir.rest.server.method;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 - 2017 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.annotation.Elements;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.server.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.server.exceptions.*; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.ETagSupportEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.NotModifiedException;
import ca.uhn.fhir.util.DateUtils; import ca.uhn.fhir.util.DateUtils;
public class ReadMethodBinding extends BaseResourceReturningMethodBinding implements IClientResponseHandlerHandlesBinary<Object> { public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReadMethodBinding.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReadMethodBinding.class);
private Integer myIdIndex; private Integer myIdIndex;
@ -60,8 +50,8 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
Validate.notNull(theMethod, "Method must not be null"); Validate.notNull(theMethod, "Method must not be null");
Integer idIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); Integer idIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
Integer versionIdIndex = MethodUtil.findVersionIdParameterIndex(theMethod); Integer versionIdIndex = ParameterUtil.findVersionIdParameterIndex(theMethod);
Class<?>[] parameterTypes = theMethod.getParameterTypes(); Class<?>[] parameterTypes = theMethod.getParameterTypes();
@ -147,60 +137,10 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
return true; return true;
} }
@Override
public HttpGetClientInvocation invokeClient(Object[] theArgs) {
HttpGetClientInvocation retVal;
IIdType id = ((IIdType) theArgs[myIdIndex]);
if (myVersionIdIndex == null) {
String resourceName = getResourceName();
if (id.hasVersionIdPart()) {
retVal = createVReadInvocation(getContext(), new IdDt(resourceName, id.getIdPart(), id.getVersionIdPart()), resourceName);
} else {
retVal = createReadInvocation(getContext(), id, resourceName);
}
} else {
IdDt vid = ((IdDt) theArgs[myVersionIdIndex]);
String resourceName = getResourceName();
retVal = createVReadInvocation(getContext(), new IdDt(resourceName, id.getIdPart(), vid.getVersionIdPart()), resourceName);
}
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
return retVal;
}
@Override
public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
byte[] contents = IOUtils.toByteArray(theResponseReader);
IBaseBinary resource = (IBaseBinary) getContext().getResourceDefinition("Binary").newInstance();
resource.setContentType(theResponseMimeType);
resource.setContent(contents);
switch (getMethodReturnType()) {
case BUNDLE:
return Bundle.withSingleResource((IResource) resource);
case LIST_OF_RESOURCES:
return Collections.singletonList(resource);
case RESOURCE:
return resource;
case BUNDLE_PROVIDER:
return new SimpleBundleProvider(resource);
case BUNDLE_RESOURCE:
case METHOD_OUTCOME:
break;
}
throw new IllegalStateException("" + getMethodReturnType()); // should not happen
}
@Override @Override
public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
theMethodParams[myIdIndex] = MethodUtil.convertIdToType(theRequest.getId(), myIdParameterType); theMethodParams[myIdIndex] = ParameterUtil.convertIdToType(theRequest.getId(), myIdParameterType);
if (myVersionIdIndex != null) { if (myVersionIdIndex != null) {
theMethodParams[myVersionIdIndex] = new IdDt(theRequest.getId().getVersionIdPart()); theMethodParams[myVersionIdIndex] = new IdDt(theRequest.getId().getVersionIdPart());
} }
@ -217,7 +157,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
if (theRequest.getServer().getETagSupport() == ETagSupportEnum.ENABLED) { if (theRequest.getServer().getETagSupport() == ETagSupportEnum.ENABLED) {
String ifNoneMatch = theRequest.getHeader(Constants.HEADER_IF_NONE_MATCH_LC); String ifNoneMatch = theRequest.getHeader(Constants.HEADER_IF_NONE_MATCH_LC);
if (StringUtils.isNotBlank(ifNoneMatch)) { if (StringUtils.isNotBlank(ifNoneMatch)) {
ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch); ifNoneMatch = ParameterUtil.parseETagValue(ifNoneMatch);
if (responseResource.getIdElement() != null && responseResource.getIdElement().hasVersionIdPart()) { if (responseResource.getIdElement() != null && responseResource.getIdElement().hasVersionIdPart()) {
if (responseResource.getIdElement().getVersionIdPart().equals(ifNoneMatch)) { if (responseResource.getIdElement().getVersionIdPart().equals(ifNoneMatch)) {
ourLog.debug("Returning HTTP 301 because request specified {}={}", Constants.HEADER_IF_NONE_MATCH, ifNoneMatch); ourLog.debug("Returning HTTP 301 because request specified {}={}", Constants.HEADER_IF_NONE_MATCH, ifNoneMatch);
@ -253,31 +193,15 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
return retVal; return retVal;
} }
@Override // @Override
public boolean isBinary() { // public boolean isBinary() {
return "Binary".equals(getResourceName()); // return "Binary".equals(getResourceName());
} // }
public boolean isVread() { public boolean isVread() {
return mySupportsVersion || myVersionIdIndex != null; return mySupportsVersion || myVersionIdIndex != null;
} }
public static HttpGetClientInvocation createAbsoluteReadInvocation(FhirContext theContext, IIdType theId) {
return new HttpGetClientInvocation(theContext, theId.toVersionless().getValue());
}
public static HttpGetClientInvocation createAbsoluteVReadInvocation(FhirContext theContext, IIdType theId) {
return new HttpGetClientInvocation(theContext, theId.getValue());
}
public static HttpGetClientInvocation createReadInvocation(FhirContext theContext, IIdType theId, String theResourceName) {
return new HttpGetClientInvocation(theContext, new IdDt(theResourceName, theId.getIdPart()).getValue());
}
public static HttpGetClientInvocation createVReadInvocation(FhirContext theContext, IIdType theId, String theResourceName) {
return new HttpGetClientInvocation(theContext, new IdDt(theResourceName, theId.getIdPart(), theId.getVersionIdPart()).getValue());
}
@Override @Override
protected BundleTypeEnum getResponseBundleType() { protected BundleTypeEnum getResponseBundleType() {
return null; return null;

View File

@ -22,27 +22,14 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class RequestDetailsParameter implements IParameter { public class RequestDetailsParameter implements IParameter {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RequestDetailsParameter.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RequestDetailsParameter.class);
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
/*
* Does nothing, since we just ignore HttpServletRequest arguments
*/
ourLog.trace("Ignoring RequestDetailsParameter argument: {}", theSourceClientArgument);
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {

View File

@ -22,26 +22,12 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.CoverageIgnore;
class RequestOperationCallbackParameter implements IParameter { class RequestOperationCallbackParameter implements IParameter {
// private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletRequestParameter.class);
@CoverageIgnore
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
// nothing
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {

View File

@ -21,7 +21,10 @@ package ca.uhn.fhir.rest.server.method;
*/ */
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.*; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -34,11 +37,16 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServerUtils; import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -49,7 +57,7 @@ public class ResourceParameter implements IParameter {
private Mode myMode; private Mode myMode;
private Class<? extends IBaseResource> myResourceType; private Class<? extends IBaseResource> myResourceType;
public ResourceParameter(Class<? extends IResource> theParameterType, Object theProvider, Mode theMode) { public ResourceParameter(Class<? extends IBaseResource> theParameterType, Object theProvider, Mode theMode) {
Validate.notNull(theParameterType, "theParameterType can not be null"); Validate.notNull(theParameterType, "theParameterType can not be null");
Validate.notNull(theMode, "theMode can not be null"); Validate.notNull(theMode, "theMode can not be null");
@ -82,7 +90,7 @@ public class ResourceParameter implements IParameter {
@Override @Override
public Object translateQueryParametersIntoServerArgument(IRequestDetails theRequest, IServerMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
switch (myMode) { switch (myMode) {
case BODY: case BODY:
try { try {
@ -178,7 +186,7 @@ public class ResourceParameter implements IParameter {
if (theRequest.getServer().getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) { if (theRequest.getServer().getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
TagList tagList = new TagList(); TagList tagList = new TagList();
for (String nextTagComplete : theRequest.getHeaders(Constants.HEADER_CATEGORY)) { for (String nextTagComplete : theRequest.getHeaders(Constants.HEADER_CATEGORY)) {
MethodUtil.parseTagValue(tagList, nextTagComplete); ParameterUtil.parseTagValue(tagList, nextTagComplete);
} }
if (tagList.isEmpty() == false) { if (tagList.isEmpty() == false) {
((IResource) retVal).getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList); ((IResource) retVal).getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);

View File

@ -24,12 +24,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -38,14 +34,16 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.param.BaseQueryParameter; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.param.QualifierDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -63,7 +61,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
Search search = theMethod.getAnnotation(Search.class); Search search = theMethod.getAnnotation(Search.class);
this.myQueryName = StringUtils.defaultIfBlank(search.queryName(), null); this.myQueryName = StringUtils.defaultIfBlank(search.queryName(), null);
this.myCompartmentName = StringUtils.defaultIfBlank(search.compartmentName(), null); this.myCompartmentName = StringUtils.defaultIfBlank(search.compartmentName(), null);
this.myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); this.myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
this.myAllowUnknownParams = search.allowUnknownParams(); this.myAllowUnknownParams = search.allowUnknownParams();
Description desc = theMethod.getAnnotation(Description.class); Description desc = theMethod.getAnnotation(Description.class);
@ -255,30 +253,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
return true; return true;
} }
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
assert (myQueryName == null || ((theArgs != null ? theArgs.length : 0) == getParameters().size())) : "Wrong number of arguments: " + (theArgs != null ? theArgs.length : "null");
Map<String, List<String>> queryStringArgs = new LinkedHashMap<String, List<String>>();
if (myQueryName != null) {
queryStringArgs.put(Constants.PARAM_QUERY, Collections.singletonList(myQueryName));
}
IdDt id = (IdDt) (myIdParamIndex != null ? theArgs[myIdParamIndex] : null);
String resourceName = getResourceName();
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], queryStringArgs, null);
}
}
BaseHttpClientInvocation retVal = createSearchInvocation(getContext(), resourceName, queryStringArgs, id, myCompartmentName, null);
return retVal;
}
@Override @Override
public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
@ -316,70 +290,52 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
public String toString() { public String toString() {
return getMethod().toString(); return getMethod().toString();
} }
public static QualifierDetails extractQualifiersFromParameterName(String theParamName) {
QualifierDetails retVal = new QualifierDetails();
if (theParamName == null || theParamName.length() == 0) {
return retVal;
}
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName, int dotIdx = -1;
SearchStyleEnum theSearchStyle) { int colonIdx = -1;
SearchStyleEnum searchStyle = theSearchStyle; for (int idx = 0; idx < theParamName.length(); idx++) {
if (searchStyle == null) { char nextChar = theParamName.charAt(idx);
int length = 0; if (nextChar == '.' && dotIdx == -1) {
for (Entry<String, List<String>> nextEntry : theParameters.entrySet()) { dotIdx = idx;
length += nextEntry.getKey().length(); } else if (nextChar == ':' && colonIdx == -1) {
for (String next : nextEntry.getValue()) { colonIdx = idx;
length += next.length();
} }
} }
if (length < 5000) { if (dotIdx != -1 && colonIdx != -1) {
searchStyle = SearchStyleEnum.GET; if (dotIdx < colonIdx) {
retVal.setDotQualifier(theParamName.substring(dotIdx, colonIdx));
retVal.setColonQualifier(theParamName.substring(colonIdx));
retVal.setParamName(theParamName.substring(0, dotIdx));
retVal.setWholeQualifier(theParamName.substring(dotIdx));
} else { } else {
searchStyle = SearchStyleEnum.POST; retVal.setColonQualifier(theParamName.substring(colonIdx, dotIdx));
retVal.setDotQualifier(theParamName.substring(dotIdx));
retVal.setParamName(theParamName.substring(0, colonIdx));
retVal.setWholeQualifier(theParamName.substring(colonIdx));
} }
} } else if (dotIdx != -1) {
retVal.setDotQualifier(theParamName.substring(dotIdx));
BaseHttpClientInvocation invocation; retVal.setParamName(theParamName.substring(0, dotIdx));
retVal.setWholeQualifier(theParamName.substring(dotIdx));
boolean compartmentSearch = false; } else if (colonIdx != -1) {
if (theCompartmentName != null) { retVal.setColonQualifier(theParamName.substring(colonIdx));
if (theId == null || !theId.hasIdPart()) { retVal.setParamName(theParamName.substring(0, colonIdx));
String msg = theContext.getLocalizer().getMessage(SearchMethodBinding.class.getName() + ".idNullForCompartmentSearch"); retVal.setWholeQualifier(theParamName.substring(colonIdx));
throw new InvalidRequestException(msg);
}
compartmentSearch = true;
}
/*
* Are we doing a get (GET [base]/Patient?name=foo) or a get with search (GET [base]/Patient/_search?name=foo) or a post (POST [base]/Patient with parameters in the POST body)
*/
switch (searchStyle) {
case GET:
default:
if (compartmentSearch) {
invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName, theId.getIdPart(), theCompartmentName);
} else { } else {
invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName); retVal.setParamName(theParamName);
} retVal.setColonQualifier(null);
break; retVal.setDotQualifier(null);
case GET_WITH_SEARCH: retVal.setWholeQualifier(null);
if (compartmentSearch) {
invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName, theId.getIdPart(), theCompartmentName, Constants.PARAM_SEARCH);
} else {
invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName, Constants.PARAM_SEARCH);
}
break;
case POST:
if (compartmentSearch) {
invocation = new HttpPostClientInvocation(theContext, theParameters, theResourceName, theId.getIdPart(), theCompartmentName, Constants.PARAM_SEARCH);
} else {
invocation = new HttpPostClientInvocation(theContext, theParameters, theResourceName, Constants.PARAM_SEARCH);
}
} }
return invocation; return retVal;
} }
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theSearchUrl, Map<String, List<String>> theParams) {
return new HttpGetClientInvocation(theContext, theParams, theSearchUrl);
}
} }

View File

@ -22,27 +22,12 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
class ServerBaseParamBinder implements IParameter { class ServerBaseParamBinder implements IParameter {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerBaseParamBinder.class);
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
/*
* Does nothing, since we just ignore serverbase arguments
*/
ourLog.trace("Ignoring server base argument: {}", theSourceClientArgument);
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {

View File

@ -22,14 +22,8 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
@ -41,14 +35,6 @@ class ServletRequestParameter implements IParameter {
super(); super();
} }
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
/*
* Does nothing, since we just ignore HttpServletRequest arguments
*/
ourLog.trace("Ignoring HttpServletRequest argument: {}", theSourceClientArgument);
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
return ((ServletRequestDetails) theRequest).getServletRequest(); return ((ServletRequestDetails) theRequest).getServletRequest();

View File

@ -22,14 +22,8 @@ package ca.uhn.fhir.rest.server.method;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
@ -37,20 +31,11 @@ import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
class ServletResponseParameter implements IParameter { class ServletResponseParameter implements IParameter {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletResponseParameter.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletResponseParameter.class);
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
/*
* Does nothing, since we just ignore HttpServletResponse arguments
*/
ourLog.trace("Ignoring HttpServletResponse argument: {}", theSourceClientArgument);
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
return ((ServletRequestDetails) theRequest).getServletResponse(); return ((ServletRequestDetails) theRequest).getServletResponse();
} }
@Override @Override
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) { public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
// ignore // ignore

View File

@ -22,21 +22,13 @@ package ca.uhn.fhir.rest.server.method;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.rest.annotation.Sort; import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -52,51 +44,16 @@ public class SortParameter implements IParameter {
@Override @Override
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) { public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
if (theOuterCollectionType != null || theInnerCollectionType != null) { if (theOuterCollectionType != null || theInnerCollectionType != null) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Sort.class.getName() + " but can not be of collection type"); throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Sort.class.getName()
+ " but can not be of collection type");
} }
if (!theParameterType.equals(SortSpec.class)) { if (!theParameterType.equals(SortSpec.class)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Sort.class.getName() + " but is an invalid type, must be: " + SortSpec.class.getCanonicalName()); throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Sort.class.getName()
+ " but is an invalid type, must be: " + SortSpec.class.getCanonicalName());
} }
} }
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
SortSpec ss = (SortSpec) theSourceClientArgument;
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2)) {
String string = createSortStringDstu3(ss);
if (string.length() > 0) {
if (!theTargetQueryArguments.containsKey(Constants.PARAM_SORT)) {
theTargetQueryArguments.put(Constants.PARAM_SORT, new ArrayList<String>());
}
theTargetQueryArguments.get(Constants.PARAM_SORT).add(string);
}
} else {
while (ss != null) {
String name;
if (ss.getOrder() == null) {
name = Constants.PARAM_SORT;
} else if (ss.getOrder() == SortOrderEnum.ASC) {
name = Constants.PARAM_SORT_ASC;
} else {
name = Constants.PARAM_SORT_DESC;
}
if (ss.getParamName() != null) {
if (!theTargetQueryArguments.containsKey(name)) {
theTargetQueryArguments.put(name, new ArrayList<String>());
}
theTargetQueryArguments.get(name).add(ss.getParamName());
}
ss = ss.getChain();
}
}
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT)) { if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT)) {

View File

@ -22,22 +22,13 @@ package ca.uhn.fhir.rest.server.method;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.CollectionBinder; import ca.uhn.fhir.rest.param.CollectionBinder;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -46,24 +37,6 @@ public class SummaryEnumParameter implements IParameter {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private Class<? extends Collection> myInnerCollectionType; private Class<? extends Collection> myInnerCollectionType;
@SuppressWarnings("unchecked")
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
if (theSourceClientArgument instanceof Collection) {
List<String> values = new ArrayList<String>();
for (SummaryEnum next : (Collection<SummaryEnum>) theSourceClientArgument) {
if (next != null) {
values.add(next.getCode());
}
}
theTargetQueryArguments.put(Constants.PARAM_SUMMARY, values);
} else {
SummaryEnum ss = (SummaryEnum) theSourceClientArgument;
if (ss != null) {
theTargetQueryArguments.put(Constants.PARAM_SUMMARY, Collections.singletonList(ss.getCode()));
}
}
}
@Override @Override
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })

View File

@ -25,7 +25,6 @@ import java.lang.reflect.Method;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
@ -38,10 +37,11 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.Transaction; import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.server.*; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
@ -60,7 +60,8 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
for (IParameter next : getParameters()) { for (IParameter next : getParameters()) {
if (next instanceof TransactionParameter) { if (next instanceof TransactionParameter) {
if (myTransactionParamIndex != -1) { if (myTransactionParamIndex != -1) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " has multiple parameters annotated with the @" + TransactionParam.class + " annotation, exactly one is required for @" + Transaction.class throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " has multiple parameters annotated with the @"
+ TransactionParam.class + " annotation, exactly one is required for @" + Transaction.class
+ " methods"); + " methods");
} }
myTransactionParamIndex = index; myTransactionParamIndex = index;
@ -70,7 +71,8 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
} }
if (myTransactionParamIndex == -1) { if (myTransactionParamIndex == -1) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " does not have a parameter annotated with the @" + TransactionParam.class + " annotation"); throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " does not have a parameter annotated with the @"
+ TransactionParam.class + " annotation");
} }
} }
@ -103,18 +105,6 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
return true; return true;
} }
@Override
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
FhirContext context = getContext();
if (theArgs[myTransactionParamIndex] instanceof Bundle) {
Bundle bundle = (Bundle) theArgs[myTransactionParamIndex];
return createTransactionInvocation(bundle, context);
}
@SuppressWarnings("unchecked")
List<IBaseResource> resources = (List<IBaseResource>) theArgs[myTransactionParamIndex];
return createTransactionInvocation(resources, context);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
@ -166,7 +156,7 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
if (oldId != null && !oldId.isEmpty()) { if (oldId != null && !oldId.isEmpty()) {
if (!oldId.equals(newRes.getIdElement()) && newRes instanceof IResource) { if (!oldId.equals(newRes.getIdElement()) && newRes instanceof IResource) {
((IResource)newRes).getResourceMetadata().put(ResourceMetadataKeyEnum.PREVIOUS_ID, oldId); ((IResource) newRes).getResourceMetadata().put(ResourceMetadataKeyEnum.PREVIOUS_ID, oldId);
} }
} }
} }
@ -174,7 +164,6 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
return retVal; return retVal;
} }
@Override @Override
protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) { protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) {
super.populateActionRequestDetailsForInterceptor(theRequestDetails, theDetails, theMethodParams); super.populateActionRequestDetailsForInterceptor(theRequestDetails, theDetails, theMethodParams);
@ -191,20 +180,4 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
} }
public static BaseHttpClientInvocation createTransactionInvocation(Bundle theBundle, FhirContext theContext) {
return new HttpPostClientInvocation(theContext, theBundle);
}
public static BaseHttpClientInvocation createTransactionInvocation(IBaseBundle theBundle, FhirContext theContext) {
return new HttpPostClientInvocation(theContext, theBundle);
}
public static BaseHttpClientInvocation createTransactionInvocation(List<? extends IBaseResource> theResources, FhirContext theContext) {
return new HttpPostClientInvocation(theContext, theResources, BundleTypeEnum.TRANSACTION);
}
public static BaseHttpClientInvocation createTransactionInvocation(String theRawBundle, FhirContext theContext) {
return new HttpPostClientInvocation(theContext, theRawBundle, true, "");
}
} }

View File

@ -38,10 +38,8 @@ import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.TransactionParam; import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.method.BaseMethodBinding; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.method.IParameter; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.RestfulServerUtils; import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -92,11 +90,6 @@ public class TransactionParameter implements IParameter {
} }
} }
@Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException {
// nothing
}
@Override @Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException { public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {

View File

@ -30,23 +30,19 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Update; import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam { public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam {
private Integer myIdParameterIndex;
public UpdateMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { public UpdateMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
super(theMethod, theContext, Update.class, theProvider); super(theMethod, theContext, Update.class, theProvider);
myIdParameterIndex = MethodUtil.findIdParameterIndex(theMethod, getContext());
} }
@Override @Override
@ -89,7 +85,7 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
public static IIdType applyETagAsVersion(RequestDetails theRequest, IIdType id) { public static IIdType applyETagAsVersion(RequestDetails theRequest, IIdType id) {
String ifMatchValue = theRequest.getHeader(Constants.HEADER_IF_MATCH); String ifMatchValue = theRequest.getHeader(Constants.HEADER_IF_MATCH);
if (isNotBlank(ifMatchValue)) { if (isNotBlank(ifMatchValue)) {
ifMatchValue = MethodUtil.parseETagValue(ifMatchValue); ifMatchValue = ParameterUtil.parseETagValue(ifMatchValue);
if (id != null && id.hasVersionIdPart() == false) { if (id != null && id.hasVersionIdPart() == false) {
id = id.withVersion(ifMatchValue); id = id.withVersion(ifMatchValue);
} }
@ -97,25 +93,6 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
return id; return id;
} }
@Override
protected BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource theResource) {
IdDt idDt = (IdDt) theArgs[myIdParameterIndex];
if (idDt == null) {
throw new NullPointerException("ID can not be null");
}
FhirContext context = getContext();
HttpPutClientInvocation retVal = MethodUtil.createUpdateInvocation(theResource, null, idDt, context);
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
return retVal;
}
@Override @Override
protected String getMatchingOperation() { protected String getMatchingOperation() {
return null; return null;
@ -154,7 +131,7 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
throw new InvalidRequestException(msg); throw new InvalidRequestException(msg);
} }
} else { } else {
theResource.setId((IIdType)null); theResource.setId((IIdType) null);
} }
} }

View File

@ -24,16 +24,13 @@ import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Validate; import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.param.IParameter;
public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindingWithResourceParam { public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindingWithResourceParam {
@ -42,7 +39,7 @@ public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindin
public ValidateMethodBindingDstu1(Method theMethod, FhirContext theContext, Object theProvider) { public ValidateMethodBindingDstu1(Method theMethod, FhirContext theContext, Object theProvider) {
super(theMethod, theContext, Validate.class, theProvider); super(theMethod, theContext, Validate.class, theProvider);
myIdParameterIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); myIdParameterIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
} }
@Override @Override
@ -57,40 +54,6 @@ public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindin
} }
} }
@Override
protected BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource theResource) {
FhirContext context = getContext();
IdDt idDt=null;
if (myIdParameterIndex != null) {
idDt = (IdDt) theArgs[myIdParameterIndex];
}
HttpPostClientInvocation retVal = createValidateInvocation(theResource, idDt, context);
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
}
return retVal;
}
public static HttpPostClientInvocation createValidateInvocation(IBaseResource theResource, IdDt theId, FhirContext theContext) {
StringBuilder urlExtension = new StringBuilder();
urlExtension.append(theContext.getResourceDefinition(theResource).getName());
urlExtension.append('/');
urlExtension.append(Constants.PARAM_VALIDATE);
if (theId != null && theId.isEmpty() == false) {
String id = theId.getValue();
urlExtension.append('/');
urlExtension.append(id);
}
// TODO: is post correct here?
HttpPostClientInvocation retVal = new HttpPostClientInvocation(theContext, theResource, urlExtension.toString());
return retVal;
}
@Override @Override

View File

@ -24,7 +24,6 @@ import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
@ -33,9 +32,6 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Validate; import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.util.ParametersUtil;
public class ValidateMethodBindingDstu2Plus extends OperationMethodBinding { public class ValidateMethodBindingDstu2Plus extends OperationMethodBinding {
@ -68,17 +64,4 @@ public class ValidateMethodBindingDstu2Plus extends OperationMethodBinding {
} }
public static BaseHttpClientInvocation createValidateInvocation(FhirContext theContext, IBaseResource theResource) {
IBaseParameters parameters = (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance();
ParametersUtil.addParameterToParameters(theContext, parameters, theResource, "resource");
String resourceName = theContext.getResourceDefinition(theResource).getName();
String resourceId = theResource.getIdElement().getIdPart();
BaseHttpClientInvocation retVal = createOperationInvocation(theContext, resourceName, resourceId, Constants.EXTOP_VALIDATE, parameters, false);
return retVal;
}
} }

View File

@ -21,23 +21,18 @@ package ca.uhn.fhir.rest.server.servlet;
*/ */
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.ByteArrayInputStream; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Collections; import java.util.*;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.entity.ContentType;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
@ -166,14 +161,26 @@ public class ServletRequestDetails extends RequestDetails {
@Override @Override
public Charset getCharset() { public Charset getCharset() {
String ct = getHeader(Constants.HEADER_CONTENT_TYPE);
Charset charset = null; Charset charset = null;
if (isNotBlank(ct)) {
ContentType parsedCt = ContentType.parse(ct); String charsetString = myServletResponse.getCharacterEncoding();
charset = parsedCt.getCharset(); if (isNotBlank(charsetString)) {
charset = Charset.forName(charsetString);
} }
// String ct = getHeader(Constants.HEADER_CONTENT_TYPE);
//
// if (isNotBlank(ct)) {
// ContentType parsedCt = ContentType.parse(ct);
// charset = parsedCt.getCharset();
// }
return charset; return charset;
} }
@Override
public FhirContext getFhirContext() {
return getServer().getFhirContext();
}
} }