Merge branch 'master' of https://github.com/jamesagnew/hapi-fhir into jaxrs-sever-evolution

This commit is contained in:
Sebastien Riviere 2017-04-12 09:33:10 +02:00
commit dc50e5416d
22 changed files with 194 additions and 11 deletions

View File

@ -195,7 +195,7 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
*/
public TimeZone getTimeZone() {
if (myTimeZoneZulu) {
return TimeZone.getTimeZone("Z");
return TimeZone.getTimeZone("GMT");
}
return myTimeZone;
}

View File

@ -1778,6 +1778,15 @@ class ParserState<T> {
push(newState);
return;
}
case CONTAINED_RESOURCES:
case CONTAINED_RESOURCE_LIST:
case EXTENSION_DECLARED:
case PRIMITIVE_XHTML:
case PRIMITIVE_XHTML_HL7ORG:
case RESOURCE:
case RESOURCE_BLOCK:
case UNDECL_EXT:
break;
}
}

View File

@ -143,6 +143,9 @@ public class DynamicSearchParameter implements IParameter {
uriOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, uriOrListParam);
break;
case HAS:
// Should not happen
break;
}
}
}

View File

@ -306,6 +306,7 @@ public class MethodUtil {
return index;
}
@SuppressWarnings("GetClassOnAnnotation")
public static Integer findParamAnnotationIndex(Method theMethod, Class<?> toFind) {
int paramIndex = 0;
for (Annotation[] annotations : theMethod.getParameterAnnotations()) {

View File

@ -213,7 +213,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
qualifiedNames = processWhitelistAndBlacklist(qualifiedNames, temp.getQualifierWhitelist(), temp.getQualifierBlacklist());
methodParamsTemp.addAll(qualifiedNames);
}
if (!qualifiedParamNames.contains(name) && !qualifiedParamNames.contains(name)) {
if (!qualifiedParamNames.contains(name)) {
methodParamsTemp.add(name);
}
}

View File

@ -201,7 +201,11 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
case GREATERTHAN_OR_EQUALS:
break;
case LESSTHAN:
case APPROXIMATE:
case LESSTHAN_OR_EQUALS:
case ENDS_BEFORE:
case NOT_EQUAL:
case STARTS_AFTER:
throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getPrefix());
}
}
@ -229,6 +233,10 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
break;
case GREATERTHAN_OR_EQUALS:
case GREATERTHAN:
case APPROXIMATE:
case ENDS_BEFORE:
case NOT_EQUAL:
case STARTS_AFTER:
throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getPrefix());
}
}

View File

@ -24,7 +24,24 @@ import ca.uhn.fhir.util.CoverageIgnore;
*/
/**
* Represents an <b>HTTP 401 Client Unauthorized</b> response, which means that the client needs to provide credentials, or has provided invalid credentials.
* Represents an <b>HTTP 401 Client Unauthorized</b> response, which
* means that the client needs to provide credentials, or has
* provided invalid credentials.
* <p>
* For security failures, you should use
* {@link AuthenticationException} if you want to indicate that the
* user could not be authenticated (e.g. credential failures), also
* known as an <b>authentication</b> failure.
* You should use {@link ForbiddenOperationException} if you want to
* indicate that the authenticated user does not have permission to
* perform the requested operation, also known as an <b>authorization</b>
* failure.
* </p>
* <p>
* Note that a complete list of RESTful exceptions is available in the <a href="./package-summary.html">Package
* Summary</a>.
* </p>
*/
@CoverageIgnore
public class AuthenticationException extends BaseServerResponseException {

View File

@ -33,6 +33,16 @@ import ca.uhn.fhir.util.CoverageIgnore;
* </ul>
*
* <p>
* For security failures, you should use
* {@link AuthenticationException} if you want to indicate that the
* user could not be authenticated (e.g. credential failures), also
* known as an <b>authentication</b> failure.
* You should use {@link ForbiddenOperationException} if you want to
* indicate that the authenticated user does not have permission to
* perform the requested operation, also known as an <b>authorization</b>
* failure.
* </p>
* <p>
* Note that a complete list of RESTful exceptions is available in the <a href="./package-summary.html">Package
* Summary</a>.
* </p>

View File

@ -110,7 +110,7 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
b.append(nextChar);
b.append("</span>");
inValue = false;
} else if (nextChar == '}' || nextChar == '}' || nextChar == ',') {
} else if (nextChar == '{' || nextChar == '}' || nextChar == ',') {
b.append("<span class='hlControl'>");
b.append(nextChar);
b.append("</span>");

View File

@ -50,6 +50,7 @@ public class RuleImplConditional extends BaseRule implements IAuthRule {
if (theOperation == myOperationType) {
switch (myAppliesTo) {
case ALL_RESOURCES:
case INSTANCES:
break;
case TYPES:
if (theInputResource == null || !myAppliesToTypes.contains(theInputResource.getClass())) {

View File

@ -109,6 +109,10 @@ public class RunServerCommand extends BaseCommand {
case DSTU3:
theSce.getServletContext().setInitParameter(ContextLoader.CONFIG_LOCATION_PARAM, FhirServerConfigDstu3.class.getName());
break;
case DSTU1:
case DSTU2_1:
case DSTU2_HL7ORG:
break;
}
cll.contextInitialized(theSce);
}

View File

@ -909,12 +909,19 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
updateEntity(theResource, theEntity, null, true, false, theEntity.getUpdatedDate());
}
@Override
public void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm) {
removeTag(theId, theTagType, theScheme, theTerm, null);
}
@Override
public void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, RequestDetails theRequestDetails) {
// Notify interceptors
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theId);
notifyInterceptors(RestOperationTypeEnum.DELETE_TAGS, requestDetails);
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theId);
notifyInterceptors(RestOperationTypeEnum.DELETE_TAGS, requestDetails);
}
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theId);
if (entity == null) {

View File

@ -447,6 +447,8 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
entriesToProcess.put(nextRespEntry, outcome.getEntity());
break;
}
case GET:
break;
}
}

View File

@ -170,7 +170,9 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
*/
void reindex(T theResource, ResourceTable theEntity);
void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, RequestDetails theRequestDetails);
void removeTag(IIdType theId, TagTypeEnum theTagType, String theSystem, String theCode, RequestDetails theRequestDetails);
void removeTag(IIdType theId, TagTypeEnum theTagType, String theSystem, String theCode);
IBundleProvider search(Map<String, IQueryParameterType> theParams);

View File

@ -26,6 +26,7 @@ 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.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
@ -38,4 +39,5 @@ public interface IFhirResourceDaoPatient<T extends IBaseResource> extends IFhirR
IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSortSpec, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails);
}

View File

@ -1046,6 +1046,12 @@ public class SearchBuilder {
retVal = createPredicateQuantity(builder, dateJoin, leftValue);
break;
}
case COMPOSITE:
case HAS:
case NUMBER:
case REFERENCE:
case URI:
break;
}
if (retVal == null) {
@ -1936,6 +1942,9 @@ public class SearchBuilder {
}
}
break;
case HAS:
// should not happen
break;
}
}
}

View File

@ -455,6 +455,9 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
entriesToProcess.put(nextRespEntry, outcome.getEntity());
break;
}
case GET:
case NULL:
break;
}
}

View File

@ -2592,6 +2592,103 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
}
@Test
public void testRemoveTag() {
String methodName = "testResourceMetaOperation";
IIdType id1, id2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
patient.addName().setFamily("Tester").addGiven("Joe");
patient.getMeta().addTag(null, "Dog", "Puppies");
patient.getMeta().addSecurity().setSystem("seclabel:sys:1").setCode("seclabel:code:1").setDisplay("seclabel:dis:1");
patient.getMeta().addProfile(("http://profile/1"));
id1 = myPatientDao.create(patient, mySrd).getId();
}
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
patient.addName().setFamily("Tester").addGiven("Joe");
patient.getMeta().addTag("http://foo", "Cat", "Kittens");
patient.getMeta().addSecurity().setSystem("seclabel:sys:2").setCode("seclabel:code:2").setDisplay("seclabel:dis:2");
patient.getMeta().addProfile("http://profile/2");
id2 = myPatientDao.create(patient, mySrd).getId();
}
{
Device device = new Device();
device.addIdentifier().setSystem("urn:system").setValue(methodName);
device.getMeta().addTag("http://foo", "Foo", "Bars");
device.getMeta().addSecurity().setSystem("seclabel:sys:3").setCode("seclabel:code:3").setDisplay("seclabel:dis:3");
device.getMeta().addProfile("http://profile/3");
myDeviceDao.create(device, mySrd);
}
Meta meta;
meta = myPatientDao.metaGetOperation(Meta.class, mySrd);
List<Coding> published = meta.getTag();
assertEquals(2, published.size());
assertEquals(null, published.get(0).getSystem());
assertEquals("Dog", published.get(0).getCode());
assertEquals("Puppies", published.get(0).getDisplay());
assertEquals("http://foo", published.get(1).getSystem());
assertEquals("Cat", published.get(1).getCode());
assertEquals("Kittens", published.get(1).getDisplay());
List<Coding> secLabels = meta.getSecurity();
assertEquals(2, secLabels.size());
assertEquals("seclabel:sys:1", secLabels.get(0).getSystemElement().getValue());
assertEquals("seclabel:code:1", secLabels.get(0).getCodeElement().getValue());
assertEquals("seclabel:dis:1", secLabels.get(0).getDisplayElement().getValue());
assertEquals("seclabel:sys:2", secLabels.get(1).getSystemElement().getValue());
assertEquals("seclabel:code:2", secLabels.get(1).getCodeElement().getValue());
assertEquals("seclabel:dis:2", secLabels.get(1).getDisplayElement().getValue());
List<UriType> profiles = meta.getProfile();
assertEquals(2, profiles.size());
assertEquals("http://profile/1", profiles.get(0).getValue());
assertEquals("http://profile/2", profiles.get(1).getValue());
meta = myPatientDao.metaGetOperation(Meta.class, id2, mySrd);
published = meta.getTag();
assertEquals(1, published.size());
assertEquals("http://foo", published.get(0).getSystem());
assertEquals("Cat", published.get(0).getCode());
assertEquals("Kittens", published.get(0).getDisplay());
secLabels = meta.getSecurity();
assertEquals(1, secLabels.size());
assertEquals("seclabel:sys:2", secLabels.get(0).getSystemElement().getValue());
assertEquals("seclabel:code:2", secLabels.get(0).getCodeElement().getValue());
assertEquals("seclabel:dis:2", secLabels.get(0).getDisplayElement().getValue());
profiles = meta.getProfile();
assertEquals(1, profiles.size());
assertEquals("http://profile/2", profiles.get(0).getValue());
myPatientDao.removeTag(id1, TagTypeEnum.TAG, null, "Dog");
myPatientDao.removeTag(id1, TagTypeEnum.SECURITY_LABEL, "seclabel:sys:1", "seclabel:code:1");
myPatientDao.removeTag(id1, TagTypeEnum.PROFILE, BaseHapiFhirDao.NS_JPA_PROFILE, "http://profile/1");
meta = myPatientDao.metaGetOperation(Meta.class, mySrd);
published = meta.getTag();
assertEquals(1, published.size());
assertEquals("http://foo", published.get(0).getSystem());
assertEquals("Cat", published.get(0).getCode());
assertEquals("Kittens", published.get(0).getDisplay());
secLabels = meta.getSecurity();
assertEquals(1, secLabels.size());
assertEquals("seclabel:sys:2", secLabels.get(0).getSystemElement().getValue());
assertEquals("seclabel:code:2", secLabels.get(0).getCodeElement().getValue());
assertEquals("seclabel:dis:2", secLabels.get(0).getDisplayElement().getValue());
profiles = meta.getProfile();
assertEquals(1, profiles.size());
assertEquals("http://profile/2", profiles.get(0).getValue());
}
@Test
public void testReverseIncludes() {
String methodName = "testReverseIncludes";

View File

@ -402,7 +402,7 @@ public class BaseDateTimeDtDstu2Test {
public void testLargePrecision() {
DateTimeDt dt = new DateTimeDt("2014-03-06T22:09:58.9121174+04:30");
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("Z"));
myDateInstantParser.setTimeZone(TimeZone.getTimeZone("GMT"));
assertEquals("2014-03-06 17:39:58.912", myDateInstantParser.format(dt.getValue()));
}

View File

@ -307,7 +307,7 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
*/
public TimeZone getTimeZone() {
if (myTimeZoneZulu) {
return TimeZone.getTimeZone("Z");
return TimeZone.getTimeZone("GMT");
}
return myTimeZone;
}

View File

@ -162,7 +162,7 @@ public class BaseController {
b.append(nextChar);
b.append("</span>");
inValue = false;
} else if (nextChar == '}' || nextChar == '}' || nextChar == ',') {
} else if (nextChar == '{' || nextChar == '}' || nextChar == ',') {
b.append("<span class='hlControl'>");
b.append(nextChar);
b.append("</span>");
@ -321,6 +321,9 @@ public class BaseController {
return loadAndAddConfDstu2(theServletRequest, theRequest, theModel);
case DSTU3:
return loadAndAddConfDstu3(theServletRequest, theRequest, theModel);
case DSTU2_1:
case DSTU2_HL7ORG:
break;
}
throw new IllegalStateException("Unknown version: " + theRequest.getFhirVersion(myConfig));
}

View File

@ -63,6 +63,11 @@
of literal ones, meaning that the server will not try to resolve these
URLs. Thanks to Eeva Turkka for the suggestion!
</action>
<action type="add">
Add a utility method to JPA server:
<![CDATA[<code>IFhirResourceDao#removeTag(IIdType, TagTypeEnum, String, String)</code>]]>. This allows client code to remove tags
from a resource without having a servlet request object in context.
</action>
</release>
<release version="2.3" date="2017-03-18">
<action type="add">