Fix #19 - Now have a whitelist and a blacklist for parameter names
This commit is contained in:
parent
9217ee28bf
commit
c704aa185d
|
@ -70,6 +70,7 @@ import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
|
@ -156,36 +157,82 @@ public List<Patient> findPatients(
|
||||||
}
|
}
|
||||||
//END SNIPPET: underlyingReq
|
//END SNIPPET: underlyingReq
|
||||||
|
|
||||||
//START SNIPPET: reference
|
//START SNIPPET: referenceSimple
|
||||||
@Search
|
@Search
|
||||||
public List<Patient> findPatients(
|
public List<Patient> findPatientsWithSimpleReference(
|
||||||
@RequiredParam(name=Patient.SP_PROVIDER) ReferenceParam theProvider
|
@OptionalParam(name=Patient.SP_PROVIDER) ReferenceParam theProvider
|
||||||
) {
|
) {
|
||||||
|
List<Patient> retVal=new ArrayList<Patient>();
|
||||||
|
|
||||||
// May be populated with the resource type (e.g. "Patient") if the client requested one
|
// If the parameter passed in includes a resource type (e.g. ?provider:Patient=123)
|
||||||
String type = theProvider.getResourceType();
|
// that resoruce type is available. Here we just check that it is either not provided
|
||||||
|
// or set to "Patient"
|
||||||
|
if (theProvider.hasResourceType()) {
|
||||||
|
String resourceType = theProvider.getResourceType();
|
||||||
|
if ("Patient".equals(resourceType) == false) {
|
||||||
|
throw new InvalidRequestException("Invalid resource type for parameter 'provider': " + resourceType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// May be populated with the chain (e.g. "name") if the client requested one
|
if (theProvider != null) {
|
||||||
String chain = theProvider.getChain();
|
// ReferenceParam extends IdDt so all of the resource ID methods are available
|
||||||
|
String providerId = theProvider.getIdPart();
|
||||||
|
|
||||||
/* The actual parameter value. This will be the resource ID if no chain was provided,
|
// .. populate retVal will Patient resources having provider with id "providerId" ..
|
||||||
* but refers to the value of a specific property noted by the chain if one was given.
|
|
||||||
* For example, the following request:
|
}
|
||||||
* http://example.com/fhir/Patient?provider:Organization.name=FooOrg
|
|
||||||
* has a type of "Organization" and a chain of "name", meaning that
|
|
||||||
* the returned patients should have a provider which is an Organization
|
|
||||||
* with a name matching "FooOrg".
|
|
||||||
*/
|
|
||||||
String value = theProvider.getValue();
|
|
||||||
|
|
||||||
List<Patient> retVal=new ArrayList<Patient>(); // populate this
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
||||||
}
|
}
|
||||||
//END SNIPPET: reference
|
//END SNIPPET: referenceSimple
|
||||||
|
|
||||||
|
|
||||||
//START SNIPPET: referenceChain
|
//START SNIPPET: referenceWithChain
|
||||||
|
@Search
|
||||||
|
public List<DiagnosticReport> findReportsWithChain(
|
||||||
|
@RequiredParam(name=DiagnosticReport.SP_SUBJECT, chainWhitelist= {Patient.SP_FAMILY, Patient.SP_GENDER}) ReferenceParam theSubject
|
||||||
|
) {
|
||||||
|
List<DiagnosticReport> retVal=new ArrayList<DiagnosticReport>();
|
||||||
|
|
||||||
|
String chain = theSubject.getChain();
|
||||||
|
if (Patient.SP_FAMILY.equals(chain)) {
|
||||||
|
String familyName = theSubject.getValue();
|
||||||
|
// .. populate with reports matching subject family name ..
|
||||||
|
}
|
||||||
|
if (Patient.SP_GENDER.equals(chain)) {
|
||||||
|
String gender = theSubject.getValue();
|
||||||
|
// .. populate with reports matching subject gender ..
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
//END SNIPPET: referenceWithChain
|
||||||
|
|
||||||
|
|
||||||
|
//START SNIPPET: referenceWithChainCombo
|
||||||
|
@Search
|
||||||
|
public List<DiagnosticReport> findReportsWithChainCombo (
|
||||||
|
@RequiredParam(name=DiagnosticReport.SP_SUBJECT, chainWhitelist= {"", Patient.SP_FAMILY}) ReferenceParam theSubject
|
||||||
|
) {
|
||||||
|
List<DiagnosticReport> retVal=new ArrayList<DiagnosticReport>();
|
||||||
|
|
||||||
|
String chain = theSubject.getChain();
|
||||||
|
if (Patient.SP_FAMILY.equals(chain)) {
|
||||||
|
String familyName = theSubject.getValue();
|
||||||
|
// .. populate with reports matching subject family name ..
|
||||||
|
}
|
||||||
|
if ("".equals(chain)) {
|
||||||
|
String resourceId = theSubject.getValue();
|
||||||
|
// .. populate with reports matching subject with resource ID ..
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
//END SNIPPET: referenceWithChainCombo
|
||||||
|
|
||||||
|
|
||||||
|
//START SNIPPET: referenceWithStaticChain
|
||||||
@Search
|
@Search
|
||||||
public List<Patient> findObservations(
|
public List<Patient> findObservations(
|
||||||
@RequiredParam(name=Observation.SP_SUBJECT+'.'+Patient.SP_IDENTIFIER) TokenParam theProvider
|
@RequiredParam(name=Observation.SP_SUBJECT+'.'+Patient.SP_IDENTIFIER) TokenParam theProvider
|
||||||
|
@ -200,7 +247,7 @@ public List<Patient> findObservations(
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
||||||
}
|
}
|
||||||
//END SNIPPET: referenceChain
|
//END SNIPPET: referenceWithStaticChain
|
||||||
|
|
||||||
|
|
||||||
//START SNIPPET: read
|
//START SNIPPET: read
|
||||||
|
|
|
@ -39,6 +39,8 @@ public @interface OptionalParam {
|
||||||
|
|
||||||
public static final String ALLOW_CHAIN_ANY = "*";
|
public static final String ALLOW_CHAIN_ANY = "*";
|
||||||
|
|
||||||
|
public static final String ALLOW_CHAIN_NOTCHAINED = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For reference parameters ({@link ReferenceParam}) this value may be
|
* For reference parameters ({@link ReferenceParam}) this value may be
|
||||||
* used to indicate which chain values (if any) are <b>not</b> valid
|
* used to indicate which chain values (if any) are <b>not</b> valid
|
||||||
|
@ -54,10 +56,23 @@ public @interface OptionalParam {
|
||||||
/**
|
/**
|
||||||
* For reference parameters ({@link ReferenceParam}) this value may be
|
* For reference parameters ({@link ReferenceParam}) this value may be
|
||||||
* used to indicate which chain values (if any) are valid for the given
|
* used to indicate which chain values (if any) are valid for the given
|
||||||
* parameter. If the list contains the value {@link #ALLOW_CHAIN_ANY}, as is
|
* parameter. If the list contains the value {@link #ALLOW_CHAIN_ANY}, all values are valid. (this is the default)
|
||||||
* the default, all values are valid. Any values specified in
|
* If the list contains the value {@link #ALLOW_CHAIN_NOTCHAINED}
|
||||||
|
* then the reference param only supports the empty chain (i.e. the resource
|
||||||
|
* ID).
|
||||||
|
* <p>
|
||||||
|
* Valid values for this parameter include:
|
||||||
|
* <ul>
|
||||||
|
* <li><code>chainWhitelist={ OptionalParam.ALLOW_CHAIN_NOTCHAINED }</code> - Only allow resource reference (no chaining allowed for this parameter)</li>
|
||||||
|
* <li><code>chainWhitelist={ OptionalParam.ALLOW_CHAIN_ANY }</code> - Allow any chaining at all (including a non chained value, <b>this is the default</b>)</li>
|
||||||
|
* <li><code>chainWhitelist={ "foo", "bar" }</code> - Allow property.foo and property.bar</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Any values specified in
|
||||||
* {@link #chainBlacklist()} will supercede (have priority over) values
|
* {@link #chainBlacklist()} will supercede (have priority over) values
|
||||||
* here.
|
* here.
|
||||||
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* If the parameter annotated with this annotation is not a {@link ReferenceParam},
|
* If the parameter annotated with this annotation is not a {@link ReferenceParam},
|
||||||
* this value must not be populated.
|
* this value must not be populated.
|
||||||
|
|
|
@ -35,60 +35,67 @@ import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
* Parameter annotation which specifies a search parameter for a {@link Search} method.
|
* Parameter annotation which specifies a search parameter for a {@link Search} method.
|
||||||
*/
|
*/
|
||||||
public @interface RequiredParam {
|
public @interface RequiredParam {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For reference parameters ({@link ReferenceParam}) this value may be used to indicate which chain values (if any)
|
* For reference parameters ({@link ReferenceParam}) this value may be used to indicate which chain values (if any) are <b>not</b> valid for the given parameter. Values here will supercede any
|
||||||
* are <b>not</b> valid for the given parameter. Values here will supercede any values specified in
|
* values specified in {@link #chainWhitelist()}
|
||||||
* {@link #chainWhitelist()}
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the parameter annotated with this annotation is not a {@link ReferenceParam}, this value must not be
|
* If the parameter annotated with this annotation is not a {@link ReferenceParam}, this value must not be populated.
|
||||||
* populated.
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
String[] chainBlacklist() default {};
|
String[] chainBlacklist() default {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For reference parameters ({@link ReferenceParam}) this value may be used to indicate which chain values (if any)
|
* For reference parameters ({@link ReferenceParam}) this value may be
|
||||||
* are valid for the given parameter. If the list contains the value {@link OptionalParam#ALLOW_CHAIN_ANY}, as is
|
* used to indicate which chain values (if any) are valid for the given
|
||||||
* the default, all values are valid. Any values specified in {@link #chainBlacklist()} will supercede (have
|
* parameter. If the list contains the value {@link OptionalParam#ALLOW_CHAIN_ANY}, all values are valid. (this is the default)
|
||||||
* priority over) values here.
|
* If the list contains the value {@link OptionalParam#ALLOW_CHAIN_NOTCHAINED}
|
||||||
|
* then the reference param only supports the empty chain (i.e. the resource
|
||||||
|
* ID).
|
||||||
* <p>
|
* <p>
|
||||||
* If the parameter annotated with this annotation is not a {@link ReferenceParam}, this value must not be
|
* Valid values for this parameter include:
|
||||||
* populated.
|
* <ul>
|
||||||
|
* <li><code>chainWhitelist={ OptionalParam.ALLOW_CHAIN_NOTCHAINED }</code> - Only allow resource reference (no chaining allowed for this parameter)</li>
|
||||||
|
* <li><code>chainWhitelist={ OptionalParam.ALLOW_CHAIN_ANY }</code> - Allow any chaining at all (including a non chained value, <b>this is the default</b>)</li>
|
||||||
|
* <li><code>chainWhitelist={ "foo", "bar" }</code> - Allow property.foo and property.bar</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Any values specified in
|
||||||
|
* {@link #chainBlacklist()} will supercede (have priority over) values
|
||||||
|
* here.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* If the parameter annotated with this annotation is not a {@link ReferenceParam},
|
||||||
|
* this value must not be populated.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
String[] chainWhitelist() default {OptionalParam.ALLOW_CHAIN_ANY};
|
String[] chainWhitelist() default {OptionalParam.ALLOW_CHAIN_ANY};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For composite parameters ({@link CompositeParam}) this parameter may be used to indicate the parameter type(s)
|
* For composite parameters ({@link CompositeParam}) this parameter may be used to indicate the parameter type(s) which may be referenced by this param.
|
||||||
* which may be referenced by this param.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the parameter annotated with this annotation is not a {@link CompositeParam}, this value must not be
|
* If the parameter annotated with this annotation is not a {@link CompositeParam}, this value must not be populated.
|
||||||
* populated.
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
Class<? extends IQueryParameterType>[] compositeTypes() default {};
|
Class<? extends IQueryParameterType>[] compositeTypes() default {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the name for the parameter. Generally this should be a simple string (e.g. "name", or "identifier") which
|
* This is the name for the parameter. Generally this should be a simple string (e.g. "name", or "identifier") which will be the name of the URL parameter used to populate this method parameter.
|
||||||
* will be the name of the URL parameter used to populate this method parameter.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Most resource model classes have constants which may be used to supply values for this field, e.g.
|
* Most resource model classes have constants which may be used to supply values for this field, e.g. {@link Patient#SP_NAME} or {@link Observation#SP_DATE}
|
||||||
* {@link Patient#SP_NAME} or {@link Observation#SP_DATE}
|
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* If you wish to specify a parameter for a resource reference which only accepts a specific chained value, it is
|
* If you wish to specify a parameter for a resource reference which only accepts a specific chained value, it is also valid to supply a chained name here, such as "patient.name". It is
|
||||||
* also valid to supply a chained name here, such as "patient.name". It is recommended to supply this using
|
* recommended to supply this using constants where possible, e.g. <code>{@link Observation#SP_SUBJECT} + '.' + {@link Patient#SP_IDENTIFIER}</code>
|
||||||
* constants where possible, e.g. <code>{@link Observation#SP_SUBJECT} + '.' + {@link Patient#SP_IDENTIFIER}</code>
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
String name();
|
String name();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For resource reference parameters ({@link ReferenceParam}) this parameter may be used to indicate the resource
|
* For resource reference parameters ({@link ReferenceParam}) this parameter may be used to indicate the resource type(s) which may be referenced by this param.
|
||||||
* type(s) which may be referenced by this param.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the parameter annotated with this annotation is not a {@link ReferenceParam}, this value must not be
|
* If the parameter annotated with this annotation is not a {@link ReferenceParam}, this value must not be populated.
|
||||||
* populated.
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
Class<? extends IResource>[] targetTypes() default {};
|
Class<? extends IResource>[] targetTypes() default {};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ca.uhn.fhir.rest.method;
|
package ca.uhn.fhir.rest.method;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PushbackReader;
|
import java.io.PushbackReader;
|
||||||
|
@ -18,13 +19,10 @@ import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.swing.text.html.Option;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.http.client.utils.DateUtils;
|
import org.apache.http.client.utils.DateUtils;
|
||||||
|
|
||||||
import com.google.common.base.Optional;
|
|
||||||
|
|
||||||
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.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
|
|
@ -41,6 +41,7 @@ import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||||
import ca.uhn.fhir.rest.annotation.Search;
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||||
import ca.uhn.fhir.rest.param.BaseQueryParameter;
|
import ca.uhn.fhir.rest.param.BaseQueryParameter;
|
||||||
|
@ -84,7 +85,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
* Check for parameter combinations and names that are invalid
|
* Check for parameter combinations and names that are invalid
|
||||||
*/
|
*/
|
||||||
List<IParameter> parameters = getParameters();
|
List<IParameter> parameters = getParameters();
|
||||||
List<SearchParameter> searchParameters = new ArrayList<SearchParameter>();
|
// List<SearchParameter> searchParameters = new ArrayList<SearchParameter>();
|
||||||
for (int i = 0; i < parameters.size(); i++) {
|
for (int i = 0; i < parameters.size(); i++) {
|
||||||
IParameter next = parameters.get(i);
|
IParameter next = parameters.get(i);
|
||||||
if (!(next instanceof SearchParameter)) {
|
if (!(next instanceof SearchParameter)) {
|
||||||
|
@ -94,17 +95,18 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
SearchParameter sp = (SearchParameter) next;
|
SearchParameter sp = (SearchParameter) next;
|
||||||
if (sp.getName().startsWith("_")) {
|
if (sp.getName().startsWith("_")) {
|
||||||
if (ALLOWED_PARAMS.contains(sp.getName())) {
|
if (ALLOWED_PARAMS.contains(sp.getName())) {
|
||||||
String msg = getContext().getLocalizer().getMessage(getClass().getName() + ".invalidSpecialParamName", theMethod.getName(), theMethod.getDeclaringClass().getSimpleName(), sp.getName());
|
String msg = getContext().getLocalizer().getMessage(getClass().getName() + ".invalidSpecialParamName", theMethod.getName(), theMethod.getDeclaringClass().getSimpleName(),
|
||||||
|
sp.getName());
|
||||||
throw new ConfigurationException(msg);
|
throw new ConfigurationException(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
searchParameters.add(sp);
|
// searchParameters.add(sp);
|
||||||
}
|
|
||||||
for (int i = 0; i < searchParameters.size(); i++) {
|
|
||||||
SearchParameter next = searchParameters.get(i);
|
|
||||||
// next.
|
|
||||||
}
|
}
|
||||||
|
// for (int i = 0; i < searchParameters.size(); i++) {
|
||||||
|
// SearchParameter next = searchParameters.get(i);
|
||||||
|
// // next.
|
||||||
|
// }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only compartment searching methods may have an ID parameter
|
* Only compartment searching methods may have an ID parameter
|
||||||
|
@ -291,16 +293,36 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
ArrayList<String> retVal = new ArrayList<String>(theQualifiedNames.size());
|
ArrayList<String> retVal = new ArrayList<String>(theQualifiedNames.size());
|
||||||
for (String next : theQualifiedNames) {
|
for (String next : theQualifiedNames) {
|
||||||
String qualifier = "";
|
String qualifier = "";
|
||||||
int idx = next.indexOf('.');
|
|
||||||
if (idx > -1 && next.length() > (idx + 1)) {
|
int start = -1;
|
||||||
qualifier = next.substring(idx);
|
int end = -1;
|
||||||
|
for (int idx = 0; idx < next.length(); idx++) {
|
||||||
|
char nextChar = next.charAt(idx);
|
||||||
|
if (nextChar == '.' || nextChar == ':') {
|
||||||
|
if (start == -1) {
|
||||||
|
start = idx;
|
||||||
|
} else {
|
||||||
|
end = idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start != -1) {
|
||||||
|
if (end != -1) {
|
||||||
|
qualifier = next.substring(start, end);
|
||||||
|
} else {
|
||||||
|
qualifier = next.substring(start);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theQualifierWhitelist != null) {
|
if (theQualifierWhitelist != null) {
|
||||||
|
if (!theQualifierWhitelist.contains(OptionalParam.ALLOW_CHAIN_ANY)) {
|
||||||
if (!theQualifierWhitelist.contains(qualifier)) {
|
if (!theQualifierWhitelist.contains(qualifier)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (theQualifierBlacklist != null) {
|
if (theQualifierBlacklist != null) {
|
||||||
if (theQualifierBlacklist.contains(qualifier)) {
|
if (theQualifierBlacklist.contains(qualifier)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -311,7 +333,8 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName, SearchStyleEnum theSearchStyle) {
|
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName,
|
||||||
|
SearchStyleEnum theSearchStyle) {
|
||||||
SearchStyleEnum searchStyle = theSearchStyle;
|
SearchStyleEnum searchStyle = theSearchStyle;
|
||||||
if (searchStyle == null) {
|
if (searchStyle == null) {
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
@ -342,8 +365,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Are we doing a get (GET [base]/Patient?name=foo) or a get with search (GET [base]/Patient/_search?name=foo)
|
* 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)
|
||||||
* or a post (POST [base]/Patient with parameters in the POST body)
|
|
||||||
*/
|
*/
|
||||||
switch (searchStyle) {
|
switch (searchStyle) {
|
||||||
case GET:
|
case GET:
|
||||||
|
|
|
@ -68,8 +68,10 @@ import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
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.CollectionUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by dsotnikov on 2/25/2014.
|
* Created by dsotnikov on 2/25/2014.
|
||||||
|
@ -77,38 +79,49 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class SearchParameter extends BaseQueryParameter {
|
public class SearchParameter extends BaseQueryParameter {
|
||||||
|
|
||||||
|
private static final String EMPTY_STRING = "";
|
||||||
private static HashMap<Class<?>, SearchParamTypeEnum> ourParamTypes;
|
private static HashMap<Class<?>, SearchParamTypeEnum> ourParamTypes;
|
||||||
|
private static HashMap<SearchParamTypeEnum, Set<String>> ourParamQualifiers;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ourParamTypes = new HashMap<Class<?>, SearchParamTypeEnum>();
|
ourParamTypes = new HashMap<Class<?>, SearchParamTypeEnum>();
|
||||||
|
ourParamQualifiers = new HashMap<SearchParamTypeEnum, Set<String>>();
|
||||||
|
|
||||||
ourParamTypes.put(StringParam.class, SearchParamTypeEnum.STRING);
|
ourParamTypes.put(StringParam.class, SearchParamTypeEnum.STRING);
|
||||||
ourParamTypes.put(StringOrListParam.class, SearchParamTypeEnum.STRING);
|
ourParamTypes.put(StringOrListParam.class, SearchParamTypeEnum.STRING);
|
||||||
ourParamTypes.put(StringAndListParam.class, SearchParamTypeEnum.STRING);
|
ourParamTypes.put(StringAndListParam.class, SearchParamTypeEnum.STRING);
|
||||||
|
ourParamQualifiers.put(SearchParamTypeEnum.STRING, CollectionUtil.newSet(Constants.PARAMQUALIFIER_STRING_EXACT, Constants.PARAMQUALIFIER_MISSING, EMPTY_STRING));
|
||||||
|
|
||||||
ourParamTypes.put(TokenParam.class, SearchParamTypeEnum.TOKEN);
|
ourParamTypes.put(TokenParam.class, SearchParamTypeEnum.TOKEN);
|
||||||
ourParamTypes.put(TokenOrListParam.class, SearchParamTypeEnum.TOKEN);
|
ourParamTypes.put(TokenOrListParam.class, SearchParamTypeEnum.TOKEN);
|
||||||
ourParamTypes.put(TokenAndListParam.class, SearchParamTypeEnum.TOKEN);
|
ourParamTypes.put(TokenAndListParam.class, SearchParamTypeEnum.TOKEN);
|
||||||
|
ourParamQualifiers.put(SearchParamTypeEnum.TOKEN, CollectionUtil.newSet(Constants.PARAMQUALIFIER_TOKEN_TEXT, Constants.PARAMQUALIFIER_MISSING, EMPTY_STRING));
|
||||||
|
|
||||||
ourParamTypes.put(DateParam.class, SearchParamTypeEnum.DATE);
|
ourParamTypes.put(DateParam.class, SearchParamTypeEnum.DATE);
|
||||||
ourParamTypes.put(DateOrListParam.class, SearchParamTypeEnum.DATE);
|
ourParamTypes.put(DateOrListParam.class, SearchParamTypeEnum.DATE);
|
||||||
ourParamTypes.put(DateAndListParam.class, SearchParamTypeEnum.DATE);
|
ourParamTypes.put(DateAndListParam.class, SearchParamTypeEnum.DATE);
|
||||||
ourParamTypes.put(DateRangeParam.class, SearchParamTypeEnum.DATE);
|
ourParamTypes.put(DateRangeParam.class, SearchParamTypeEnum.DATE);
|
||||||
|
ourParamQualifiers.put(SearchParamTypeEnum.DATE, CollectionUtil.newSet(Constants.PARAMQUALIFIER_MISSING, EMPTY_STRING));
|
||||||
|
|
||||||
ourParamTypes.put(QuantityParam.class, SearchParamTypeEnum.QUANTITY);
|
ourParamTypes.put(QuantityParam.class, SearchParamTypeEnum.QUANTITY);
|
||||||
ourParamTypes.put(QuantityOrListParam.class, SearchParamTypeEnum.QUANTITY);
|
ourParamTypes.put(QuantityOrListParam.class, SearchParamTypeEnum.QUANTITY);
|
||||||
ourParamTypes.put(QuantityAndListParam.class, SearchParamTypeEnum.QUANTITY);
|
ourParamTypes.put(QuantityAndListParam.class, SearchParamTypeEnum.QUANTITY);
|
||||||
|
ourParamQualifiers.put(SearchParamTypeEnum.QUANTITY, CollectionUtil.newSet(Constants.PARAMQUALIFIER_MISSING, EMPTY_STRING));
|
||||||
|
|
||||||
ourParamTypes.put(NumberParam.class, SearchParamTypeEnum.NUMBER);
|
ourParamTypes.put(NumberParam.class, SearchParamTypeEnum.NUMBER);
|
||||||
ourParamTypes.put(NumberOrListParam.class, SearchParamTypeEnum.NUMBER);
|
ourParamTypes.put(NumberOrListParam.class, SearchParamTypeEnum.NUMBER);
|
||||||
ourParamTypes.put(NumberAndListParam.class, SearchParamTypeEnum.NUMBER);
|
ourParamTypes.put(NumberAndListParam.class, SearchParamTypeEnum.NUMBER);
|
||||||
|
ourParamQualifiers.put(SearchParamTypeEnum.NUMBER, CollectionUtil.newSet(Constants.PARAMQUALIFIER_MISSING, EMPTY_STRING));
|
||||||
|
|
||||||
ourParamTypes.put(ReferenceParam.class, SearchParamTypeEnum.REFERENCE);
|
ourParamTypes.put(ReferenceParam.class, SearchParamTypeEnum.REFERENCE);
|
||||||
ourParamTypes.put(ReferenceOrListParam.class, SearchParamTypeEnum.REFERENCE);
|
ourParamTypes.put(ReferenceOrListParam.class, SearchParamTypeEnum.REFERENCE);
|
||||||
ourParamTypes.put(ReferenceAndListParam.class, SearchParamTypeEnum.REFERENCE);
|
ourParamTypes.put(ReferenceAndListParam.class, SearchParamTypeEnum.REFERENCE);
|
||||||
|
ourParamQualifiers.put(SearchParamTypeEnum.REFERENCE, CollectionUtil.newSet(Constants.PARAMQUALIFIER_MISSING)); // no empty because that gets added from OptionalParam#chainWhitelist
|
||||||
|
|
||||||
ourParamTypes.put(CompositeParam.class, SearchParamTypeEnum.COMPOSITE);
|
ourParamTypes.put(CompositeParam.class, SearchParamTypeEnum.COMPOSITE);
|
||||||
ourParamTypes.put(CompositeOrListParam.class, SearchParamTypeEnum.COMPOSITE);
|
ourParamTypes.put(CompositeOrListParam.class, SearchParamTypeEnum.COMPOSITE);
|
||||||
ourParamTypes.put(CompositeAndListParam.class, SearchParamTypeEnum.COMPOSITE);
|
ourParamTypes.put(CompositeAndListParam.class, SearchParamTypeEnum.COMPOSITE);
|
||||||
|
ourParamQualifiers.put(SearchParamTypeEnum.COMPOSITE, CollectionUtil.newSet(Constants.PARAMQUALIFIER_MISSING, EMPTY_STRING));
|
||||||
}
|
}
|
||||||
private Set<String> myQualifierBlacklist;
|
private Set<String> myQualifierBlacklist;
|
||||||
private Set<String> myQualifierWhitelist;
|
private Set<String> myQualifierWhitelist;
|
||||||
|
@ -205,12 +218,12 @@ public class SearchParameter extends BaseQueryParameter {
|
||||||
|
|
||||||
public void setChainlists(String[] theChainWhitelist, String[] theChainBlacklist) {
|
public void setChainlists(String[] theChainWhitelist, String[] theChainBlacklist) {
|
||||||
myQualifierWhitelist = new HashSet<String>(theChainWhitelist.length);
|
myQualifierWhitelist = new HashSet<String>(theChainWhitelist.length);
|
||||||
|
|
||||||
for (int i = 0; i < theChainWhitelist.length; i++) {
|
for (int i = 0; i < theChainWhitelist.length; i++) {
|
||||||
if (theChainWhitelist[i].equals(OptionalParam.ALLOW_CHAIN_ANY)) {
|
if (theChainWhitelist[i].equals(OptionalParam.ALLOW_CHAIN_ANY)) {
|
||||||
myQualifierWhitelist = null;
|
myQualifierWhitelist.add(OptionalParam.ALLOW_CHAIN_ANY);
|
||||||
break;
|
} else if (theChainWhitelist[i].equals(EMPTY_STRING)) {
|
||||||
} else if (theChainWhitelist[i].equals("")) {
|
myQualifierWhitelist.add(EMPTY_STRING);
|
||||||
myQualifierWhitelist.add("");
|
|
||||||
} else {
|
} else {
|
||||||
myQualifierWhitelist.add('.' + theChainWhitelist[i]);
|
myQualifierWhitelist.add('.' + theChainWhitelist[i]);
|
||||||
}
|
}
|
||||||
|
@ -219,8 +232,8 @@ public class SearchParameter extends BaseQueryParameter {
|
||||||
if (theChainBlacklist.length > 0) {
|
if (theChainBlacklist.length > 0) {
|
||||||
myQualifierBlacklist = new HashSet<String>(theChainBlacklist.length);
|
myQualifierBlacklist = new HashSet<String>(theChainBlacklist.length);
|
||||||
for (String next : theChainBlacklist) {
|
for (String next : theChainBlacklist) {
|
||||||
if (next.equals("")) {
|
if (next.equals(EMPTY_STRING)) {
|
||||||
myQualifierBlacklist.add("");
|
myQualifierBlacklist.add(EMPTY_STRING);
|
||||||
} else {
|
} else {
|
||||||
myQualifierBlacklist.add('.' + next);
|
myQualifierBlacklist.add('.' + next);
|
||||||
}
|
}
|
||||||
|
@ -264,8 +277,23 @@ public class SearchParameter extends BaseQueryParameter {
|
||||||
throw new ConfigurationException("Unsupported data type for parameter: " + type.getCanonicalName());
|
throw new ConfigurationException("Unsupported data type for parameter: " + type.getCanonicalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SearchParamTypeEnum typeEnum = ourParamTypes.get(type);
|
||||||
|
if (typeEnum != null) {
|
||||||
|
Set<String> builtInQualifiers = ourParamQualifiers.get(typeEnum);
|
||||||
|
if (builtInQualifiers != null) {
|
||||||
|
if (myQualifierWhitelist != null) {
|
||||||
|
HashSet<String> qualifierWhitelist = new HashSet<String>();
|
||||||
|
qualifierWhitelist.addAll(myQualifierWhitelist);
|
||||||
|
qualifierWhitelist.addAll(builtInQualifiers);
|
||||||
|
myQualifierWhitelist = qualifierWhitelist;
|
||||||
|
} else {
|
||||||
|
myQualifierWhitelist = Collections.unmodifiableSet(builtInQualifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (myParamType == null) {
|
if (myParamType == null) {
|
||||||
myParamType = ourParamTypes.get(type);
|
myParamType = typeEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myParamType != null) {
|
if (myParamType != null) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||||
import ca.uhn.fhir.rest.method.IParameter;
|
import ca.uhn.fhir.rest.method.IParameter;
|
||||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||||
|
@ -52,15 +53,15 @@ public abstract class BaseQueryParameter implements IParameter {
|
||||||
public abstract boolean isRequired();
|
public abstract boolean isRequired();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameter should return true if {@link #parse(List)} should be called even if the query string contained no
|
* Parameter should return true if {@link #parse(List)} should be called even if the query string contained no values for the given parameter
|
||||||
* values for the given parameter
|
|
||||||
*/
|
*/
|
||||||
public abstract boolean handlesMissing();
|
public abstract boolean handlesMissing();
|
||||||
|
|
||||||
public abstract SearchParamTypeEnum getParamType();
|
public abstract SearchParamTypeEnum getParamType();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, BaseHttpClientInvocation theClientInvocation) throws InternalErrorException {
|
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments,
|
||||||
|
BaseHttpClientInvocation theClientInvocation) throws InternalErrorException {
|
||||||
if (theSourceClientArgument == null) {
|
if (theSourceClientArgument == null) {
|
||||||
if (isRequired()) {
|
if (isRequired()) {
|
||||||
throw new NullPointerException("SearchParameter '" + getName() + "' is required and may not be null");
|
throw new NullPointerException("SearchParameter '" + getName() + "' is required and may not be null");
|
||||||
|
@ -117,10 +118,12 @@ public abstract class BaseQueryParameter implements IParameter {
|
||||||
|
|
||||||
private void parseParams(RequestDetails theRequest, List<QualifiedParamList> paramList, String theQualifiedParamName, String theQualifier) {
|
private void parseParams(RequestDetails theRequest, List<QualifiedParamList> paramList, String theQualifiedParamName, String theQualifier) {
|
||||||
if (getQualifierWhitelist() != null) {
|
if (getQualifierWhitelist() != null) {
|
||||||
|
if (!getQualifierWhitelist().contains(OptionalParam.ALLOW_CHAIN_ANY)) {
|
||||||
if (!getQualifierWhitelist().contains(defaultString(theQualifier))) {
|
if (!getQualifierWhitelist().contains(defaultString(theQualifier))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (getQualifierBlacklist() != null) {
|
if (getQualifierBlacklist() != null) {
|
||||||
if (getQualifierBlacklist().contains(defaultString(theQualifier))) {
|
if (getQualifierBlacklist().contains(defaultString(theQualifier))) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CollectionUtil {
|
||||||
|
|
||||||
|
public static <T> Set<T> newSet(T... theValues) {
|
||||||
|
HashSet<T> retVal = new HashSet<T>();
|
||||||
|
|
||||||
|
for (T t : theValues) {
|
||||||
|
retVal.add(t);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -682,35 +682,54 @@
|
||||||
<p>
|
<p>
|
||||||
Reference parameters use the
|
Reference parameters use the
|
||||||
<a href="./apidocs/ca/uhn/fhir/rest/param/ReferenceParam.html">ReferenceParam</a>
|
<a href="./apidocs/ca/uhn/fhir/rest/param/ReferenceParam.html">ReferenceParam</a>
|
||||||
type. Reference param objects being passed into server methods will have three properties
|
type. Reference parameters are, in their most basic form, just a pointer to another
|
||||||
populated:
|
resource. For example, you might want to query for DiagnosticReport resources where the
|
||||||
|
subject (the Patient resource that the report is about) is Patient/123. The following
|
||||||
|
example shows a simple resource reference parameter in use.
|
||||||
|
</p>
|
||||||
|
<macro name="snippet">
|
||||||
|
<param name="id" value="referenceSimple" />
|
||||||
|
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
||||||
|
</macro>
|
||||||
|
|
||||||
|
|
||||||
|
<h4>Chained Resource References</h4>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
References may also support a "chained" value. This is a search parameter name
|
||||||
|
on the target resource. For example, you might want to search for DiagnosticReport
|
||||||
|
resources by subject, but use the subject's last name instead of their resource ID.
|
||||||
|
In this example, you are chaining "family" (the last name) to "subject" (the patient).
|
||||||
|
The net result in the query string would look like:<br/>
|
||||||
|
<code>http://fhir.example.com/DiagnosticReport?subject.family=SMITH</code>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Chained values must be explicitly declared through the use
|
||||||
|
of a whitelist (or blacklist). The following example shows how to declare a
|
||||||
|
report with an allowable chained parameter:
|
||||||
|
</p>
|
||||||
|
<macro name="snippet">
|
||||||
|
<param name="id" value="referenceWithChain" />
|
||||||
|
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
||||||
|
</macro>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You may also specify the whitelist value of
|
||||||
|
<code>""</code> to allow an empty chain (e.g. ther resource ID)
|
||||||
|
and this can be combined with other values, as shown below:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<b>The resource type (optional):</b> This is the type of resource
|
|
||||||
being targeted, if the client specifies one in the URL.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>The chain property (optional):</b> This is the name of the
|
|
||||||
property on the target resource to search for
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<b>The value (required):</b> This is the actual value to search for. If
|
|
||||||
a chain property has not been specified, this is the ID of the resource.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<macro name="snippet">
|
<macro name="snippet">
|
||||||
<param name="id" value="reference" />
|
<param name="id" value="referenceWithChainCombo" />
|
||||||
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
||||||
</macro>
|
</macro>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Example URLs to invoke this method:
|
Example URLs to invoke this method:
|
||||||
<br />
|
<br />
|
||||||
Resource by ID: <code>http://fhir.example.com/Patient?provider=1234</code>
|
Resource by ID: <code>http://fhir.example.com/DiagnosticReport?subject=1234</code>
|
||||||
<br />
|
<br />
|
||||||
Resource by chained parameter value: <code>http://fhir.example.com/Patient?provider:Organization.name=FooOrg</code>
|
Resource by chained parameter value: <code>http://fhir.example.com/DiagnosticReport?subject.family=SMITH</code>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>Static Chains</h4>
|
<h4>Static Chains</h4>
|
||||||
|
@ -724,7 +743,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<macro name="snippet">
|
<macro name="snippet">
|
||||||
<param name="id" value="referenceChain" />
|
<param name="id" value="referenceWithStaticChain" />
|
||||||
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
<param name="file" value="examples/src/main/java/example/RestfulPatientResourceProviderMore.java" />
|
||||||
</macro>
|
</macro>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -221,7 +221,9 @@ public class ReferenceParameterTest {
|
||||||
ServletHandler proxyHandler = new ServletHandler();
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
RestfulServer servlet = new RestfulServer();
|
RestfulServer servlet = new RestfulServer();
|
||||||
ourCtx = servlet.getFhirContext();
|
ourCtx = servlet.getFhirContext();
|
||||||
servlet.setResourceProviders(patientProvider, new DummyOrganizationResourceProvider());
|
servlet.setResourceProviders(patientProvider
|
||||||
|
, new DummyOrganizationResourceProvider()
|
||||||
|
);
|
||||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
ourServer.setHandler(proxyHandler);
|
ourServer.setHandler(proxyHandler);
|
||||||
|
|
|
@ -174,7 +174,7 @@ public class StringParameterTest {
|
||||||
public static class DummyPatientResourceProvider implements IResourceProvider {
|
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||||
|
|
||||||
@Search
|
@Search
|
||||||
public List<Patient> findPatient(@RequiredParam(name = "str") StringParam theParam) {
|
public List<Patient> findPatientByStringParam(@RequiredParam(name = "str") StringParam theParam) {
|
||||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
|
||||||
if (theParam.isExact() && theParam.getValue().equals("aaa")) {
|
if (theParam.isExact() && theParam.getValue().equals("aaa")) {
|
||||||
|
@ -192,7 +192,7 @@ public class StringParameterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Search
|
@Search
|
||||||
public List<Patient> findPatient(@RequiredParam(name = "plain") String theParam) {
|
public List<Patient> findPatientByString(@RequiredParam(name = "plain") String theParam) {
|
||||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
|
||||||
if (theParam.toLowerCase().equals("aaa")) {
|
if (theParam.toLowerCase().equals("aaa")) {
|
||||||
|
|
Loading…
Reference in New Issue