Clean up client fluent param types and add some test coverage

This commit is contained in:
James Agnew 2016-06-05 11:33:43 -04:00
parent 87eabe6bf8
commit 99568a4b30
19 changed files with 662 additions and 339 deletions

View File

@ -25,6 +25,7 @@ import java.util.Date;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
/**
* Date parameter type for use in fluent client interfaces
@ -43,30 +44,32 @@ public class DateClientParam extends BaseClientParam implements IParam {
}
public IDateSpecifier after() {
return new DateWithPrefix(">");
return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN);
}
public IDateSpecifier afterOrEquals() {
return new DateWithPrefix(">=");
return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN_OR_EQUALS);
}
public IDateSpecifier before() {
return new DateWithPrefix("<");
return new DateWithPrefix(ParamPrefixEnum.LESSTHAN);
}
public IDateSpecifier beforeOrEquals() {
return new DateWithPrefix("<=");
return new DateWithPrefix(ParamPrefixEnum.LESSTHAN_OR_EQUALS);
}
public IDateSpecifier exactly() {
return new DateWithPrefix("");
return new DateWithPrefix(ParamPrefixEnum.EQUAL);
}
private class Criterion implements ICriterion<DateClientParam>, ICriterionInternal {
private String myValue;
private ParamPrefixEnum myPrefix;
public Criterion(String theValue) {
public Criterion(ParamPrefixEnum thePrefix, String theValue) {
myPrefix = thePrefix;
myValue = theValue;
}
@ -77,15 +80,20 @@ public class DateClientParam extends BaseClientParam implements IParam {
@Override
public String getParameterValue(FhirContext theContext) {
return myValue;
StringBuilder b = new StringBuilder();
if (myPrefix != null && myPrefix != ParamPrefixEnum.EQUAL) {
b.append(myPrefix.getValueForContext(theContext));
}
b.append(myValue);
return b.toString();
}
}
private class DateWithPrefix implements IDateSpecifier {
private String myPrefix;
private ParamPrefixEnum myPrefix;
public DateWithPrefix(String thePrefix) {
public DateWithPrefix(ParamPrefixEnum thePrefix) {
myPrefix = thePrefix;
}
@ -93,35 +101,35 @@ public class DateClientParam extends BaseClientParam implements IParam {
public ICriterion<DateClientParam> day(Date theValue) {
DateTimeDt dt = new DateTimeDt(theValue);
dt.setPrecision(TemporalPrecisionEnum.DAY);
return new Criterion(myPrefix + dt.getValueAsString());
return new Criterion(myPrefix, dt.getValueAsString());
}
@Override
public ICriterion<DateClientParam> day(String theValue) {
DateTimeDt dt = new DateTimeDt(theValue);
dt.setPrecision(TemporalPrecisionEnum.DAY);
return new Criterion(myPrefix + dt.getValueAsString());
return new Criterion(myPrefix , dt.getValueAsString());
}
@Override
public ICriterion<DateClientParam> now() {
DateTimeDt dt = new DateTimeDt();
dt.setPrecision(TemporalPrecisionEnum.DAY);
return new Criterion(myPrefix + dt.getValueAsString());
DateTimeDt dt = DateTimeDt.withCurrentTime();
dt.setPrecision(TemporalPrecisionEnum.SECOND);
return new Criterion(myPrefix , dt.getValueAsString());
}
@Override
public ICriterion<DateClientParam> second(Date theValue) {
DateTimeDt dt = new DateTimeDt(theValue);
dt.setPrecision(TemporalPrecisionEnum.SECOND);
return new Criterion(myPrefix + dt.getValueAsString());
return new Criterion(myPrefix , dt.getValueAsString());
}
@Override
public ICriterion<DateClientParam> second(String theValue) {
DateTimeDt dt = new DateTimeDt(theValue);
dt.setPrecision(TemporalPrecisionEnum.SECOND);
return new Criterion(myPrefix + dt.getValueAsString());
return new Criterion(myPrefix , dt.getValueAsString());
}
}

View File

@ -191,7 +191,7 @@ public class QuantityClientParam extends BaseClientParam implements IParam {
@Override
public ICriterion<QuantityClientParam> andUnits(String theUnits) {
return andUnits(theUnits, null);
return andUnits(null, theUnits);
}
@Override

View File

@ -24,6 +24,7 @@ import java.util.Arrays;
import java.util.List;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.util.CoverageIgnore;
/**
*
@ -45,11 +46,22 @@ public class UriClientParam extends BaseClientParam implements IParam {
/**
* The string matches the given value (servers will often, but are not required to) implement this as a left match, meaning that a value of "smi" would match "smi" and "smith".
* @param theValue THIS PARAMETER DOES NOT DO ANYTHING - This method was added by accident
*
* @deprecated theValue does not do anything, use {@link #matches()} instead
*/
@CoverageIgnore
@Deprecated
public IUriMatch matches(String theValue) {
return new UriMatches();
}
/**
* The string matches the given value (servers will often, but are not required to) implement this as a left match, meaning that a value of "smi" would match "smi" and "smith".
*/
public IUriMatch matches() {
return new UriMatches();
}
public interface IUriMatch {

View File

@ -1,56 +0,0 @@
package ca.uhn.fhir.util;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 - 2016 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.lang.reflect.Method;
import ca.uhn.fhir.util.reflection.IBeanUtils;
public class BeanUtils {
private static IBeanUtils beanUtils;
private static IBeanUtils getBeanUtils() {
if (beanUtils == null) {
try {
beanUtils = (IBeanUtils) Class.forName("ca.uhn.fhir.util.reflection.JavaBeansBeanUtil").newInstance();
} catch (Exception e) {
try {
beanUtils = (IBeanUtils) Class.forName("ca.uhn.fhir.util.reflection.JavaReflectBeanUtil")
.newInstance();
} catch (Exception e1) {
throw new RuntimeException("Could not resolve BeanUtil implementation");
}
}
}
return beanUtils;
}
public static Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
throws NoSuchFieldException {
return getBeanUtils().findAccessor(theClassToIntrospect, theTargetReturnType, thePropertyName);
}
public static Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
throws NoSuchFieldException {
return getBeanUtils().findMutator(theClassToIntrospect, theTargetReturnType, thePropertyName);
}
}

View File

@ -55,31 +55,37 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
myTarget.flush();
}
@CoverageIgnore
@Override
public NamespaceContext getNamespaceContext() {
return myTarget.getNamespaceContext();
}
@CoverageIgnore
@Override
public String getPrefix(String theUri) throws XMLStreamException {
return myTarget.getPrefix(theUri);
}
@CoverageIgnore
@Override
public Object getProperty(String theName) throws IllegalArgumentException {
return myTarget.getProperty(theName);
}
@CoverageIgnore
@Override
public void setDefaultNamespace(String theUri) throws XMLStreamException {
myTarget.setDefaultNamespace(theUri);
}
@CoverageIgnore
@Override
public void setNamespaceContext(NamespaceContext theContext) throws XMLStreamException {
myTarget.setNamespaceContext(theContext);
}
@CoverageIgnore
@Override
public void setPrefix(String thePrefix, String theUri) throws XMLStreamException {
myTarget.setPrefix(thePrefix, theUri);
@ -90,16 +96,19 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
myTarget.writeAttribute(theLocalName, theValue);
}
@CoverageIgnore
@Override
public void writeAttribute(String theNamespaceURI, String theLocalName, String theValue) throws XMLStreamException {
myTarget.writeAttribute(theNamespaceURI, theLocalName, theValue);
}
@CoverageIgnore
@Override
public void writeAttribute(String thePrefix, String theNamespaceURI, String theLocalName, String theValue) throws XMLStreamException {
myTarget.writeAttribute(thePrefix, theNamespaceURI, theLocalName, theValue);
}
@CoverageIgnore
@Override
public void writeCData(String theData) throws XMLStreamException {
myTarget.writeCData(theData);
@ -130,29 +139,34 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
myTarget.writeDefaultNamespace(theNamespaceURI);
}
@CoverageIgnore
@Override
public void writeDTD(String theDtd) throws XMLStreamException {
myTarget.writeDTD(theDtd);
}
@CoverageIgnore
@Override
public void writeEmptyElement(String theLocalName) throws XMLStreamException {
indent();
myTarget.writeEmptyElement(theLocalName);
}
@CoverageIgnore
@Override
public void writeEmptyElement(String theNamespaceURI, String theLocalName) throws XMLStreamException {
indent();
myTarget.writeEmptyElement(theNamespaceURI, theLocalName);
}
@CoverageIgnore
@Override
public void writeEmptyElement(String thePrefix, String theLocalName, String theNamespaceURI) throws XMLStreamException {
indent();
myTarget.writeEmptyElement(thePrefix, theLocalName, theNamespaceURI);
}
@CoverageIgnore
@Override
public void writeEndDocument() throws XMLStreamException {
decrementAndIndent();
@ -170,6 +184,7 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
}
@CoverageIgnore
@Override
public void writeEntityRef(String theName) throws XMLStreamException {
myTarget.writeEntityRef(theName);
@ -180,11 +195,13 @@ public class PrettyPrintWriterWrapper implements XMLStreamWriter {
myTarget.writeNamespace(thePrefix, theNamespaceURI);
}
@CoverageIgnore
@Override
public void writeProcessingInstruction(String theTarget) throws XMLStreamException {
myTarget.writeProcessingInstruction(theTarget);
}
@CoverageIgnore
@Override
public void writeProcessingInstruction(String theTarget, String theData) throws XMLStreamException {
myTarget.writeProcessingInstruction(theTarget, theData);

View File

@ -30,10 +30,11 @@ import java.util.LinkedHashSet;
import java.util.List;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.IQueryParameterType;
public class ReflectionUtil {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReflectionUtil.class);
public static LinkedHashSet<Method> getDeclaredMethods(Class<?> theClazz) {
LinkedHashSet<Method> retVal = new LinkedHashSet<Method>();
for (Method next : theClazz.getDeclaredMethods()) {
@ -136,4 +137,20 @@ public class ReflectionUtil {
}
}
@SuppressWarnings("unchecked")
public static <T> T newInstanceOrReturnNull(String theClassName, Class<T> theType) {
try {
Class<?> clazz = Class.forName(theClassName);
if (!theType.isAssignableFrom(clazz)) {
throw new ConfigurationException(theClassName + " is not assignable to " + theType);
}
return (T) clazz.newInstance();
} catch (ConfigurationException e) {
throw e;
} catch (Exception e) {
ourLog.info("Failed to instantiate {}: {}", theClassName, e.toString());
return null;
}
}
}

View File

@ -1,5 +1,8 @@
package ca.uhn.fhir.util.jar;
import ca.uhn.fhir.util.CoverageIgnore;
import ca.uhn.fhir.util.ReflectionUtil;
/*
* #%L
* HAPI FHIR - Core Library
@ -21,16 +24,16 @@ package ca.uhn.fhir.util.jar;
*/
public class DependencyLogFactory {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DependencyLogFactory.class);
@SuppressWarnings("unchecked")
/**
* Non instantiable
*/
@CoverageIgnore
private DependencyLogFactory() {
// nothing
}
public static IDependencyLog createJarLogger() {
try {
Class<IDependencyLog> clas = (Class<IDependencyLog>) Class.forName("ca.uhn.fhir.util.jar.DependencyLogImpl");
return clas.newInstance();
} catch (Exception e) {
ourLog.info("Could not log dependency.");
return null;
}
return ReflectionUtil.newInstanceOrReturnNull("ca.uhn.fhir.util.jar.DependencyLogImpl", IDependencyLog.class);
}
}

View File

@ -1,31 +0,0 @@
package ca.uhn.fhir.util.reflection;
import java.lang.reflect.Method;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 - 2016 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public interface IBeanUtils {
Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
throws NoSuchFieldException;
Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
throws NoSuchFieldException;
}

View File

@ -1,70 +0,0 @@
package ca.uhn.fhir.util.reflection;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 - 2016 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class JavaBeansBeanUtil implements IBeanUtils {
@Override
public Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
BeanInfo info;
try {
info = Introspector.getBeanInfo(theClassToIntrospect);
} catch (IntrospectionException e) {
throw new NoSuchFieldException(e.getMessage());
}
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
if (thePropertyName.equals(pd.getName())) {
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
return pd.getReadMethod();
}else {
throw new NoSuchFieldException(theClassToIntrospect + " has an accessor for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
}
}
}
throw new NoSuchFieldException(theClassToIntrospect + " has no accessor for field " + thePropertyName);
}
@Override
public Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
BeanInfo info;
try {
info = Introspector.getBeanInfo(theClassToIntrospect);
} catch (IntrospectionException e) {
throw new NoSuchFieldException(e.getMessage());
}
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
if (thePropertyName.equals(pd.getName())) {
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
return pd.getWriteMethod();
}else {
throw new NoSuchFieldException(theClassToIntrospect + " has an mutator for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
}
}
}
throw new NoSuchFieldException(theClassToIntrospect + " has no mutator for field " + thePropertyName);
}
}

View File

@ -1,63 +0,0 @@
package ca.uhn.fhir.util.reflection;
import java.lang.reflect.Method;
import org.apache.commons.lang3.text.WordUtils;
import ca.uhn.fhir.context.ConfigurationException;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 - 2016 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public class JavaReflectBeanUtil implements IBeanUtils {
@Override
public Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
throws NoSuchFieldException {
String methodName = "get" + WordUtils.capitalize(thePropertyName);
try {
Method method = theClassToIntrospect.getMethod(methodName);
if (theTargetReturnType.isAssignableFrom(method.getReturnType())) {
return method;
}
} catch (NoSuchMethodException e) {
// fall through
} catch (SecurityException e) {
throw new ConfigurationException("Failed to scan class '" + theClassToIntrospect + "' because of a security exception", e);
}
throw new NoSuchFieldException(theClassToIntrospect + " has no accessor for field " + thePropertyName);
}
@Override
public Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetArgumentType, String thePropertyName)
throws NoSuchFieldException {
String methodName = "set" + WordUtils.capitalize(thePropertyName);
try {
return theClassToIntrospect.getMethod(methodName, theTargetArgumentType);
} catch (NoSuchMethodException e) {
//fall through
} catch (SecurityException e) {
throw new ConfigurationException("Failed to scan class '" + theClassToIntrospect + "' because of a security exception", e);
}
throw new NoSuchFieldException(theClassToIntrospect + " has an mutator for field " + thePropertyName + " but it does not return type " + theTargetArgumentType);
}
}

View File

@ -1,78 +0,0 @@
package ca.uhn.fhir.util;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import org.junit.Test;
import ca.uhn.fhir.util.reflection.IBeanUtils;
import ca.uhn.fhir.util.reflection.JavaBeansBeanUtil;
import ca.uhn.fhir.util.reflection.JavaReflectBeanUtil;
public class BeanUtilTest {
@Test
public void testFindAccessor() throws Exception {
JavaBeansBeanUtil javaBeansBeanUtil = new JavaBeansBeanUtil();
testBeanUtilsAccessor(javaBeansBeanUtil);
JavaReflectBeanUtil javaReflectBeanUtil = new JavaReflectBeanUtil();
testBeanUtilsAccessor(javaReflectBeanUtil);
assertNotNull(BeanUtils.findAccessor(BeanUtilTestClass.class, String.class, "field"));
Method jbMGet = javaBeansBeanUtil.findAccessor(BeanUtilTestClass.class, String.class, "field");
Method jrMGet = javaReflectBeanUtil.findAccessor(BeanUtilTestClass.class, String.class, "field");
assertNotNull(jbMGet);
assertNotNull(jrMGet);
assertEquals(jbMGet, jrMGet);
}
@Test
public void testFindMutator() throws Exception {
JavaBeansBeanUtil javaBeansBeanUtil = new JavaBeansBeanUtil();
testBeanUtilsMutator(javaBeansBeanUtil);
JavaReflectBeanUtil javaReflectBeanUtil = new JavaReflectBeanUtil();
testBeanUtilsMutator(javaReflectBeanUtil);
assertNotNull(BeanUtils.findMutator(BeanUtilTestClass.class, String.class, "field"));
Method jbMSet = javaBeansBeanUtil.findMutator(BeanUtilTestClass.class, String.class, "field");
Method jrMSet = javaReflectBeanUtil.findMutator(BeanUtilTestClass.class, String.class, "field");
assertNotNull(jbMSet);
assertNotNull(jrMSet);
assertEquals(jbMSet, jrMSet);
}
private void testBeanUtilsAccessor(IBeanUtils util) throws Exception {
assertNotNull(util.findAccessor(BeanUtilTestClass.class, String.class, "field"));
try {
assertNull(util.findAccessor(BeanUtilTestClass.class, String.class, "fieldX"));
fail("Field is not in class");
} catch (NoSuchFieldException e) { }
try {
assertNull(util.findAccessor(BeanUtilTestClass.class, Integer.class, "field"));
fail("Field is in class, but we expect Integer as return type");
} catch (NoSuchFieldException e) { }
}
private void testBeanUtilsMutator(IBeanUtils util) throws Exception {
assertNotNull(util.findMutator(BeanUtilTestClass.class, String.class, "field"));
try {
assertNull(util.findMutator(BeanUtilTestClass.class, String.class, "fieldX"));
fail("Field is not in class");
} catch (NoSuchFieldException e) { }
try {
assertNull(util.findMutator(BeanUtilTestClass.class, Integer.class, "field"));
fail("Field is in class, but we expect Integer as parameter type");
} catch (NoSuchFieldException e) { }
}
public static class BeanUtilTestClass {
private String myField;
public String getField() {
return myField;
}
public void setField(String value) {
this.myField = value;
}
}
}

View File

@ -16,6 +16,26 @@ public class ReflectionUtilTest {
assertEquals(ArrayList.class, ReflectionUtil.newInstance(ArrayList.class).getClass());
}
@Test
public void testNewInstanceOrReturnNullString() {
assertEquals(ArrayList.class, ReflectionUtil.newInstanceOrReturnNull(ArrayList.class.getName(), List.class).getClass());
}
@Test
public void testNewInstanceOrReturnNullWrong1() {
assertEquals(null, ReflectionUtil.newInstanceOrReturnNull("foo.Foo", List.class));
}
@Test
public void testNewInstanceOrReturnNullWrong2() {
try {
ReflectionUtil.newInstanceOrReturnNull("java.lang.String", List.class);
fail();
} catch (ConfigurationException e) {
assertEquals("java.lang.String is not assignable to interface java.util.List", e.getMessage());
}
}
@Test
public void testNewInstanceFail() {
try {

View File

@ -288,6 +288,7 @@
<source>../hapi-fhir-structures-hl7org-dstu2/src/test/java</source>
<source>../hapi-fhir-structures-dstu3/src/test/java</source>
<source>../hapi-fhir-jpaserver-base/src/test/java</source>
<source>../hapi-fhir-base/src/test/java</source>
</sources>
</configuration>
</execution>
@ -357,6 +358,9 @@
<resources>
</resources>
<testResources>
<testResource>
<directory>../hapi-fhir-base/src/test/resources</directory>
</testResource>
<testResource>
<directory>../hapi-fhir-jpaserver-base/src/test/resources</directory>
</testResource>

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.jpa.util;
import ca.uhn.fhir.util.CoverageIgnore;
/*
* #%L
* HAPI FHIR JPA Server
@ -22,6 +24,14 @@ package ca.uhn.fhir.jpa.util;
public class LogicUtil {
/**
* Non instantiable
*/
@CoverageIgnore
private LogicUtil() {
// nothing
}
public static boolean multiXor(boolean... theValues) {
int count = 0;
for (int i = 0; i < theValues.length; i++) {

View File

@ -45,12 +45,10 @@ import com.google.common.collect.Sets;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
@ -139,7 +137,7 @@ public class XmlParserDstu2Test {
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, bin.getContent());
}
@Test
public void testChoiceTypeWithProfiledType() {
//@formatter:off
@ -1042,6 +1040,25 @@ public class XmlParserDstu2Test {
}
@Test
public void testEncodeDivWithPre() {
Patient p = new Patient();
p.getText().setDiv("<div>\n\n<p>A P TAG</p><p><pre>line1\nline2\nline3 <b>BOLD</b></pre></p></div>");
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
//@formatter:off
assertThat(output, stringContainsInOrder(
" <text>",
" <div",
" <pre>line1\nline2\nline3 <b>BOLD</b></pre>"
));
//@formatter:on
}
@Test
public void testEncodeDoesntIncludeUuidId() {
Patient p = new Patient();
@ -2253,16 +2270,6 @@ public class XmlParserDstu2Test {
}
@Test
public void testParseInvalidTextualNumber() {
Observation obs = new Observation();
obs.setValue(new QuantityDt().setValue(1234));
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
encoded = encoded.replace("1234", "\"1234\"");
ourLog.info(encoded);
ourCtx.newJsonParser().parseResource(encoded);
}
/**
* See #366
*/
@ -2277,6 +2284,16 @@ public class XmlParserDstu2Test {
ourCtx.newXmlParser().parseResource(resource);
}
@Test
public void testParseInvalidTextualNumber() {
Observation obs = new Observation();
obs.setValue(new QuantityDt().setValue(1234));
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
encoded = encoded.replace("1234", "\"1234\"");
ourLog.info(encoded);
ourCtx.newJsonParser().parseResource(encoded);
}
/**
* See #216
*/

View File

@ -57,6 +57,7 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle.Link;
import ca.uhn.fhir.model.dstu2.resource.Conformance.Rest;
import ca.uhn.fhir.model.dstu2.resource.Conformance.RestSecurity;
import ca.uhn.fhir.model.dstu2.resource.Conformance;
import ca.uhn.fhir.model.dstu2.resource.Encounter;
import ca.uhn.fhir.model.dstu2.resource.Observation;
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
@ -1804,6 +1805,75 @@ public class GenericClientDstu2Test {
}
@Test
public void testSearchByNumber() throws Exception {
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;
//@formatter:off
client.search()
.forResource("Encounter")
.where(Encounter.LENGTH.greaterThan().number(123))
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Encounter?length=gt123", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Encounter")
.where(Encounter.LENGTH.lessThan().number(123))
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Encounter?length=lt123", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Encounter")
.where(Encounter.LENGTH.greaterThanOrEqual().number("123"))
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Encounter?length=ge123", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Encounter")
.where(Encounter.LENGTH.lessThanOrEqual().number("123"))
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Encounter?length=le123", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Encounter")
.where(Encounter.LENGTH.exactly().number(123))
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Encounter?length=123", capt.getAllValues().get(idx).getURI().toString());
idx++;
}
@Test
public void testSearchByUrl() throws Exception {

View File

@ -119,6 +119,26 @@ public class XmlParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
@Test
public void testEncodeDivWithPre() {
Patient p = new Patient();
p.getText().setDivAsString("<div>\n\n<p>A P TAG</p><p><pre>line1\nline2\nline3 <b>BOLD</b></pre></p></div>");
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
//@formatter:off
assertThat(output, stringContainsInOrder(
" <text>",
" <div",
" <pre>line1\nline2\nline3 <b>BOLD</b></pre>"
));
//@formatter:on
}
@Test
public void testEncodeContainedWithNonLocalId() throws Exception {

View File

@ -1,19 +1,28 @@
package ca.uhn.fhir.rest.client;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.lang3.time.FastDateParser;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
@ -26,6 +35,8 @@ import org.hl7.fhir.dstu3.model.Binary;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.Conformance;
import org.hl7.fhir.dstu3.model.Device;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.OperationOutcome;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Patient;
@ -41,13 +52,19 @@ import org.mockito.stubbing.Answer;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.CustomTypeDstu3Test;
import ca.uhn.fhir.parser.CustomTypeDstu3Test.MyCustomPatient;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.PreferReturnEnum;
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil;
import ca.uhn.fhir.util.VersionUtil;
public class GenericClientDstu3Test {
@ -708,4 +725,402 @@ public class GenericClientDstu3Test {
public static void beforeClass() {
ourCtx = FhirContext.forDstu3();
}
@SuppressWarnings("deprecation")
@Test
public void testSearchByQuantity() throws Exception {
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.approximately().number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=ap123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.approximately().number("123").andUnits("CODE"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=ap123||CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.approximately().number("123").andUnits("SYSTEM", "CODE"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=ap123|SYSTEM|CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.exactly().number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.exactly().number("123").andUnits("CODE"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=123||CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.exactly().number("123").andUnits("SYSTEM", "CODE"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=123|SYSTEM|CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.greaterThan().number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=gt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.lessThan().number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=lt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.greaterThanOrEquals().number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=ge123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.lessThanOrEquals().number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=le123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.withComparator(QuantityCompararatorEnum.GREATERTHAN).number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=gt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Observation")
.where(Observation.VALUE_QUANTITY.withPrefix(ParamPrefixEnum.GREATERTHAN).number(123).andNoUnits())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Observation?value-quantity=gt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
}
@Test
public void testSearchByUrl() throws Exception {
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;
//@formatter:off
client.search()
.forResource("Device")
.where(Device.URL.matches().value("http://foo.com"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Device?url=http://foo.com", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
assertEquals("http://example.com/fhir/Device?url=http%3A%2F%2Ffoo.com", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Device")
.where(Device.URL.matches().value(new StringDt("http://foo.com")))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Device?url=http://foo.com", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
}
@Test
public void testSearchByString() throws Exception {
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matches().value("AAA"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=AAA", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matches().value(new StringDt("AAA")))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=AAA", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matches().values("AAA", "BBB"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matches().values(Arrays.asList("AAA", "BBB")))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matchesExactly().value("AAA"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name%3Aexact=AAA", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matchesExactly().value(new StringDt("AAA")))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name%3Aexact=AAA", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matchesExactly().values("AAA", "BBB"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name:exact=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.NAME.matchesExactly().values(Arrays.asList("AAA", "BBB")))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name:exact=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
}
@Test
public void testSearchByDate() throws Exception {
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;
Date date = new DateTimeDt("2011-01-02T22:33:01Z").getValue();
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.after().day("2011-01-02"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=gt2011-01-02", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.after().day(date))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=gt2011-01-02", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.afterOrEquals().day("2011-01-02"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=ge2011-01-02", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.before().day("2011-01-02"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=lt2011-01-02", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.beforeOrEquals().day("2011-01-02"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=le2011-01-02", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.exactly().day("2011-01-02"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=2011-01-02", capt.getAllValues().get(idx).getURI().toString());
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.after().second("2011-01-02T22:33:01Z"))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=gt2011-01-02T22:33:01Z", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
String expDate = new DateTimeDt(date).getValueAsString();
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.after().second(date))
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?birthdate=gt" + expDate, UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
idx++;
//@formatter:off
client.search()
.forResource("Patient")
.where(Patient.BIRTHDATE.after().now())
.returnBundle(Bundle.class)
.execute();
//@formatter:on
assertThat(capt.getAllValues().get(idx).getURI().toString(), startsWith("http://example.com/fhir/Patient?birthdate=gt2"));
String dateString = UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()).substring(44);
ourLog.info(dateString);
assertEquals(TemporalPrecisionEnum.SECOND, new DateTimeDt(dateString).getPrecision());
idx++;
}
}

View File

@ -263,6 +263,14 @@
Update STU3 client and server to use the new sort parameter style (param1,-param2,param). Thanks to GitHub user @euz1e4r for
reporting!
</action>
<action type="fix">
QuantityClientParam#withUnit(String) put the unit into the system part of the
parameter value
</action>
<action type="fix">
Fluent client searches with date parameters were not correctly using
new prefix style (e.g. gt) instead of old one (e.g. &gt;)
</action>
</release>
<release version="1.5" date="2016-04-20">
<action type="fix" issue="339">