From 79bdd94f72fe4e62f4a423e491aa87f9222ee66b Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Fri, 21 Mar 2014 08:12:44 -0400 Subject: [PATCH] Some unit test fixes, still some failures --- .../java/ca/uhn/fhir/context/FhirContext.java | 3 + .../fhir/model/api/TemporalPrecisionEnum.java | 44 +++++- .../java/ca/uhn/fhir/parser/BaseParser.java | 3 +- .../main/java/ca/uhn/fhir/parser/IParser.java | 2 +- .../java/ca/uhn/fhir/parser/JsonParser.java | 148 +++++++++--------- .../java/ca/uhn/fhir/parser/ParserState.java | 4 +- .../java/ca/uhn/fhir/parser/XmlParser.java | 10 +- .../uhn/fhir/rest/param/DateRangeParam.java | 35 ++++- .../java/example/FhirContextIntro.java | 9 +- .../RestfulPatientResourceProviderMore.java | 17 ++ .../src/site/xdoc/doc_rest_operations.xml | 48 +++++- .../ca/uhn/fhir/parser/JsonParserTest.java | 4 +- .../ca/uhn/fhir/parser/XmlParserTest.java | 2 +- .../fhir/rest/param/DateRangeParamTest.java | 84 ++++++++++ 14 files changed, 309 insertions(+), 104 deletions(-) create mode 100644 hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java index b81c6900726..a519c273846 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java @@ -27,6 +27,9 @@ public class FhirContext { this(toCollection(theResourceType)); } + public FhirContext() { + } + public FhirContext(Class... theResourceTypes) { this(toCollection(theResourceTypes)); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/TemporalPrecisionEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/TemporalPrecisionEnum.java index 2bf8ef416e3..2e27f092a4c 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/TemporalPrecisionEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/TemporalPrecisionEnum.java @@ -1,14 +1,45 @@ package ca.uhn.fhir.model.api; import java.util.Calendar; +import java.util.Date; + +import org.apache.commons.lang3.time.DateUtils; public enum TemporalPrecisionEnum { - YEAR(Calendar.YEAR), - MONTH(Calendar.MONTH), - DAY(Calendar.DATE), - SECOND(Calendar.SECOND), - MILLI(Calendar.MILLISECOND), + YEAR(Calendar.YEAR) { + @Override + public Date add(Date theInput, int theAmount) { + return DateUtils.addYears(theInput, theAmount); + } + }, + + MONTH(Calendar.MONTH) { + @Override + public Date add(Date theInput, int theAmount) { + return DateUtils.addMonths(theInput, theAmount); + } + }, + DAY(Calendar.DATE) { + @Override + public Date add(Date theInput, int theAmount) { + return DateUtils.addDays(theInput, theAmount); + } + }, + SECOND(Calendar.SECOND) { + @Override + public Date add(Date theInput, int theAmount) { + return DateUtils.addSeconds(theInput, theAmount); + } + }, + + MILLI(Calendar.MILLISECOND) { + @Override + public Date add(Date theInput, int theAmount) { + return DateUtils.addMilliseconds(theInput, theAmount); + } + }, + ; private int myCalendarConstant; @@ -17,7 +48,10 @@ public enum TemporalPrecisionEnum { myCalendarConstant = theCalendarConstant; } + public abstract Date add(Date theInput, int theAmount); + public int getCalendarConstant() { return myCalendarConstant; } + } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java index 1332244444c..1f17d9b35ed 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java @@ -30,6 +30,7 @@ public abstract class BaseParser implements IParser { public IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException { return parseResource(null, theReader); } + public void containResourcesForEncoding(IResource theResource) { List allElements = theResource.getAllPopulatedChildElementsOfType(ResourceReferenceDt.class); @@ -46,7 +47,7 @@ public abstract class BaseParser implements IParser { theResource.getContained().getContainedResources().add(resource); allIds.add(resource.getId().getValue()); } - + next.setReference("#" + resource.getId().getValue()); } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/IParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/IParser.java index 1276c2b23f8..df0f387102a 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/IParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/IParser.java @@ -28,7 +28,7 @@ public interface IParser { T parseResource(Class theResourceType, String theMessageString); - IResource parseResource(Class theResourceType, Reader theReader); + T parseResource(Class theResourceType, Reader theReader); IParser setPrettyPrint(boolean thePrettyPrint); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java index ca9ae7daf05..8035860fa08 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java @@ -4,6 +4,7 @@ import static org.apache.commons.lang3.StringUtils.*; import java.io.IOException; import java.io.Reader; +import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; @@ -65,21 +66,6 @@ public class JsonParser extends BaseParser implements IParser { return stringWriter.toString(); } - private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, StringDt theStringDt) { - if (StringUtils.isNotBlank(theStringDt.getValue())) { - theEventWriter.write(theElementName, theStringDt.getValue()); - } else { - theEventWriter.writeNull(theElementName); - } - } - - private void writeOptionalTagWithTextNode(JsonGenerator theEventWriter, String theElementName, IPrimitiveDatatype theInstantDt) { - String str = theInstantDt.getValueAsString(); - if (StringUtils.isNotBlank(str)) { - theEventWriter.write(theElementName, theInstantDt.getValueAsString()); - } - } - @Override public void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws IOException { JsonGenerator eventWriter = createJsonGenerator(theWriter); @@ -132,26 +118,6 @@ public class JsonParser extends BaseParser implements IParser { eventWriter.close(); } - private void writeAuthor(BaseBundle theBundle, JsonGenerator eventWriter) { - if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) { - eventWriter.writeStartArray("author"); - eventWriter.writeStartObject(); - writeTagWithTextNode(eventWriter, "name", theBundle.getAuthorName()); - writeOptionalTagWithTextNode(eventWriter, "uri", theBundle.getAuthorUri()); - eventWriter.writeEnd(); - eventWriter.writeEnd(); - } - } - - private void writeAtomLink(JsonGenerator theEventWriter, String theRel, StringDt theLink) { - if (isNotBlank(theLink.getValue())) { - theEventWriter.writeStartObject(); - theEventWriter.write("rel", theRel); - theEventWriter.write("href", theLink.getValue()); - theEventWriter.writeEnd(); - } - } - @Override public String encodeResourceToString(IResource theResource) throws DataFormatException, IOException { Writer stringWriter = new StringWriter(); @@ -172,16 +138,6 @@ public class JsonParser extends BaseParser implements IParser { // } } - private JsonGenerator createJsonGenerator(Writer theWriter) { - Map properties = new HashMap(1); - if (myPrettyPrint) { - properties.put(JsonGenerator.PRETTY_PRINTING, myPrettyPrint); - } - JsonGeneratorFactory jgf = Json.createGeneratorFactory(properties); - JsonGenerator eventWriter = jgf.createGenerator(theWriter); - return eventWriter; - } - @Override public Bundle parseBundle(Reader theReader) { // TODO Auto-generated method stub @@ -195,24 +151,29 @@ public class JsonParser extends BaseParser implements IParser { } @Override - public IResource parseResource(Class theResourceType, Reader theReader) { + public T parseResource(Class theResourceType, String theMessageString) { + return parseResource(theResourceType, new StringReader(theMessageString)); + } + + @Override + public T parseResource(Class theResourceType, Reader theReader) { JsonReader reader = Json.createReader(theReader); JsonObject object = reader.readObject(); - - JsonValue resourceTypeObj = object.remove("resourceType"); + + JsonValue resourceTypeObj = object.get("resourceType"); assertObjectOfType(resourceTypeObj, JsonValue.ValueType.STRING, "resourceType"); - String resourceType = ((JsonString)resourceTypeObj).getString(); - + String resourceType = ((JsonString) resourceTypeObj).getString(); + if (theResourceType != null) { RuntimeResourceDefinition def = myContext.getResourceDefinition(theResourceType); - }else { + } else { RuntimeResourceDefinition def = myContext.getResourceDefinition(resourceType); } - + PushbackJsonParser parser = new PushbackJsonParser(Json.createParser(theReader)); - + while (parser.hasNext()) { - + Event next = parser.next(); switch (next) { case END_ARRAY: @@ -236,28 +197,14 @@ public class JsonParser extends BaseParser implements IParser { break; default: break; - + } - - + } - + return null; } - private void assertObjectOfType(JsonValue theResourceTypeObj, ValueType theValueType, String thePosition) { - if (theResourceTypeObj.getValueType() != theValueType) { - throw new DataFormatException("Invalid content of element " + thePosition + ", expected " + theValueType); - } - } - - @Override - public T parseResource(Class theResourceType, String theMessageString) { - // TODO Auto-generated method stub - return null; - } - - @Override public IParser setPrettyPrint(boolean thePrettyPrint) { myPrettyPrint = thePrettyPrint; @@ -279,6 +226,22 @@ public class JsonParser extends BaseParser implements IParser { } } + private void assertObjectOfType(JsonValue theResourceTypeObj, ValueType theValueType, String thePosition) { + if (theResourceTypeObj.getValueType() != theValueType) { + throw new DataFormatException("Invalid content of element " + thePosition + ", expected " + theValueType); + } + } + + private JsonGenerator createJsonGenerator(Writer theWriter) { + Map properties = new HashMap(1); + if (myPrettyPrint) { + properties.put(JsonGenerator.PRETTY_PRINTING, myPrettyPrint); + } + JsonGeneratorFactory jgf = Json.createGeneratorFactory(properties); + JsonGenerator eventWriter = jgf.createGenerator(theWriter); + return eventWriter; + } + private void encodeChildElementToStreamWriter(JsonGenerator theWriter, IElement theValue, BaseRuntimeElementDefinition theChildDef, String theChildName) throws IOException { switch (theChildDef.getChildType()) { @@ -318,7 +281,7 @@ public class JsonParser extends BaseParser implements IParser { if (theChildName != null) { theWriter.writeStartObject(theChildName); } else { - theWriter.flush();//TODO: remove + theWriter.flush();// TODO: remove theWriter.writeStartObject(); } encodeCompositeElementToStreamWriter(theValue, theWriter, childCompositeDef); @@ -424,7 +387,7 @@ public class JsonParser extends BaseParser implements IParser { } currentChildName = childName; } else { - theEventWriter.flush();//TODO: remove + theEventWriter.flush();// TODO: remove encodeChildElementToStreamWriter(theEventWriter, nextValue, childDef, null); } @@ -462,7 +425,7 @@ public class JsonParser extends BaseParser implements IParser { } if (!haveContent) { -// theEventWriter.writeEnd(); + // theEventWriter.writeEnd(); theEventWriter.flush(); // TODO: remove theEventWriter.writeNull(); } @@ -520,7 +483,7 @@ public class JsonParser extends BaseParser implements IParser { } theEventWriter.write("resourceType", resDef.getName()); - if (theResource.getId() !=null && isNotBlank(theResource.getId().getValue())) { + if (theResource.getId() != null && isNotBlank(theResource.getId().getValue())) { theEventWriter.write("id", theResource.getId().getValue()); } @@ -559,6 +522,41 @@ public class JsonParser extends BaseParser implements IParser { theWriter.writeEnd(); } + private void writeAtomLink(JsonGenerator theEventWriter, String theRel, StringDt theLink) { + if (isNotBlank(theLink.getValue())) { + theEventWriter.writeStartObject(); + theEventWriter.write("rel", theRel); + theEventWriter.write("href", theLink.getValue()); + theEventWriter.writeEnd(); + } + } + + private void writeAuthor(BaseBundle theBundle, JsonGenerator eventWriter) { + if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) { + eventWriter.writeStartArray("author"); + eventWriter.writeStartObject(); + writeTagWithTextNode(eventWriter, "name", theBundle.getAuthorName()); + writeOptionalTagWithTextNode(eventWriter, "uri", theBundle.getAuthorUri()); + eventWriter.writeEnd(); + eventWriter.writeEnd(); + } + } + + private void writeOptionalTagWithTextNode(JsonGenerator theEventWriter, String theElementName, IPrimitiveDatatype theInstantDt) { + String str = theInstantDt.getValueAsString(); + if (StringUtils.isNotBlank(str)) { + theEventWriter.write(theElementName, theInstantDt.getValueAsString()); + } + } + + private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, StringDt theStringDt) { + if (StringUtils.isNotBlank(theStringDt.getValue())) { + theEventWriter.write(theElementName, theStringDt.getValue()); + } else { + theEventWriter.writeNull(theElementName); + } + } + private class HeldExtension { private UndeclaredExtension myUndeclaredExtension; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java index 5cd3a9aac12..cee0fa9b9b5 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java @@ -115,8 +115,8 @@ class ParserState { * @param theResourceType * May be null */ - public static ParserState getPreResourceInstance(Class theResourceType, FhirContext theContext) throws DataFormatException { - ParserState retVal = new ParserState(theContext); + public static ParserState getPreResourceInstance(Class theResourceType, FhirContext theContext) throws DataFormatException { + ParserState retVal = new ParserState(theContext); retVal.push(retVal.new PreResourceState(theResourceType)); return retVal; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java index 01a7ce9947b..32f9a9ef815 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java @@ -138,6 +138,10 @@ public class XmlParser extends BaseParser implements IParser { @Override public String encodeResourceToString(IResource theResource) throws DataFormatException { + if (theResource==null) { + throw new NullPointerException("Resource can not be null"); + } + Writer stringWriter = new StringWriter(); encodeResourceToWriter(theResource, stringWriter); return stringWriter.toString(); @@ -183,7 +187,7 @@ public class XmlParser extends BaseParser implements IParser { } @Override - public IResource parseResource(Class theResourceType, Reader theReader) { + public T parseResource(Class theResourceType, Reader theReader) { XMLEventReader streamReader; try { streamReader = myXmlInputFactory.createXMLEventReader(theReader); @@ -545,8 +549,8 @@ public class XmlParser extends BaseParser implements IParser { return doXmlLoop(theStreamReader, parserState); } - private IResource parseResource(Class theResourceType, XMLEventReader theStreamReader) { - ParserState parserState = ParserState.getPreResourceInstance(theResourceType, myContext); + private T parseResource(Class theResourceType, XMLEventReader theStreamReader) { + ParserState parserState = ParserState.getPreResourceInstance(theResourceType, myContext); return doXmlLoop(theStreamReader, parserState); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java index b856ce05ba1..d4ca2d95c9b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java @@ -6,6 +6,7 @@ import java.util.Date; import java.util.List; import ca.uhn.fhir.model.api.IQueryParameterAnd; +import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class DateRangeParam implements IQueryParameterAnd { @@ -91,13 +92,39 @@ public class DateRangeParam implements IQueryParameterAnd { } public Date getLowerBoundAsInstant() { - // TODO: account for precision - return myLowerBound.getValue(); + Date retVal = myLowerBound.getValue(); + if (myLowerBound.getComparator() != null) { + switch (myLowerBound.getComparator()) { + case GREATERTHAN: + retVal = myLowerBound.getPrecision().add(retVal, 1); + break; + case GREATERTHAN_OR_EQUALS: + break; + case LESSTHAN: + case LESSTHAN_OR_EQUALS: + throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getComparator()); + } + } + return retVal; } public Date getUpperBoundAsInstant() { - // TODO: account for precision - return myUpperBound.getValue(); + Date retVal = myUpperBound.getValue(); + if (myUpperBound.getComparator() != null) { + switch (myUpperBound.getComparator()) { + case LESSTHAN: + retVal = new Date(retVal.getTime() - 1L); + break; + case LESSTHAN_OR_EQUALS: + retVal = myUpperBound.getPrecision().add(retVal, 1); + retVal = new Date(retVal.getTime() - 1L); + break; + case GREATERTHAN_OR_EQUALS: + case GREATERTHAN: + throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getComparator()); + } + } + return retVal; } } diff --git a/hapi-fhir-base/src/site/example/java/example/FhirContextIntro.java b/hapi-fhir-base/src/site/example/java/example/FhirContextIntro.java index 2e131ce1550..661bc7f9c85 100644 --- a/hapi-fhir-base/src/site/example/java/example/FhirContextIntro.java +++ b/hapi-fhir-base/src/site/example/java/example/FhirContextIntro.java @@ -17,12 +17,7 @@ public class FhirContextIntro { public static void creatingContext() { // START SNIPPET: creatingContext -/* - * Create a FhirContex instance which is able to parse and encode - * the Patient and Observation resources, and any resources referenced - * from these. - */ -FhirContext ctx = new FhirContext(Patient.class, Observation.class); +FhirContext ctx = new FhirContext(); // END SNIPPET: creatingContext } @@ -103,7 +98,7 @@ StringDt familyName = patient.getName().get(0).getFamily().get(0); CodeDt gender = patient.getGender().getCoding().get(0).getCode(); /* - * The + * The various datatype classes have accessors called getValue() */ System.out.println(patientId.getValue()); // PRP1660 System.out.println(familyName.getValue()); // Cardinal diff --git a/hapi-fhir-base/src/site/example/java/example/RestfulPatientResourceProviderMore.java b/hapi-fhir-base/src/site/example/java/example/RestfulPatientResourceProviderMore.java index 8f571199707..9bcecb75209 100644 --- a/hapi-fhir-base/src/site/example/java/example/RestfulPatientResourceProviderMore.java +++ b/hapi-fhir-base/src/site/example/java/example/RestfulPatientResourceProviderMore.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.rest.annotation.Required; import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.client.ITestClient; import ca.uhn.fhir.rest.param.CodingListParam; +import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.QualifiedDateParam; import ca.uhn.fhir.rest.server.IResourceProvider; @@ -161,6 +162,22 @@ public List getDiagnosticReport( @Required(name=DiagnosticRepo } //END SNIPPET: pathSpec +//START SNIPPET: dateRange +@Search() +public List getObservationsByDateRange(@Required(name="subject.identifier") IdentifierDt theSubjectId, + @Required(name=Observation.SP_DATE) DateRangeParam theRange) { + List retVal = new ArrayList(); + + // The following two will be set as the start and end + // of the range specified by the query parameter + Date from = theRange.getLowerBoundAsInstant(); + Date to = theRange.getUpperBoundAsInstant(); + + // ... populate ... + return retVal; +} +//END SNIPPET: dateRange + private DiagnosticReport loadSomeDiagnosticReportFromDatabase(IdentifierDt theIdentifier) { return null; } diff --git a/hapi-fhir-base/src/site/xdoc/doc_rest_operations.xml b/hapi-fhir-base/src/site/xdoc/doc_rest_operations.xml index 2a1523a4e27..cee6662b814 100644 --- a/hapi-fhir-base/src/site/xdoc/doc_rest_operations.xml +++ b/hapi-fhir-base/src/site/xdoc/doc_rest_operations.xml @@ -159,15 +159,15 @@ may be optional. To add a second required parameter, annotate the parameter with @Required. - To add an optional parameter (which will be pased in as null if no value + To add an optional parameter (which will be passed in as null if no value is supplied), annotate the method with @Optional.

You may annotate a method with any combination of as many @Required and as many @Optional - parameters as you want. It is valid to have no @Required parameters, or - no @Optional parameters as well. + parameters as you want. It is valid to have only @Required parameters, or + only @Optional parameters, or any combination of the two.

@@ -230,7 +230,7 @@ - +

The FHIR specification provides a sytax for specifying @@ -270,6 +270,46 @@ + + +

+ A common scenario in searches is to allow searching for resources + with values (i.e timestamps) within a range of dates. +

+ +

+ FHIR allows for multiple parameters with the same key, and interprets + these as being an "AND" set. So, for example, a range of
+ DATE >= 2011-01-01 and DATE < 2011-02-01
+ can be interpreted as any date within January 2011. +

+ +

+ The following snippet shows how to accept such a range, and combines it + with a specific identifier, which is a common scenario. (i.e. Give me a list + of observations for a specific patient within a given date range) +

+ + + + + +

+ Example URL to invoke this method:
+ http://fhir.example.com/Observation?subject.identifier=7000135&date=>=2011-01-01&date=<2011-02-01 +

+ +

+ Invoking a client of thie type involves the following syntax: +

+ + + + + + +
+

diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java index cc22506eacd..4afe40ec9e6 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java @@ -80,17 +80,19 @@ public class JsonParserTest { } + @Test public void testSimpleParse() throws DataFormatException, IOException { String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/example-patient-general.json")); FhirContext ctx = new FhirContext(Patient.class); IParser p = ctx.newJsonParser(); + ourLog.info("Reading in message: {}", msg); Patient res = p.parseResource(Patient.class, msg); String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res); ourLog.info(encoded); - } + } @Test public void testEncodeContainedResourcesMore() throws IOException { diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java index 3350b98d798..7ce45b551f6 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java @@ -82,7 +82,7 @@ public class XmlParserTest { String str = p.encodeResourceToString(rpt); ourLog.info(str); - assertThat(str, StringContains.containsString("

AAA
")); + assertThat(str, StringContains.containsString("
AAA
")); assertThat(str, StringContains.containsString("reference value=\"#")); int idx = str.indexOf("reference value=\"#") + "reference value=\"#".length(); diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java new file mode 100644 index 00000000000..3f53830101a --- /dev/null +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java @@ -0,0 +1,84 @@ +package ca.uhn.fhir.rest.param; + +import static org.junit.Assert.*; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; + +public class DateRangeParamTest { + + private static SimpleDateFormat ourFmt; + + @BeforeClass + public static void beforeClass() { + ourFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS"); + } + + @Test + public void testYear() throws Exception { + assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011", "<2012").getLowerBoundAsInstant()); + assertEquals(parseM1("2012-01-01 00:00:00.0000"), create(">=2011", "<2012").getUpperBoundAsInstant()); + + assertEquals(parse("2012-01-01 00:00:00.0000"), create(">2011", "<=2012").getLowerBoundAsInstant()); + assertEquals(parseM1("2014-01-01 00:00:00.0000"), create(">2011", "<=2013").getUpperBoundAsInstant()); + } + + @Test + public void testMonth() throws Exception { + assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01", "<2011-02").getLowerBoundAsInstant()); + assertEquals(parseM1("2011-02-01 00:00:00.0000"), create(">=2011-01", "<2011-02").getUpperBoundAsInstant()); + + assertEquals(parse("2011-02-01 00:00:00.0000"), create(">2011-01", "<=2011-02").getLowerBoundAsInstant()); + assertEquals(parseM1("2011-03-01 00:00:00.0000"), create(">2011-01", "<=2011-02").getUpperBoundAsInstant()); + } + + @Test + public void testDay() throws Exception { + assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getLowerBoundAsInstant()); + assertEquals(parseM1("2011-01-02 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getUpperBoundAsInstant()); + + assertEquals(parse("2011-01-02 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getLowerBoundAsInstant()); + assertEquals(parseM1("2011-01-03 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getUpperBoundAsInstant()); + } + + @Test + public void testSecond() throws Exception { + assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01T00:00:00", "<2011-01-01T01:00:00").getLowerBoundAsInstant()); + assertEquals(parseM1("2011-01-01 02:00:00.0000"), create(">=2011-01-01T00:00:00", "<2011-01-01T02:00:00").getUpperBoundAsInstant()); + + assertEquals(parse("2011-01-01 00:00:01.0000"), create(">2011-01-01T00:00:00", "<=2011-01-01T02:00:00").getLowerBoundAsInstant()); + assertEquals(parseM1("2011-01-01 02:00:01.0000"), create(">2011-01-01T00:00:00", "<=2011-01-01T02:00:00").getUpperBoundAsInstant()); + } + + private Date parse(String theString) throws ParseException { + return ourFmt.parse(theString); + } + + private Date parseM1(String theString) throws ParseException { + return new Date(ourFmt.parse(theString).getTime() - 1L); + } + + private Date parseP1(String theString) throws ParseException { + return new Date(ourFmt.parse(theString).getTime() + 1L); + } + + + private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException { + DateRangeParam p = new DateRangeParam(); + List> tokens=new ArrayList>(); + tokens.add(Collections.singletonList(theLower)); + tokens.add(Collections.singletonList(theUpper)); + p.setValuesAsQueryTokens(tokens); + return p; + } + +}