This commit is contained in:
de Beaubien, Bill 2016-01-20 19:31:15 -05:00
commit 9b5c393ad3
36 changed files with 20057 additions and 219 deletions

View File

@ -1,5 +1,4 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
@ -14,6 +13,9 @@
<name>HAPI FHIR - Deployable Artifact Parent POM</name> <name>HAPI FHIR - Deployable Artifact Parent POM</name>
<dependencies>
</dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -53,7 +55,6 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId> <artifactId>maven-project-info-reports-plugin</artifactId>
<version>${maven_project_info_plugin_version}</version>
<configuration> <configuration>
<skip>true</skip> <skip>true</skip>
</configuration> </configuration>
@ -61,7 +62,6 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>${maven_javadoc_plugin_version}</version>
<reportSets> <reportSets>
<reportSet> <reportSet>
<id>default</id> <id>default</id>
@ -110,7 +110,6 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId> <artifactId>maven-source-plugin</artifactId>
<version>${maven_source_plugin_version}</version>
<executions> <executions>
<execution> <execution>
<phase>package</phase> <phase>package</phase>
@ -123,7 +122,6 @@
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId> <artifactId>license-maven-plugin</artifactId>
<version>${maven_license_plugin_version}</version>
<executions> <executions>
<execution> <execution>
<id>first</id> <id>first</id>

View File

@ -46,6 +46,13 @@ public enum TemporalPrecisionEnum {
return DateUtils.addDays(theInput, theAmount); return DateUtils.addDays(theInput, theAmount);
} }
}, },
MINUTE(Calendar.MINUTE) {
@Override
public Date add(Date theInput, int theAmount) {
return DateUtils.addMinutes(theInput, theAmount);
}
},
SECOND(Calendar.SECOND) { SECOND(Calendar.SECOND) {
@Override @Override
public Date add(Date theInput, int theAmount) { public Date add(Date theInput, int theAmount) {
@ -58,7 +65,7 @@ public enum TemporalPrecisionEnum {
public Date add(Date theInput, int theAmount) { public Date add(Date theInput, int theAmount) {
return DateUtils.addMilliseconds(theInput, theAmount); return DateUtils.addMilliseconds(theInput, theAmount);
} }
}, },
; ;

View File

@ -68,6 +68,8 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
private static final FastDateFormat ourHumanDateFormat = FastDateFormat.getDateInstance(FastDateFormat.MEDIUM); private static final FastDateFormat ourHumanDateFormat = FastDateFormat.getDateInstance(FastDateFormat.MEDIUM);
private static final Pattern ourYearMonthPattern = Pattern.compile("[0-9]{4}[0-9]{2}"); private static final Pattern ourYearMonthPattern = Pattern.compile("[0-9]{4}[0-9]{2}");
private static final Pattern ourYearPattern = Pattern.compile("[0-9]{4}"); private static final Pattern ourYearPattern = Pattern.compile("[0-9]{4}");
private static final FastDateFormat ourYearMonthDayTimeMinsFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm");
private static final FastDateFormat ourYearMonthDayTimeMinsZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mmZZ");
static { static {
ArrayList<FastDateFormat> formatters = new ArrayList<FastDateFormat>(); ArrayList<FastDateFormat> formatters = new ArrayList<FastDateFormat>();
@ -185,36 +187,40 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
if (theValue == null) { if (theValue == null) {
return null; return null;
} else { } else {
GregorianCalendar cal;
if (myTimeZoneZulu) {
cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
} else if (myTimeZone != null) {
cal = new GregorianCalendar(myTimeZone);
} else {
cal = new GregorianCalendar();
}
cal.setTime(theValue);
switch (myPrecision) { switch (myPrecision) {
case DAY: case DAY:
return ourYearMonthDayFormat.format(theValue); return ourYearMonthDayFormat.format(cal);
case MONTH: case MONTH:
return ourYearMonthFormat.format(theValue); return ourYearMonthFormat.format(cal);
case YEAR: case YEAR:
return ourYearFormat.format(theValue); return ourYearFormat.format(cal);
case MINUTE:
if (myTimeZoneZulu) {
return ourYearMonthDayTimeMinsFormat.format(cal) + "Z";
} else {
return ourYearMonthDayTimeMinsZoneFormat.format(cal);
}
case SECOND: case SECOND:
if (myTimeZoneZulu) { if (myTimeZoneZulu) {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
cal.setTime(theValue);
return ourYearMonthDayTimeFormat.format(cal) + "Z"; return ourYearMonthDayTimeFormat.format(cal) + "Z";
} else if (myTimeZone != null) {
GregorianCalendar cal = new GregorianCalendar(myTimeZone);
cal.setTime(theValue);
return ourYearMonthDayTimeZoneFormat.format(cal);
} else { } else {
return ourYearMonthDayTimeFormat.format(theValue); return ourYearMonthDayTimeZoneFormat.format(cal);
} }
case MILLI: case MILLI:
if (myTimeZoneZulu) { if (myTimeZoneZulu) {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
cal.setTime(theValue);
return ourYearMonthDayTimeMilliFormat.format(cal) + "Z"; return ourYearMonthDayTimeMilliFormat.format(cal) + "Z";
} else if (myTimeZone != null) {
GregorianCalendar cal = new GregorianCalendar(myTimeZone);
cal.setTime(theValue);
return ourYearMonthDayTimeMilliZoneFormat.format(cal);
} else { } else {
return ourYearMonthDayTimeMilliFormat.format(theValue); return ourYearMonthDayTimeMilliZoneFormat.format(cal);
} }
} }
throw new IllegalStateException("Invalid precision (this is a HAPI bug, shouldn't happen): " + myPrecision); throw new IllegalStateException("Invalid precision (this is a HAPI bug, shouldn't happen): " + myPrecision);

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.primitive; package ca.uhn.fhir.model.primitive;
import java.util.Calendar;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -21,6 +23,8 @@ package ca.uhn.fhir.model.primitive;
*/ */
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.api.annotation.DatatypeDef; import ca.uhn.fhir.model.api.annotation.DatatypeDef;
@ -34,6 +38,17 @@ import ca.uhn.fhir.parser.DataFormatException;
* <li>{@link TemporalPrecisionEnum#MONTH} * <li>{@link TemporalPrecisionEnum#MONTH}
* <li>{@link TemporalPrecisionEnum#DAY} * <li>{@link TemporalPrecisionEnum#DAY}
* </ul> * </ul>
*
* <p>
* <b>Note on using Java Date objects:</b> This type stores the date as a Java Date. Note that
* the Java Date has more precision (millisecond precision), and does not store a timezone. As such,
* it could potentially cause issues. For example, if a Date contains the number of milliseconds at
* midnight in a timezone across the date line from your location, it might refer to a different date than
* intended.
* </p>
* <p>
* As such, it is recommended to use the <code>Calendar<code> or <code>int,int,int</code> constructors
* </p>
*/ */
@DatatypeDef(name = "date") @DatatypeDef(name = "date")
public class DateDt extends BaseDateTimeDt { public class DateDt extends BaseDateTimeDt {
@ -51,7 +66,17 @@ public class DateDt extends BaseDateTimeDt {
} }
/** /**
* Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type * Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
*/
public DateDt(Calendar theCalendar) {
super(theCalendar.getTime(), DEFAULT_PRECISION);
setTimeZone(theCalendar.getTimeZone());
}
/**
* Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
* <b>Please see the note on timezones</b> on the {@link DateDt class documentation} for considerations
* when using this constructor!
*/ */
@SimpleSetter(suffix = "WithDayPrecision") @SimpleSetter(suffix = "WithDayPrecision")
public DateDt(@SimpleSetter.Parameter(name = "theDate") Date theDate) { public DateDt(@SimpleSetter.Parameter(name = "theDate") Date theDate) {
@ -65,6 +90,8 @@ public class DateDt extends BaseDateTimeDt {
* <li>{@link TemporalPrecisionEnum#MONTH} * <li>{@link TemporalPrecisionEnum#MONTH}
* <li>{@link TemporalPrecisionEnum#DAY} * <li>{@link TemporalPrecisionEnum#DAY}
* </ul> * </ul>
* <b>Please see the note on timezones</b> on the {@link DateDt class documentation} for considerations
* when using this constructor!
* *
* @throws DataFormatException * @throws DataFormatException
* If the specified precision is not allowed for this type * If the specified precision is not allowed for this type
@ -74,6 +101,17 @@ public class DateDt extends BaseDateTimeDt {
super(theDate, thePrecision); super(theDate, thePrecision);
} }
/**
* Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
*
* @param theYear The year, e.g. 2015
* @param theMonth The month, e.g. 0 for January
* @param theDay The day (1 indexed) e.g. 1 for the first day of the month
*/
public DateDt(int theYear, int theMonth, int theDay) {
this(toCalendarZulu(theYear, theMonth, theDay));
}
/** /**
* Constructor which accepts a date as a string in FHIR format * Constructor which accepts a date as a string in FHIR format
* *
@ -84,6 +122,16 @@ public class DateDt extends BaseDateTimeDt {
super(theDate); super(theDate);
} }
/**
* Returns the default precision for this datatype
*
* @see #DEFAULT_PRECISION
*/
@Override
protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
return DEFAULT_PRECISION;
}
@Override @Override
boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) { boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
switch (thePrecision) { switch (thePrecision) {
@ -96,14 +144,12 @@ public class DateDt extends BaseDateTimeDt {
} }
} }
/** private static GregorianCalendar toCalendarZulu(int theYear, int theMonth, int theDay) {
* Returns the default precision for this datatype GregorianCalendar retVal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
* retVal.set(Calendar.YEAR, theYear);
* @see #DEFAULT_PRECISION retVal.set(Calendar.MONTH, theMonth);
*/ retVal.set(Calendar.DATE, theDay);
@Override return retVal;
protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
return DEFAULT_PRECISION;
} }
} }

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.method;
import java.lang.reflect.Method; 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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -82,8 +83,6 @@ public class OperationParameter implements IParameter {
myContext = theCtx; myContext = theCtx;
} }
protected FhirContext getContext() { protected FhirContext getContext() {
return myContext; return myContext;
} }
@ -109,22 +108,22 @@ public class OperationParameter implements IParameter {
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 (getContext().getVersion().getVersion().isRi()) { if (getContext().getVersion().getVersion().isRi()) {
if (IDatatype.class.isAssignableFrom(theParameterType)) { if (IDatatype.class.isAssignableFrom(theParameterType)) {
throw new ConfigurationException("Incorrect use of type " + theParameterType.getSimpleName() + " as parameter type for method when context is for version " + getContext().getVersion().getVersion().name() + " in method: " + theMethod.toString()); throw new ConfigurationException("Incorrect use of type " + theParameterType.getSimpleName() + " as parameter type for method when context is for version "
+ getContext().getVersion().getVersion().name() + " in method: " + theMethod.toString());
} }
} }
myParameterType = theParameterType; myParameterType = theParameterType;
if (theInnerCollectionType != null) { if (theInnerCollectionType != null) {
myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, myName); myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, myName);
} else { } else {
myMax = 1; myMax = 1;
} }
myAllowGet = IPrimitiveType.class.isAssignableFrom(myParameterType) || String.class.equals(myParameterType); myAllowGet = IPrimitiveType.class.isAssignableFrom(myParameterType) || String.class.equals(myParameterType);
/* /*
* The parameter can be of type string for validation methods - This is a bit * The parameter can be of type string for validation methods - This is a bit weird. See ValidateDstu2Test. We should probably clean this up..
* weird. See ValidateDstu2Test. We should probably clean this up..
*/ */
if (!myParameterType.equals(IBase.class) && !myParameterType.equals(String.class)) { if (!myParameterType.equals(IBase.class) && !myParameterType.equals(String.class)) {
if (IBaseResource.class.isAssignableFrom(myParameterType) && myParameterType.isInterface()) { if (IBaseResource.class.isAssignableFrom(myParameterType) && myParameterType.isInterface()) {
@ -150,7 +149,8 @@ public class OperationParameter implements IParameter {
} }
@Override @Override
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, IBaseResource theTargetResource)
throws InternalErrorException {
assert theTargetResource != null; assert theTargetResource != null;
Object sourceClientArgument = theSourceClientArgument; Object sourceClientArgument = theSourceClientArgument;
if (sourceClientArgument == null) { if (sourceClientArgument == null) {
@ -173,7 +173,7 @@ public class OperationParameter implements IParameter {
String[] paramValues = theRequest.getParameters().get(myName); String[] paramValues = theRequest.getParameters().get(myName);
if (paramValues != null && paramValues.length > 0) { if (paramValues != null && paramValues.length > 0) {
if (myAllowGet) { if (myAllowGet) {
if (DateRangeParam.class.isAssignableFrom(myParameterType)) { if (DateRangeParam.class.isAssignableFrom(myParameterType)) {
List<QualifiedParamList> parameters = new ArrayList<QualifiedParamList>(); List<QualifiedParamList> parameters = new ArrayList<QualifiedParamList>();
parameters.add(QualifiedParamList.singleton(paramValues[0])); parameters.add(QualifiedParamList.singleton(paramValues[0]));
@ -184,11 +184,11 @@ public class OperationParameter implements IParameter {
dateRangeParam.setValuesAsQueryTokens(parameters); dateRangeParam.setValuesAsQueryTokens(parameters);
matchingParamValues.add(dateRangeParam); matchingParamValues.add(dateRangeParam);
} else if (String.class.isAssignableFrom(myParameterType)) { } else if (String.class.isAssignableFrom(myParameterType)) {
for (String next : paramValues) { for (String next : paramValues) {
matchingParamValues.add(next); matchingParamValues.add(next);
} }
} else { } else {
for (String nextValue : paramValues) { for (String nextValue : paramValues) {
FhirContext ctx = theRequest.getServer().getFhirContext(); FhirContext ctx = theRequest.getServer().getFhirContext();
@ -212,42 +212,51 @@ public class OperationParameter implements IParameter {
return null; return null;
} }
Class<? extends IBaseResource> wantedResourceType = theMethodBinding.getContext().getResourceDefinition("Parameters").getImplementingClass(); // Class<? extends IBaseResource> wantedResourceType = theMethodBinding.getContext().getResourceDefinition("Parameters").getImplementingClass();
Class<IBaseResource> wantedResourceType = null;
IBaseResource requestContents = ResourceParameter.loadResourceFromRequest(theRequest, theMethodBinding, wantedResourceType); IBaseResource requestContents = ResourceParameter.loadResourceFromRequest(theRequest, theMethodBinding, wantedResourceType);
RuntimeResourceDefinition def = ctx.getResourceDefinition(requestContents); RuntimeResourceDefinition def = ctx.getResourceDefinition(requestContents);
if (def.getName().equals("Parameters")) {
BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter"); BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter");
BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter"); BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter");
RuntimeChildPrimitiveDatatypeDefinition nameChild = (RuntimeChildPrimitiveDatatypeDefinition) paramChildElem.getChildByName("name"); RuntimeChildPrimitiveDatatypeDefinition nameChild = (RuntimeChildPrimitiveDatatypeDefinition) paramChildElem.getChildByName("name");
BaseRuntimeChildDefinition valueChild = paramChildElem.getChildByName("value[x]"); BaseRuntimeChildDefinition valueChild = paramChildElem.getChildByName("value[x]");
BaseRuntimeChildDefinition resourceChild = paramChildElem.getChildByName("resource"); BaseRuntimeChildDefinition resourceChild = paramChildElem.getChildByName("resource");
IAccessor paramChildAccessor = paramChild.getAccessor(); IAccessor paramChildAccessor = paramChild.getAccessor();
List<IBase> values = paramChildAccessor.getValues(requestContents); List<IBase> values = paramChildAccessor.getValues(requestContents);
for (IBase nextParameter : values) { for (IBase nextParameter : values) {
List<IBase> nextNames = nameChild.getAccessor().getValues(nextParameter); List<IBase> nextNames = nameChild.getAccessor().getValues(nextParameter);
if (nextNames != null && nextNames.size() > 0) { if (nextNames != null && nextNames.size() > 0) {
IPrimitiveType<?> nextName = (IPrimitiveType<?>) nextNames.get(0); IPrimitiveType<?> nextName = (IPrimitiveType<?>) nextNames.get(0);
if (myName.equals(nextName.getValueAsString())) { if (myName.equals(nextName.getValueAsString())) {
if (myParameterType.isAssignableFrom(nextParameter.getClass())) { if (myParameterType.isAssignableFrom(nextParameter.getClass())) {
matchingParamValues.add(nextParameter); matchingParamValues.add(nextParameter);
} else { } else {
List<IBase> paramValues = valueChild.getAccessor().getValues(nextParameter); List<IBase> paramValues = valueChild.getAccessor().getValues(nextParameter);
List<IBase> paramResources = resourceChild.getAccessor().getValues(nextParameter); List<IBase> paramResources = resourceChild.getAccessor().getValues(nextParameter);
if (paramValues != null && paramValues.size() > 0) { if (paramValues != null && paramValues.size() > 0) {
tryToAddValues(paramValues, matchingParamValues); tryToAddValues(paramValues, matchingParamValues);
} else if (paramResources != null && paramResources.size() > 0) { } else if (paramResources != null && paramResources.size() > 0) {
tryToAddValues(paramResources, matchingParamValues); tryToAddValues(paramResources, matchingParamValues);
}
} }
}
}
} }
} }
}
} else {
if (myParameterType.isAssignableFrom(requestContents.getClass())) {
tryToAddValues(Arrays.asList((IBase) requestContents), matchingParamValues);
}
}
} }
if (matchingParamValues.isEmpty()) { if (matchingParamValues.isEmpty()) {

View File

@ -80,6 +80,12 @@ import ca.uhn.fhir.util.VersionUtil;
public class RestfulServer extends HttpServlet implements IRestfulServer<ServletRequestDetails> { public class RestfulServer extends HttpServlet implements IRestfulServer<ServletRequestDetails> {
/**
* Requests will have an HttpServletRequest attribute set with this name, containing the servlet
* context, in order to avoid a dependency on Servlet-API 3.0+
*/
public static final String SERVLET_CONTEXT_ATTRIBUTE = "ca.uhn.fhir.rest.server.RestfulServer.servlet_context";
/** /**
* Default setting for {@link #setETagSupport(ETagSupportEnum) ETag Support}: {@link ETagSupportEnum#ENABLED} * Default setting for {@link #setETagSupport(ETagSupportEnum) ETag Support}: {@link ETagSupportEnum#ENABLED}
*/ */
@ -517,6 +523,8 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
requestDetails.setRequestType(theRequestType); requestDetails.setRequestType(theRequestType);
requestDetails.setServletRequest(theRequest); requestDetails.setServletRequest(theRequest);
requestDetails.setServletResponse(theResponse); requestDetails.setServletResponse(theResponse);
theRequest.setAttribute(SERVLET_CONTEXT_ATTRIBUTE, getServletContext());
try { try {

View File

@ -186,11 +186,13 @@ public class FhirValidator {
next.validateBundle(ctx); next.validateBundle(ctx);
} }
IBaseOperationOutcome oo = ctx.toResult().toOperationOutcome(); if (ctx.toResult().isSuccessful() == false ) {
if (oo != null && OperationOutcomeUtil.hasIssues(myContext, oo)) { IBaseOperationOutcome oo = ctx.toResult().toOperationOutcome();
throw new ValidationFailureException(myContext, oo); if (oo != null && OperationOutcomeUtil.hasIssues(myContext, oo)) {
throw new ValidationFailureException(myContext, oo);
}
} }
} }
private void applyDefaultValidators() { private void applyDefaultValidators() {

View File

@ -111,6 +111,11 @@ public class ValidationResult {
OperationOutcomeUtil.addIssue(myCtx, oo, severity, next.getMessage(), location, ExceptionHandlingInterceptor.PROCESSING); OperationOutcomeUtil.addIssue(myCtx, oo, severity, next.getMessage(), location, ExceptionHandlingInterceptor.PROCESSING);
} }
if (myMessages.isEmpty()) {
String message = myCtx.getLocalizer().getMessage(ValidationResult.class, "noIssuesDetected");
OperationOutcomeUtil.addIssue(myCtx, oo, "information", message, null, "informational");
}
return oo; return oo;
} }

View File

@ -38,6 +38,7 @@ ca.uhn.fhir.rest.server.RestfulServer.rootRequest=This is the base URL of FHIR s
ca.uhn.fhir.validation.ValidationContext.unableToDetermineEncoding=Unable to determine encoding (e.g. XML / JSON) on validation input. Is this a valid FHIR resource body? ca.uhn.fhir.validation.ValidationContext.unableToDetermineEncoding=Unable to determine encoding (e.g. XML / JSON) on validation input. Is this a valid FHIR resource body?
ca.uhn.fhir.validation.FhirValidator.noPhlocWarningOnStartup=Phloc-schematron library not found on classpath, will not attempt to perform schematron validation ca.uhn.fhir.validation.FhirValidator.noPhlocWarningOnStartup=Phloc-schematron library not found on classpath, will not attempt to perform schematron validation
ca.uhn.fhir.validation.FhirValidator.noPhlocError=Phloc-schematron library not found on classpath, can not enable perform schematron validation ca.uhn.fhir.validation.FhirValidator.noPhlocError=Phloc-schematron library not found on classpath, can not enable perform schematron validation
ca.uhn.fhir.validation.ValidationResult.noIssuesDetected=No issues detected during validation
# JPA Messages # JPA Messages

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.jpa.provider; package ca.uhn.fhir.jpa.provider;
import org.hl7.fhir.dstu21.model.QuestionnaireResponse;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -20,9 +22,7 @@ package ca.uhn.fhir.jpa.provider;
* #L% * #L%
*/ */
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse; public class BaseJpaResourceProviderQuestionnaireResponseDstu21 extends JpaResourceProviderDstu21<QuestionnaireResponse> {
public class BaseJpaResourceProviderQuestionnaireResponseDstu21 extends JpaResourceProviderDstu2<QuestionnaireResponse> {
// nothing yet // nothing yet

View File

@ -62,6 +62,7 @@ public class TestDstu21Config extends BaseJavaConfigDstu21 {
extraProperties.put("hibernate.search.default.directory_provider" ,"filesystem"); extraProperties.put("hibernate.search.default.directory_provider" ,"filesystem");
extraProperties.put("hibernate.search.default.indexBase", "target/lucene_index_dstu21"); extraProperties.put("hibernate.search.default.indexBase", "target/lucene_index_dstu21");
extraProperties.put("hibernate.search.lucene_version","LUCENE_CURRENT"); extraProperties.put("hibernate.search.lucene_version","LUCENE_CURRENT");
extraProperties.put("hibernate.search.autoregister_listeners", "true");
return extraProperties; return extraProperties;
} }

View File

@ -0,0 +1,56 @@
package ca.uhn.fhir.jpa.config;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Organization;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
public class Tmp {
public static void main(String[] args) {
FhirContext ctx = FhirContext.forDstu2();
ctx.getRestfulClientFactory().setSocketTimeout(200000);
ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
IGenericClient client = ctx.newRestfulGenericClient("http://localhost:8080/hapi-fhir-jpaserver-example/baseDstu2");
Bundle b = new Bundle();
b.setType(BundleTypeEnum.TRANSACTION);
int resCount = 20;
for (int i = 0; i < (resCount / 2); i++) {
Organization org = new Organization();
org.setId(IdDt.newRandomUuid());
org.setName("Random Org " + i);
org.addAddress().addLine("Random Org Line 1");
org.addIdentifier().setSystem("urn:foo").setValue("some_system" + i);
b.addEntry().setResource(org).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Organization");
Patient patient = new Patient();
patient.setId(IdDt.newRandomUuid());
patient.addName().addFamily("Family" + i).addGiven("Gigven " + i);
patient.addAddress().addLine("Random Patient Line 1");
patient.addIdentifier().setSystem("urn:bar").setValue("some_system" + i);
b.addEntry().setResource(patient).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
}
int total = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < 300; i++) {
client.transaction().withBundle(b).execute();
ourLog.info("" + i);
total += resCount;
}
long delay = System.currentTimeMillis() - start;
ourLog.info("Wrote {} resources at {}ms / res", total, delay / total);
//sync 13:57:14.683 [main] INFO ca.uhn.fhir.jpa.config.Tmp - Wrote 6000 resources at 7ms / res
}
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Tmp.class);
}

View File

@ -57,6 +57,7 @@ import org.hl7.fhir.dstu21.model.Encounter;
import org.hl7.fhir.dstu21.model.Encounter.EncounterClass; import org.hl7.fhir.dstu21.model.Encounter.EncounterClass;
import org.hl7.fhir.dstu21.model.Encounter.EncounterLocationComponent; import org.hl7.fhir.dstu21.model.Encounter.EncounterLocationComponent;
import org.hl7.fhir.dstu21.model.Encounter.EncounterState; import org.hl7.fhir.dstu21.model.Encounter.EncounterState;
import org.hl7.fhir.dstu21.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu21.model.IdType; import org.hl7.fhir.dstu21.model.IdType;
import org.hl7.fhir.dstu21.model.ImagingStudy; import org.hl7.fhir.dstu21.model.ImagingStudy;
import org.hl7.fhir.dstu21.model.InstantType; import org.hl7.fhir.dstu21.model.InstantType;
@ -111,10 +112,10 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
@Override @Override
public void before() throws Exception { public void before() throws Exception {
super.before(); super.before();
myDaoConfig.setAllowMultipleDelete(true); myDaoConfig.setAllowMultipleDelete(true);
} }
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException { private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false"); HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false");
CloseableHttpResponse resp = ourHttpClient.execute(get); CloseableHttpResponse resp = ourHttpClient.execute(get);
@ -135,7 +136,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
Device dev1 = new Device(); Device dev1 = new Device();
dev1.setManufacturer("Some Manufacturer"); dev1.setManufacturer("Some Manufacturer");
IIdType devId1 = myDeviceDao.create(dev1).getId().toUnqualifiedVersionless(); IIdType devId1 = myDeviceDao.create(dev1).getId().toUnqualifiedVersionless();
Device dev2 = new Device(); Device dev2 = new Device();
dev2.setManufacturer("Some Manufacturer 2"); dev2.setManufacturer("Some Manufacturer 2");
myDeviceDao.create(dev2).getId().toUnqualifiedVersionless(); myDeviceDao.create(dev2).getId().toUnqualifiedVersionless();
@ -159,12 +160,12 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
obs3.getCode().addCoding().setCode("CODE3"); obs3.getCode().addCoding().setCode("CODE3");
obs3.setValue(new StringType("obsvalue3")); obs3.setValue(new StringType("obsvalue3"));
IIdType obsId3 = myObservationDao.create(obs3).getId().toUnqualifiedVersionless(); IIdType obsId3 = myObservationDao.create(obs3).getId().toUnqualifiedVersionless();
List<IIdType> actual; List<IIdType> actual;
StringAndListParam param; StringAndListParam param;
ourLog.info("Pt1:{} Pt2:{} Obs1:{} Obs2:{} Obs3:{}", new Object[] {ptId1.getIdPart(), ptId2.getIdPart(), obsId1.getIdPart(), obsId2.getIdPart(), obsId3.getIdPart()}); ourLog.info("Pt1:{} Pt2:{} Obs1:{} Obs2:{} Obs3:{}", new Object[] { ptId1.getIdPart(), ptId2.getIdPart(), obsId1.getIdPart(), obsId2.getIdPart(), obsId3.getIdPart() });
param = new StringAndListParam(); param = new StringAndListParam();
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1"))); param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
@ -176,13 +177,12 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
.withParameter(Parameters.class, Constants.PARAM_CONTENT, new StringType("obsvalue1")) .withParameter(Parameters.class, Constants.PARAM_CONTENT, new StringType("obsvalue1"))
.execute(); .execute();
//@formatter:on //@formatter:on
actual = toUnqualifiedVersionlessIds((Bundle)response.getParameter().get(0).getResource()); actual = toUnqualifiedVersionlessIds((Bundle) response.getParameter().get(0).getResource());
assertThat(actual, containsInAnyOrder(ptId1, obsId1, devId1)); assertThat(actual, containsInAnyOrder(ptId1, obsId1, devId1));
} }
@Test @Test
public void testBundleCreate() throws Exception { public void testBundleCreate() throws Exception {
IGenericClient client = ourClient; IGenericClient client = ourClient;
@ -211,7 +211,6 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} }
} }
// private void delete(String theResourceType, String theParamName, String theParamValue) { // private void delete(String theResourceType, String theParamName, String theParamValue) {
// Bundle resources; // Bundle resources;
// do { // do {
@ -244,7 +243,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
subs.getChannel().setType(SubscriptionChannelType.WEBSOCKET); subs.getChannel().setType(SubscriptionChannelType.WEBSOCKET);
subs.setCriteria("Observation?"); subs.setCriteria("Observation?");
IIdType id = ourClient.create().resource(subs).execute().getId().toUnqualifiedVersionless(); IIdType id = ourClient.create().resource(subs).execute().getId().toUnqualifiedVersionless();
//@formatter:off //@formatter:off
Bundle resp = ourClient Bundle resp = ourClient
.search() .search()
@ -297,24 +296,11 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
ourClient.transaction().withResources(resources).prettyPrint().encodedXml().execute(); ourClient.transaction().withResources(resources).prettyPrint().encodedXml().execute();
//@formatter:on //@formatter:on
Bundle found = ourClient Bundle found = ourClient.search().forResource(Organization.class).where(Organization.NAME.matches().value("rpdstu2_testCountParam_01")).count(10).returnBundle(Bundle.class).execute();
.search()
.forResource(Organization.class)
.where(Organization.NAME.matches()
.value("rpdstu2_testCountParam_01"))
.count(10)
.returnBundle(Bundle.class)
.execute();
assertEquals(100, found.getTotal()); assertEquals(100, found.getTotal());
assertEquals(10, found.getEntry().size()); assertEquals(10, found.getEntry().size());
found = ourClient found = ourClient.search().forResource(Organization.class).where(Organization.NAME.matches().value("rpdstu2_testCountParam_01")).count(999).returnBundle(Bundle.class).execute();
.search()
.forResource(Organization.class)
.where(Organization.NAME.matches().value("rpdstu2_testCountParam_01"))
.count(999)
.returnBundle(Bundle.class)
.execute();
//@formatter:on //@formatter:on
assertEquals(100, found.getTotal()); assertEquals(100, found.getTotal());
assertEquals(50, found.getEntry().size()); assertEquals(50, found.getEntry().size());
@ -353,7 +339,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
assertThat(e.getMessage(), containsString("Question with linkId[link0]")); assertThat(e.getMessage(), containsString("Question with linkId[link0]"));
} }
} }
@Test @Test
public void testUpdateResourceConditionalComplex() throws IOException { public void testUpdateResourceConditionalComplex() throws IOException {
Patient pt = new Patient(); Patient pt = new Patient();
@ -374,12 +360,12 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} finally { } finally {
response.close(); response.close();
} }
pt.addName().addFamily("FOO"); pt.addName().addFamily("FOO");
resource = myFhirCtx.newXmlParser().encodeResourceToString(pt); resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escape("|")))); HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escape("|"))));
put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
IdType id2; IdType id2;
response = ourHttpClient.execute(put); response = ourHttpClient.execute(put);
try { try {
@ -390,7 +376,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} finally { } finally {
response.close(); response.close();
} }
assertEquals(id.getIdPart(), id2.getIdPart()); assertEquals(id.getIdPart(), id2.getIdPart());
assertEquals("1", id.getVersionIdPart()); assertEquals("1", id.getVersionIdPart());
assertEquals("2", id2.getVersionIdPart()); assertEquals("2", id2.getVersionIdPart());
@ -416,7 +402,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} finally { } finally {
response.close(); response.close();
} }
IdType id2; IdType id2;
response = ourHttpClient.execute(post); response = ourHttpClient.execute(post);
try { try {
@ -427,7 +413,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} finally { } finally {
response.close(); response.close();
} }
// //@formatter:off // //@formatter:off
// IIdType id3 = ourClient // IIdType id3 = ourClient
// .update() // .update()
@ -435,10 +421,10 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
// .conditionalByUrl("Patient?identifier=http://general-hospital.co.uk/Identifiers|09832345234543876876") // .conditionalByUrl("Patient?identifier=http://general-hospital.co.uk/Identifiers|09832345234543876876")
// .execute().getId(); // .execute().getId();
// //@formatter:on // //@formatter:on
assertEquals(id.getValue(), id2.getValue()); assertEquals(id.getValue(), id2.getValue());
} }
@Test @Test
public void testCreateResourceConditional() throws IOException { public void testCreateResourceConditional() throws IOException {
String methodName = "testCreateResourceConditional"; String methodName = "testCreateResourceConditional";
@ -581,12 +567,12 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
String methodName = "testDeleteConditionalMultiple"; String methodName = "testDeleteConditionalMultiple";
myDaoConfig.setAllowMultipleDelete(false); myDaoConfig.setAllowMultipleDelete(false);
Patient p = new Patient(); Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName); p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("FAM1"); p.addName().addFamily("FAM1");
IIdType id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless(); IIdType id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient(); p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName); p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("FAM2"); p.addName().addFamily("FAM2");
@ -602,15 +588,16 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
//@formatter:on //@formatter:on
fail(); fail();
} catch (PreconditionFailedException e) { } catch (PreconditionFailedException e) {
assertEquals("HTTP 412 Precondition Failed: Failed to DELETE resource with match URL \"Patient?identifier=testDeleteConditionalMultiple\" because this search matched 2 resources", e.getMessage()); assertEquals("HTTP 412 Precondition Failed: Failed to DELETE resource with match URL \"Patient?identifier=testDeleteConditionalMultiple\" because this search matched 2 resources",
e.getMessage());
} }
// Not deleted yet.. // Not deleted yet..
ourClient.read().resource("Patient").withId(id1).execute(); ourClient.read().resource("Patient").withId(id1).execute();
ourClient.read().resource("Patient").withId(id2).execute(); ourClient.read().resource("Patient").withId(id2).execute();
myDaoConfig.setAllowMultipleDelete(true); myDaoConfig.setAllowMultipleDelete(true);
//@formatter:off //@formatter:off
ourClient ourClient
.delete() .delete()
@ -686,7 +673,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} }
} }
/** /**
* Based on email from Rene Spronk * Based on email from Rene Spronk
*/ */
@ -713,8 +700,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} }
/* /*
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to * Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to make sure that works too..
* make sure that works too..
*/ */
Socket sock = new Socket(); Socket sock = new Socket();
sock.setSoTimeout(3000); sock.setSoTimeout(3000);
@ -842,7 +828,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless(); IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless();
Location locParent = new Location(); Location locParent = new Location();
locParent.setName(methodName+"Parent"); locParent.setName(methodName + "Parent");
IIdType locPId = ourClient.create().resource(locParent).execute().getId().toUnqualifiedVersionless(); IIdType locPId = ourClient.create().resource(locParent).execute().getId().toUnqualifiedVersionless();
Location locChild = new Location(); Location locChild = new Location();
@ -854,7 +840,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
encU.getPatient().setReferenceElement(patientId); encU.getPatient().setReferenceElement(patientId);
encU.addLocation().getLocation().setReferenceElement(locCId); encU.addLocation().getLocation().setReferenceElement(locCId);
IIdType encUId = ourClient.create().resource(encU).execute().getId().toUnqualifiedVersionless(); IIdType encUId = ourClient.create().resource(encU).execute().getId().toUnqualifiedVersionless();
Encounter enc = new Encounter(); Encounter enc = new Encounter();
enc.getPatient().setReferenceElement(patientId); enc.getPatient().setReferenceElement(patientId);
enc.addLocation().getLocation().setReferenceElement(locCId); enc.addLocation().getLocation().setReferenceElement(locCId);
@ -867,7 +853,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
IIdType obsId = ourClient.create().resource(obs).execute().getId().toUnqualifiedVersionless(); IIdType obsId = ourClient.create().resource(obs).execute().getId().toUnqualifiedVersionless();
ourLog.info("IDs: EncU:" + encUId.getIdPart() + " Enc:" + encId.getIdPart() + " " + patientId.toUnqualifiedVersionless()); ourLog.info("IDs: EncU:" + encUId.getIdPart() + " Enc:" + encId.getIdPart() + " " + patientId.toUnqualifiedVersionless());
Parameters output = ourClient.operation().onInstance(encId).named("everything").withNoParameters(Parameters.class).execute(); Parameters output = ourClient.operation().onInstance(encId).named("everything").withNoParameters(Parameters.class).execute();
Bundle b = (Bundle) output.getParameter().get(0).getResource(); Bundle b = (Bundle) output.getParameter().get(0).getResource();
List<IIdType> ids = toUnqualifiedVersionlessIds(b); List<IIdType> ids = toUnqualifiedVersionlessIds(b);
@ -906,7 +892,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless(); IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless();
Location locParent = new Location(); Location locParent = new Location();
locParent.setName(methodName+"Parent"); locParent.setName(methodName + "Parent");
IIdType locPId = ourClient.create().resource(locParent).execute().getId().toUnqualifiedVersionless(); IIdType locPId = ourClient.create().resource(locParent).execute().getId().toUnqualifiedVersionless();
Location locChild = new Location(); Location locChild = new Location();
@ -917,7 +903,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
Encounter encU = new Encounter(); Encounter encU = new Encounter();
encU.addIdentifier().setValue(methodName); encU.addIdentifier().setValue(methodName);
IIdType encUId = ourClient.create().resource(encU).execute().getId().toUnqualifiedVersionless(); IIdType encUId = ourClient.create().resource(encU).execute().getId().toUnqualifiedVersionless();
Encounter enc = new Encounter(); Encounter enc = new Encounter();
enc.getPatient().setReferenceElement(patientId); enc.getPatient().setReferenceElement(patientId);
enc.addLocation().getLocation().setReferenceElement(locCId); enc.addLocation().getLocation().setReferenceElement(locCId);
@ -995,18 +981,18 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
assertThat(ids.size(), greaterThan(10)); assertThat(ids.size(), greaterThan(10));
} }
} }
/** /**
* Test for #226 * Test for #226
*/ */
@Test @Test
public void testEverythingPatientIncludesBackReferences() throws Exception { public void testEverythingPatientIncludesBackReferences() throws Exception {
String methodName = "testEverythingIncludesBackReferences"; String methodName = "testEverythingIncludesBackReferences";
Medication med = new Medication(); Medication med = new Medication();
med.getCode().setText(methodName); med.getCode().setText(methodName);
IIdType medId = myMedicationDao.create(med).getId().toUnqualifiedVersionless(); IIdType medId = myMedicationDao.create(med).getId().toUnqualifiedVersionless();
Patient pat = new Patient(); Patient pat = new Patient();
pat.addAddress().addLine(methodName); pat.addAddress().addLine(methodName);
IIdType patId = myPatientDao.create(pat).getId().toUnqualifiedVersionless(); IIdType patId = myPatientDao.create(pat).getId().toUnqualifiedVersionless();
@ -1015,7 +1001,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
mo.getPatient().setReferenceElement(patId); mo.getPatient().setReferenceElement(patId);
mo.setMedication(new Reference(medId)); mo.setMedication(new Reference(medId));
IIdType moId = myMedicationOrderDao.create(mo).getId().toUnqualifiedVersionless(); IIdType moId = myMedicationOrderDao.create(mo).getId().toUnqualifiedVersionless();
Parameters output = ourClient.operation().onInstance(patId).named("everything").withNoParameters(Parameters.class).execute(); Parameters output = ourClient.operation().onInstance(patId).named("everything").withNoParameters(Parameters.class).execute();
Bundle b = (Bundle) output.getParameter().get(0).getResource(); Bundle b = (Bundle) output.getParameter().get(0).getResource();
List<IIdType> ids = toUnqualifiedVersionlessIds(b); List<IIdType> ids = toUnqualifiedVersionlessIds(b);
@ -1058,8 +1044,6 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} }
@Test @Test
public void testEverythingPatientOperation() throws Exception { public void testEverythingPatientOperation() throws Exception {
String methodName = "testEverythingOperation"; String methodName = "testEverythingOperation";
@ -1104,27 +1088,27 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
ourLog.info(ids.toString()); ourLog.info(ids.toString());
} }
@Test @Test
public void testEverythingPatientType() throws Exception { public void testEverythingPatientType() throws Exception {
String methodName = "testEverythingPatientType"; String methodName = "testEverythingPatientType";
Organization o1 = new Organization(); Organization o1 = new Organization();
o1.setName(methodName+"1"); o1.setName(methodName + "1");
IIdType o1Id = ourClient.create().resource(o1).execute().getId().toUnqualifiedVersionless(); IIdType o1Id = ourClient.create().resource(o1).execute().getId().toUnqualifiedVersionless();
Organization o2 = new Organization(); Organization o2 = new Organization();
o2.setName(methodName+"2"); o2.setName(methodName + "2");
IIdType o2Id = ourClient.create().resource(o2).execute().getId().toUnqualifiedVersionless(); IIdType o2Id = ourClient.create().resource(o2).execute().getId().toUnqualifiedVersionless();
Patient p1 = new Patient(); Patient p1 = new Patient();
p1.addName().addFamily(methodName+"1"); p1.addName().addFamily(methodName + "1");
p1.getManagingOrganization().setReferenceElement(o1Id); p1.getManagingOrganization().setReferenceElement(o1Id);
IIdType p1Id = ourClient.create().resource(p1).execute().getId().toUnqualifiedVersionless(); IIdType p1Id = ourClient.create().resource(p1).execute().getId().toUnqualifiedVersionless();
Patient p2 = new Patient(); Patient p2 = new Patient();
p2.addName().addFamily(methodName+"2"); p2.addName().addFamily(methodName + "2");
p2.getManagingOrganization().setReferenceElement(o2Id); p2.getManagingOrganization().setReferenceElement(o2Id);
IIdType p2Id = ourClient.create().resource(p2).execute().getId().toUnqualifiedVersionless(); IIdType p2Id = ourClient.create().resource(p2).execute().getId().toUnqualifiedVersionless();
Condition c1 = new Condition(); Condition c1 = new Condition();
c1.getPatient().setReferenceElement(p1Id); c1.getPatient().setReferenceElement(p1Id);
IIdType c1Id = ourClient.create().resource(c1).execute().getId().toUnqualifiedVersionless(); IIdType c1Id = ourClient.create().resource(c1).execute().getId().toUnqualifiedVersionless();
@ -1133,7 +1117,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
IIdType c2Id = ourClient.create().resource(c2).execute().getId().toUnqualifiedVersionless(); IIdType c2Id = ourClient.create().resource(c2).execute().getId().toUnqualifiedVersionless();
Condition c3 = new Condition(); Condition c3 = new Condition();
c3.addIdentifier().setValue(methodName+"3"); c3.addIdentifier().setValue(methodName + "3");
IIdType c3Id = ourClient.create().resource(c3).execute().getId().toUnqualifiedVersionless(); IIdType c3Id = ourClient.create().resource(c3).execute().getId().toUnqualifiedVersionless();
Parameters output = ourClient.operation().onType(Patient.class).named("everything").withNoParameters(Parameters.class).execute(); Parameters output = ourClient.operation().onType(Patient.class).named("everything").withNoParameters(Parameters.class).execute();
@ -1152,18 +1136,18 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
Organization org = new Organization(); Organization org = new Organization();
org.setName(methodName); org.setName(methodName);
IIdType oId = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless(); IIdType oId = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
long time1 = System.currentTimeMillis(); long time1 = System.currentTimeMillis();
Thread.sleep(10); Thread.sleep(10);
Patient p = new Patient(); Patient p = new Patient();
p.addName().addFamily(methodName); p.addName().addFamily(methodName);
p.getManagingOrganization().setReferenceElement(oId); p.getManagingOrganization().setReferenceElement(oId);
IIdType pId = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless(); IIdType pId = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
long time2 = System.currentTimeMillis(); long time2 = System.currentTimeMillis();
Thread.sleep(10); Thread.sleep(10);
Condition c = new Condition(); Condition c = new Condition();
c.getCode().setText(methodName); c.getCode().setText(methodName);
c.getPatient().setReferenceElement(pId); c.getPatient().setReferenceElement(pId);
@ -1171,8 +1155,8 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
Thread.sleep(10); Thread.sleep(10);
long time3 = System.currentTimeMillis(); long time3 = System.currentTimeMillis();
// %3E=> %3C=< // %3E=> %3C=<
HttpGet get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_lastUpdated=%3E" + new InstantType(new Date(time1)).getValueAsString()); HttpGet get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_lastUpdated=%3E" + new InstantType(new Date(time1)).getValueAsString());
CloseableHttpResponse response = ourHttpClient.execute(get); CloseableHttpResponse response = ourHttpClient.execute(get);
@ -1188,7 +1172,8 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
response.close(); response.close();
} }
get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_lastUpdated=%3E" + new InstantType(new Date(time2)).getValueAsString() + "&_lastUpdated=%3C" + new InstantType(new Date(time3)).getValueAsString()); get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_lastUpdated=%3E" + new InstantType(new Date(time2)).getValueAsString() + "&_lastUpdated=%3C"
+ new InstantType(new Date(time3)).getValueAsString());
response = ourHttpClient.execute(get); response = ourHttpClient.execute(get);
try { try {
assertEquals(200, response.getStatusLine().getStatusCode()); assertEquals(200, response.getStatusLine().getStatusCode());
@ -1229,7 +1214,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
} finally { } finally {
response.close(); response.close();
} }
} }
@Test @Test
@ -1786,12 +1771,12 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
String methodName = "testSearchWithMissing"; String methodName = "testSearchWithMissing";
Organization org = new Organization(); Organization org = new Organization();
IIdType deletedIdMissingTrue = (IdType) ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless(); IIdType deletedIdMissingTrue = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
ourClient.delete().resourceById(deletedIdMissingTrue).execute(); ourClient.delete().resourceById(deletedIdMissingTrue).execute();
org = new Organization(); org = new Organization();
org.setName("Help I'm a Bug"); org.setName("Help I'm a Bug");
IIdType deletedIdMissingFalse = (IdType) ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless(); IIdType deletedIdMissingFalse = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
ourClient.delete().resourceById(deletedIdMissingFalse).execute(); ourClient.delete().resourceById(deletedIdMissingFalse).execute();
List<IBaseResource> resources = new ArrayList<IBaseResource>(); List<IBaseResource> resources = new ArrayList<IBaseResource>();
@ -1805,11 +1790,11 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
org = new Organization(); org = new Organization();
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01"); org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
org.setName(methodName + "name"); org.setName(methodName + "name");
IIdType orgNotMissing = (IdType) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless(); IIdType orgNotMissing = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
org = new Organization(); org = new Organization();
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01"); org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
IIdType orgMissing = (IdType) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless(); IIdType orgMissing = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
{ {
//@formatter:off //@formatter:off
@ -1817,7 +1802,7 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
.search() .search()
.forResource(Organization.class) .forResource(Organization.class)
.where(Organization.NAME.isMissing(false)) .where(Organization.NAME.isMissing(false))
.limitTo(100) .count(100)
.prettyPrint() .prettyPrint()
.returnBundle(Bundle.class) .returnBundle(Bundle.class)
.execute(); .execute();
@ -2207,14 +2192,14 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
.returnBundle(Bundle.class) .returnBundle(Bundle.class)
.execute(); .execute();
//@formatter:on //@formatter:on
assertEquals(1, actual.getEntry().size()); assertEquals(1, actual.getEntry().size());
assertEquals(p1Id.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart()); assertEquals(p1Id.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
} }
@Test @Test
public void testValidateResource() throws IOException { public void testValidateResourceWithNoIdParameters() throws IOException {
Patient patient = new Patient(); Patient patient = new Patient();
patient.addName().addGiven("James"); patient.addName().addGiven("James");
@ -2224,8 +2209,6 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
input.addParameter().setName("resource").setResource(patient); input.addParameter().setName("resource").setResource(patient);
String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(input); String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(input);
ourLog.info(inputStr);
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate?_pretty=true"); HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate?_pretty=true");
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
@ -2235,6 +2218,61 @@ public class ResourceProviderDstu21Test extends BaseResourceProviderDstu21Test {
ourLog.info(resp); ourLog.info(resp);
assertEquals(200, response.getStatusLine().getStatusCode()); assertEquals(200, response.getStatusLine().getStatusCode());
assertThat(resp, not(containsString("Resource has no id"))); assertThat(resp, not(containsString("Resource has no id")));
assertThat(resp, containsString("<pre>No issues detected during validation</pre>"));
assertThat(resp,
stringContainsInOrder("<issue>", "<severity value=\"information\"/>", "<code value=\"informational\"/>", "<diagnostics value=\"No issues detected during validation\"/>", "</issue>"));
} finally {
IOUtils.closeQuietly(response.getEntity().getContent());
response.close();
}
}
@Test
public void testValidateResourceWithNoIdRaw() throws IOException {
Patient patient = new Patient();
patient.addName().addGiven("James");
patient.setBirthDateElement(new DateType("2011-02-02"));
String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(patient);
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
CloseableHttpResponse response = ourHttpClient.execute(post);
try {
String resp = IOUtils.toString(response.getEntity().getContent());
ourLog.info(resp);
assertEquals(200, response.getStatusLine().getStatusCode());
assertThat(resp, not(containsString("Resource has no id")));
assertThat(resp, containsString("<pre>No issues detected during validation</pre>"));
assertThat(resp,
stringContainsInOrder("<issue>", "<severity value=\"information\"/>", "<code value=\"informational\"/>", "<diagnostics value=\"No issues detected during validation\"/>", "</issue>"));
} finally {
IOUtils.closeQuietly(response.getEntity().getContent());
response.close();
}
}
@Test
public void testValidateResourceBaseWithNoIdRaw() throws IOException {
Patient patient = new Patient();
patient.addName().addGiven("James");
patient.setBirthDateElement(new DateType("2011-02-02"));
patient.addContact().setGender(AdministrativeGender.MALE);
String inputStr = myFhirCtx.newXmlParser().encodeResourceToString(patient);
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
CloseableHttpResponse response = ourHttpClient.execute(post);
try {
String resp = IOUtils.toString(response.getEntity().getContent());
ourLog.info(resp);
assertEquals(412, response.getStatusLine().getStatusCode());
assertThat(resp, not(containsString("Resource has no id")));
assertThat(resp,
stringContainsInOrder(">ERROR<","/f:Patient/f:contact","<pre>SHALL at least contain a contact's details or a reference to an organization</pre>","<issue><severity value=\"error\"/>","<code value=\"processing\"/>","<diagnostics value=\"SHALL at least contain a contact's details or a reference to an organization\"/>","<location value=\"/f:Patient/f:contact\"/>"));
} finally { } finally {
IOUtils.closeQuietly(response.getEntity().getContent()); IOUtils.closeQuietly(response.getEntity().getContent());
response.close(); response.close();

View File

@ -88,6 +88,7 @@ public class FhirServerConfigDstu21 extends BaseJavaConfigDstu21 {
extraProperties.put("hibernate.search.default.directory_provider", "filesystem"); extraProperties.put("hibernate.search.default.directory_provider", "filesystem");
extraProperties.put("hibernate.search.default.indexBase", "target/lucenefiles"); extraProperties.put("hibernate.search.default.indexBase", "target/lucenefiles");
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT"); extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");
// extraProperties.put("hibernate.search.default.worker.execution", "async");
return extraProperties; return extraProperties;
} }

View File

@ -20,9 +20,14 @@
<version>1.4-SNAPSHOT</version> <version>1.4-SNAPSHOT</version>
</dependency> </dependency>
<!--
The JPA project uses a newer API but we'll try to hold to this version
as much as possible. See #283.
-->
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>

View File

@ -36,7 +36,6 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Conformance; import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.Conformance.Rest; import ca.uhn.fhir.model.dstu.resource.Conformance.Rest;
import ca.uhn.fhir.model.dstu.resource.Conformance.RestQuery; import ca.uhn.fhir.model.dstu.resource.Conformance.RestQuery;
@ -156,7 +155,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
String resourceName = next.getResourceName(); String resourceName = next.getResourceName();
RuntimeResourceDefinition def = myServerConfiguration.getFhirContext().getResourceDefinition(resourceName); RuntimeResourceDefinition def = myServerConfiguration.getFhirContext().getResourceDefinition(resourceName);
resource.getType().setValue(def.getName()); resource.getType().setValue(def.getName());
ServletContext servletContext = theRequest == null ? null : theRequest.getServletContext(); ServletContext servletContext = (ServletContext) (theRequest == null ? null : theRequest.getAttribute(RestfulServer.SERVLET_CONTEXT_ATTRIBUTE));
String serverBase = myServerConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest); String serverBase = myServerConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest);
resource.getProfile().setReference(new IdDt(def.getResourceProfile(serverBase))); resource.getProfile().setReference(new IdDt(def.getResourceProfile(serverBase)));

View File

@ -153,7 +153,7 @@ public class ResourceValidatorTest {
assertTrue(result.isSuccessful()); assertTrue(result.isSuccessful());
assertNotNull(operationOutcome); assertNotNull(operationOutcome);
assertEquals(0, operationOutcome.getIssue().size()); assertEquals(1, operationOutcome.getIssue().size());
} }
@Test @Test

View File

@ -26,9 +26,15 @@
<version>1.4-SNAPSHOT</version> <version>1.4-SNAPSHOT</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!--
The JPA project uses a newer API but we'll try to hold to this version
as much as possible. See #283.
-->
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>

View File

@ -85,8 +85,10 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
* Server FHIR Provider which serves the conformance statement for a RESTful server implementation * Server FHIR Provider which serves the conformance statement for a RESTful server implementation
* *
* <p> * <p>
* Note: This class is safe to extend, but it is important to note that the same instance of {@link Conformance} is always returned unless {@link #setCache(boolean)} is called with a value of * Note: This class is safe to extend, but it is important to note that the same instance of {@link Conformance} is
* <code>false</code>. This means that if you are adding anything to the returned conformance instance on each call you should call <code>setCache(false)</code> in your provider constructor. * always returned unless {@link #setCache(boolean)} is called with a value of <code>false</code>. This means that if
* you are adding anything to the returned conformance instance on each call you should call
* <code>setCache(false)</code> in your provider constructor.
* </p> * </p>
*/ */
public class ServerConformanceProvider implements IServerConformanceProvider<Conformance> { public class ServerConformanceProvider implements IServerConformanceProvider<Conformance> {
@ -101,22 +103,20 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
public ServerConformanceProvider(RestfulServer theRestfulServer) { public ServerConformanceProvider(RestfulServer theRestfulServer) {
this.myServerConfiguration = theRestfulServer.createConfiguration(); this.myServerConfiguration = theRestfulServer.createConfiguration();
} }
public ServerConformanceProvider(RestulfulServerConfiguration theServerConfiguration) { public ServerConformanceProvider(RestulfulServerConfiguration theServerConfiguration) {
this.myServerConfiguration = theServerConfiguration; this.myServerConfiguration = theServerConfiguration;
} }
/* /*
* Add a no-arg constructor and seetter so that the * Add a no-arg constructor and seetter so that the ServerConfirmanceProvider can be Spring-wired with the
* ServerConfirmanceProvider can be Spring-wired with * RestfulService avoiding the potential reference cycle that would happen.
* the RestfulService avoiding the potential reference
* cycle that would happen.
*/ */
public ServerConformanceProvider () { public ServerConformanceProvider() {
super(); super();
} }
public void setRestfulServer (RestfulServer theRestfulServer) { public void setRestfulServer(RestfulServer theRestfulServer) {
myServerConfiguration = theRestfulServer.createConfiguration(); myServerConfiguration = theRestfulServer.createConfiguration();
} }
@ -167,8 +167,9 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
} }
/** /**
* Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The * Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted. * mandatory element, the value should not be null (although this is not enforced). The value defaults to
* "Not provided" but may be set to null, which will cause this element to be omitted.
*/ */
public String getPublisher() { public String getPublisher() {
return myPublisher; return myPublisher;
@ -186,7 +187,8 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
retVal.setPublisher(myPublisher); retVal.setPublisher(myPublisher);
retVal.setDateElement(conformanceDate()); retVal.setDateElement(conformanceDate());
retVal.setFhirVersion("1.0.2"); // TODO: pull from model retVal.setFhirVersion("1.0.2"); // TODO: pull from model
retVal.setAcceptUnknown(UnknownContentCode.EXTENSIONS); // TODO: make this configurable - this is a fairly big effort since the parser retVal.setAcceptUnknown(UnknownContentCode.EXTENSIONS); // TODO: make this configurable - this is a fairly big
// effort since the parser
// needs to be modified to actually allow it // needs to be modified to actually allow it
retVal.getImplementation().setDescription(myServerConfiguration.getImplementationDescription()); retVal.getImplementation().setDescription(myServerConfiguration.getImplementationDescription());
@ -211,8 +213,8 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
String resourceName = nextEntry.getKey(); String resourceName = nextEntry.getKey();
RuntimeResourceDefinition def = myServerConfiguration.getFhirContext().getResourceDefinition(resourceName); RuntimeResourceDefinition def = myServerConfiguration.getFhirContext().getResourceDefinition(resourceName);
resource.getTypeElement().setValue(def.getName()); resource.getTypeElement().setValue(def.getName());
ServletContext servletContext = theRequest == null ? null : theRequest.getServletContext(); ServletContext servletContext = (ServletContext) (theRequest == null ? null : theRequest.getAttribute(RestfulServer.SERVLET_CONTEXT_ATTRIBUTE));
String serverBase = myServerConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest); String serverBase = myServerConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest);
resource.getProfile().setReference((def.getResourceProfile(serverBase))); resource.getProfile().setReference((def.getResourceProfile(serverBase)));
TreeSet<String> includes = new TreeSet<String>(); TreeSet<String> includes = new TreeSet<String>();
@ -441,7 +443,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
if (targetDef != null) { if (targetDef != null) {
ResourceType code; ResourceType code;
try { try {
code = ResourceType.fromCode(targetDef.getName()); code = ResourceType.fromCode(targetDef.getName());
} catch (FHIRException e) { } catch (FHIRException e) {
code = null; code = null;
} }
@ -561,8 +563,9 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
} }
/** /**
* Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The * Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted. * mandatory element, the value should not be null (although this is not enforced). The value defaults to
* "Not provided" but may be set to null, which will cause this element to be omitted.
*/ */
public void setPublisher(String thePublisher) { public void setPublisher(String thePublisher) {
myPublisher = thePublisher; myPublisher = thePublisher;

View File

@ -126,51 +126,43 @@ public abstract class BaseDateTimeType extends PrimitiveType<Date> {
if (theValue == null) { if (theValue == null) {
return null; return null;
} else { } else {
GregorianCalendar cal;
if (myTimeZoneZulu) {
cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
} else if (myTimeZone != null) {
cal = new GregorianCalendar(myTimeZone);
} else {
cal = new GregorianCalendar();
}
cal.setTime(theValue);
switch (myPrecision) { switch (myPrecision) {
case DAY: case DAY:
return ourYearMonthDayFormat.format(theValue); return ourYearMonthDayFormat.format(cal);
case MONTH: case MONTH:
return ourYearMonthFormat.format(theValue); return ourYearMonthFormat.format(cal);
case YEAR: case YEAR:
return ourYearFormat.format(theValue); return ourYearFormat.format(cal);
case MINUTE: case MINUTE:
if (myTimeZoneZulu) { if (myTimeZoneZulu) {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
cal.setTime(theValue);
return ourYearMonthDayTimeMinsFormat.format(cal) + "Z"; return ourYearMonthDayTimeMinsFormat.format(cal) + "Z";
} else if (myTimeZone != null) {
GregorianCalendar cal = new GregorianCalendar(myTimeZone);
cal.setTime(theValue);
return (ourYearMonthDayTimeMinsZoneFormat.format(cal));
} else { } else {
return ourYearMonthDayTimeMinsFormat.format(theValue); return ourYearMonthDayTimeMinsZoneFormat.format(cal);
} }
case SECOND: case SECOND:
if (myTimeZoneZulu) { if (myTimeZoneZulu) {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
cal.setTime(theValue);
return ourYearMonthDayTimeFormat.format(cal) + "Z"; return ourYearMonthDayTimeFormat.format(cal) + "Z";
} else if (myTimeZone != null) {
GregorianCalendar cal = new GregorianCalendar(myTimeZone);
cal.setTime(theValue);
return (ourYearMonthDayTimeZoneFormat.format(cal));
} else { } else {
return ourYearMonthDayTimeFormat.format(theValue); return ourYearMonthDayTimeZoneFormat.format(cal);
} }
case MILLI: case MILLI:
if (myTimeZoneZulu) { if (myTimeZoneZulu) {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
cal.setTime(theValue);
return ourYearMonthDayTimeMilliFormat.format(cal) + "Z"; return ourYearMonthDayTimeMilliFormat.format(cal) + "Z";
} else if (myTimeZone != null) {
GregorianCalendar cal = new GregorianCalendar(myTimeZone);
cal.setTime(theValue);
return (ourYearMonthDayTimeMilliZoneFormat.format(cal));
} else { } else {
return ourYearMonthDayTimeMilliFormat.format(theValue); return ourYearMonthDayTimeMilliZoneFormat.format(cal);
} }
} }
throw new IllegalStateException("Invalid precision (this is a bug, shouldn't happen): " + myPrecision); throw new IllegalStateException("Invalid precision (this is a HAPI bug, shouldn't happen): " + myPrecision);
} }
} }

View File

@ -29,11 +29,14 @@ POSSIBILITY OF SUCH DAMAGE.
package org.hl7.fhir.dstu21.model; package org.hl7.fhir.dstu21.model;
import java.util.Calendar;
/** /**
* Primitive type "date" in FHIR: any day in a gregorian calendar * Primitive type "date" in FHIR: any day in a gregorian calendar
*/ */
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone; import java.util.TimeZone;
import ca.uhn.fhir.model.api.annotation.DatatypeDef; import ca.uhn.fhir.model.api.annotation.DatatypeDef;
@ -95,6 +98,33 @@ public class DateType extends BaseDateTimeType {
super(theDate); super(theDate);
} }
/**
* Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
*/
public DateType(Calendar theCalendar) {
super(theCalendar.getTime(), DEFAULT_PRECISION);
setTimeZone(theCalendar.getTimeZone());
}
/**
* Constructor which accepts a date value and uses the {@link #DEFAULT_PRECISION} for this type.
*
* @param theYear The year, e.g. 2015
* @param theMonth The month, e.g. 0 for January
* @param theDay The day (1 indexed) e.g. 1 for the first day of the month
*/
public DateType(int theYear, int theMonth, int theDay) {
this(toCalendarZulu(theYear, theMonth, theDay));
}
private static GregorianCalendar toCalendarZulu(int theYear, int theMonth, int theDay) {
GregorianCalendar retVal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
retVal.set(Calendar.YEAR, theYear);
retVal.set(Calendar.MONTH, theMonth);
retVal.set(Calendar.DATE, theDay);
return retVal;
}
@Override @Override
boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) { boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision) {
switch (thePrecision) { switch (thePrecision) {

View File

@ -0,0 +1,105 @@
package ca.uhn.fhir.model;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.hl7.fhir.dstu21.model.DateTimeType;
import org.hl7.fhir.dstu21.model.DateType;
import org.hl7.fhir.dstu21.model.TemporalPrecisionEnum;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class BaseDateTimeTypeDstu21Test {
private static Locale ourDefaultLocale;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseDateTimeTypeDstu21Test.class);
private SimpleDateFormat myDateInstantParser;
@Before
public void before() {
myDateInstantParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
}
/**
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
*/
@Test
public void testPrecisionRespectedForSetValue() throws Exception {
Calendar cal = Calendar.getInstance();
cal.setTime(myDateInstantParser.parse("2012-01-02 22:31:02.333"));
cal.setTimeZone(TimeZone.getTimeZone("EST"));
Date time = cal.getTime();
DateType date = new DateType();
date.setValue(time);
assertEquals("2012-01-02", date.getValueAsString());
}
@Test
public void testMinutePrecisionEncode() throws Exception {
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
cal.set(1990, Calendar.JANUARY, 3, 3, 22, 11);
DateTimeType date = new DateTimeType();
date.setValue(cal.getTime(), TemporalPrecisionEnum.MINUTE);
date.setTimeZone(TimeZone.getTimeZone("EST"));
assertEquals("1990-01-02T21:22-05:00", date.getValueAsString());
date.setTimeZoneZulu(true);
assertEquals("1990-01-03T02:22Z", date.getValueAsString());
}
/**
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
*/
@Test
public void testPrecisionRespectedForSetValueWithPrecision() throws Exception {
Calendar cal = Calendar.getInstance();
cal.setTime(myDateInstantParser.parse("2012-01-02 22:31:02.333"));
cal.setTimeZone(TimeZone.getTimeZone("EST"));
Date time = cal.getTime();
DateType date = new DateType();
date.setValue(time, TemporalPrecisionEnum.DAY);
assertEquals("2012-01-02", date.getValueAsString());
}
@Test
public void testToHumanDisplay() {
DateTimeType dt = new DateTimeType("2012-01-05T12:00:00-08:00");
String human = dt.toHumanDisplay();
ourLog.info(human);
assertThat(human, containsString("2012"));
assertThat(human, containsString("12"));
}
public static void afterClass() {
Locale.setDefault(ourDefaultLocale);
}
@BeforeClass
public static void beforeClass() {
/*
* We cache the default locale, but temporarily set it to a random value during this test. This helps ensure
* that there are no language specific dependencies in the test.
*/
ourDefaultLocale = Locale.getDefault();
Locale[] available = { Locale.CANADA, Locale.GERMANY, Locale.TAIWAN };
Locale newLocale = available[(int) (Math.random() * available.length)];
Locale.setDefault(newLocale);
ourLog.info("Tests are running in locale: " + newLocale.getDisplayName());
}
}

View File

@ -0,0 +1,52 @@
package ca.uhn.fhir.model;
import static org.junit.Assert.assertEquals;
import java.util.Calendar;
import java.util.TimeZone;
import org.hl7.fhir.dstu21.model.DateType;
import org.junit.Test;
public class DateTypeTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DateTypeTest.class);
@Test
public void testPrecision() {
// ourLog.info(""+ new TreeSet<String>(Arrays.asList(TimeZone.getAvailableIDs())));
final Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
cal.set(1990, Calendar.JANUARY, 1, 0, 0, 0);
ourLog.info("Time: {}", cal); // 631152000775
DateType dateDt = new DateType(cal.getTime());
long time = dateDt.getValue().getTime();
ourLog.info("Time: {}", time); // 631152000775
ourLog.info("Time: {}", dateDt.getValue()); // 631152000775
dateDt.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
time = dateDt.getValue().getTime();
ourLog.info("Time: {}", time); // 631152000775
ourLog.info("Time: {}", dateDt.getValue()); // 631152000775
String valueAsString = dateDt.getValueAsString();
ourLog.info(valueAsString);
// is 631152000030
}
@Test
public void testConstructors() {
final Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
cal.set(1990, Calendar.JANUARY, 5, 0, 0, 0);
DateType dateDt = new DateType(cal);
assertEquals("1990-01-05", dateDt.getValueAsString());
dateDt = new DateType(1990, 0, 5);
assertEquals("1990-01-05", dateDt.getValueAsString());
}
}

File diff suppressed because it is too large Load Diff

View File

@ -27,9 +27,14 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!--
The JPA project uses a newer API but we'll try to hold to this version
as much as possible. See #283.
-->
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>

View File

@ -206,7 +206,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
String resourceName = nextEntry.getKey(); String resourceName = nextEntry.getKey();
RuntimeResourceDefinition def = myServerConfiguration.getFhirContext().getResourceDefinition(resourceName); RuntimeResourceDefinition def = myServerConfiguration.getFhirContext().getResourceDefinition(resourceName);
resource.getTypeElement().setValue(def.getName()); resource.getTypeElement().setValue(def.getName());
ServletContext servletContext = theRequest == null ? null : theRequest.getServletContext(); ServletContext servletContext = (ServletContext) (theRequest == null ? null : theRequest.getAttribute(RestfulServer.SERVLET_CONTEXT_ATTRIBUTE));
String serverBase = myServerConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest); String serverBase = myServerConfiguration.getServerAddressStrategy().determineServerBase(servletContext, theRequest);
resource.getProfile().setReference(new IdDt(def.getResourceProfile(serverBase))); resource.getProfile().setReference(new IdDt(def.getResourceProfile(serverBase)));

View File

@ -41,6 +41,21 @@ public class BaseDateTimeDtDstu2Test {
assertEquals("2012-01-02", date.getValueAsString()); assertEquals("2012-01-02", date.getValueAsString());
} }
@Test
public void testMinutePrecisionEncode() throws Exception {
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
cal.set(1990, Calendar.JANUARY, 3, 3, 22, 11);
DateTimeDt date = new DateTimeDt();
date.setValue(cal.getTime(), TemporalPrecisionEnum.MINUTE);
date.setTimeZone(TimeZone.getTimeZone("EST"));
assertEquals("1990-01-02T21:22-05:00", date.getValueAsString());
date.setTimeZoneZulu(true);
assertEquals("1990-01-03T02:22Z", date.getValueAsString());
}
/** /**
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101 * See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
*/ */

View File

@ -0,0 +1,55 @@
package ca.uhn.fhir.model.primitive;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.TreeSet;
import org.junit.Test;
public class DateDtTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DateDtTest.class);
@Test
public void testPrecision() {
// ourLog.info(""+ new TreeSet<String>(Arrays.asList(TimeZone.getAvailableIDs())));
final Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
cal.set(1990, Calendar.JANUARY, 1, 0, 0, 0);
ourLog.info("Time: {}", cal); // 631152000775
DateDt dateDt = new DateDt(cal.getTime());
long time = dateDt.getValue().getTime();
ourLog.info("Time: {}", time); // 631152000775
ourLog.info("Time: {}", dateDt.getValue()); // 631152000775
dateDt.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
time = dateDt.getValue().getTime();
ourLog.info("Time: {}", time); // 631152000775
ourLog.info("Time: {}", dateDt.getValue()); // 631152000775
String valueAsString = dateDt.getValueAsString();
ourLog.info(valueAsString);
// is 631152000030
}
@Test
public void testConstructors() {
final Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
cal.set(1990, Calendar.JANUARY, 5, 0, 0, 0);
DateDt dateDt = new DateDt(cal);
assertEquals("1990-01-05", dateDt.getValueAsString());
dateDt = new DateDt(1990, 0, 5);
assertEquals("1990-01-05", dateDt.getValueAsString());
}
}

View File

@ -0,0 +1,29 @@
package ca.uhn.fhir.parser;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.dstu2.resource.Conformance;
import ca.uhn.fhir.model.dstu2.resource.Conformance.RestSecurity;
public class ExtensionsDstu2Test {
private static final FhirContext ourCtx = FhirContext.forDstu2();
@Test
public void testParseExtensions() throws Exception {
String input = IOUtils.toString(getClass().getResourceAsStream("/smart-conf.xml"));
Conformance conf = (Conformance) ourCtx.newXmlParser().parseResource(input);
RestSecurity sec = conf.getRest().get(0).getSecurity();
List<ExtensionDt> uris = sec.getUndeclaredExtensionsByUrl("http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris");
assertEquals(1, uris.size());
}
}

View File

@ -132,7 +132,7 @@ public class ResourceValidatorDstu2Test {
assertTrue(result.toString(), result.isSuccessful()); assertTrue(result.toString(), result.isSuccessful());
assertNotNull(operationOutcome); assertNotNull(operationOutcome);
assertEquals(0, operationOutcome.getIssue().size()); assertEquals(1, operationOutcome.getIssue().size());
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")

File diff suppressed because it is too large Load Diff

View File

@ -26,13 +26,18 @@
<version>1.4-SNAPSHOT</version> <version>1.4-SNAPSHOT</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!--
The JPA project uses a newer API but we'll try to hold to this version
as much as possible. See #283.
-->
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- <dependency> <groupId>net.sf.saxon</groupId> <artifactId>saxon</artifactId> <!-- <dependency> <groupId>net.sf.saxon</groupId> <artifactId>saxon</artifactId>
<version>8.7</version> </dependency> --> <version>8.7</version> </dependency> -->

View File

@ -109,7 +109,6 @@ public class Controller extends BaseController {
return "result"; return "result";
} }
@SuppressWarnings("unchecked")
@RequestMapping(value = { "/delete" }) @RequestMapping(value = { "/delete" })
public String actionDelete(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) { public String actionDelete(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
addCommonParams(theReq, theRequest, theModel); addCommonParams(theReq, theRequest, theModel);

View File

@ -248,7 +248,6 @@
<hibernate_version>5.0.6.Final</hibernate_version> <hibernate_version>5.0.6.Final</hibernate_version>
<hibernate_validator_version>5.2.2.Final</hibernate_validator_version> <hibernate_validator_version>5.2.2.Final</hibernate_validator_version>
<maven_assembly_plugin_version>2.5.3</maven_assembly_plugin_version> <maven_assembly_plugin_version>2.5.3</maven_assembly_plugin_version>
<maven_failsafe_plugin_version>2.18.1</maven_failsafe_plugin_version>
<maven_license_plugin_version>1.8</maven_license_plugin_version> <maven_license_plugin_version>1.8</maven_license_plugin_version>
<maven_site_plugin_version>3.4</maven_site_plugin_version> <maven_site_plugin_version>3.4</maven_site_plugin_version>
<maven_source_plugin_version>2.4</maven_source_plugin_version> <maven_source_plugin_version>2.4</maven_source_plugin_version>
@ -731,7 +730,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId> <artifactId>maven-failsafe-plugin</artifactId>
<version>2.19</version> <version>2.19.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -741,7 +740,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version> <version>2.19.1</version>
<configuration> <configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile> <redirectTestOutputToFile>true</redirectTestOutputToFile>
<runOrder>random</runOrder> <runOrder>random</runOrder>
@ -1314,7 +1313,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId> <artifactId>maven-surefire-report-plugin</artifactId>
<version>2.19</version> <version>2.19.1</version>
<reportSets> <reportSets>
<reportSet> <reportSet>
<reports> <reports>

View File

@ -139,6 +139,12 @@
implementations and wasn't compatible implementations and wasn't compatible
with coming changes to that API. with coming changes to that API.
</action> </action>
<action type="fix" issue="283">
Remove dependency on Servlet-API 3.0+ by using methods available in 2.5 where possible.
Note that we continue to use Servlet-API 3.0+ features in some parts of the JPA API, so
running in an old serlvet container should be tested well before use. Thanks to Bill Denton
for reporting!
</action>
</release> </release>
<release version="1.3" date="2015-11-14"> <release version="1.3" date="2015-11-14">
<action type="add"> <action type="add">

View File

@ -13,7 +13,7 @@
<b>hapi-fhir-cli</b> is the HAPI FHIR Command Line tool. It features a number of HAPI's <b>hapi-fhir-cli</b> is the HAPI FHIR Command Line tool. It features a number of HAPI's
built-in features as easy to use command line options. built-in features as easy to use command line options.
</p> </p>
<subsection name="Download and Installation"> <subsection name="Download and Installation">
<p> <p>
You can get the tool by downloading it from our You can get the tool by downloading it from our
@ -35,7 +35,12 @@
<subsection name="Troubleshooting"> <subsection name="Troubleshooting">
<p> <p>
The tool should work correctly on any system that has Java 6 (or newer) installed. If <b>Note on Java version support:</b> The HAPI library is designed to
work in Java 6+, but the Command Line Tool required a minimum of Java 8. This
is because the Jetty Web Server that is used within the tool has this requirement.
</p>
<p>
The tool should work correctly on any system that has Java 8 (or newer) installed. If
it is not working correctly, first try the following command to test if Java is installed:<br/> it is not working correctly, first try the following command to test if Java is installed:<br/>
<code>$ java -version</code> <code>$ java -version</code>
</p> </p>