Work on HL7org structs
This commit is contained in:
parent
eddcf5f4d8
commit
b42737262b
|
@ -3,10 +3,12 @@ package ca.uhn.fhir.android;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
|
@ -56,7 +58,7 @@ public class BuiltJarIT {
|
|||
* Android does not like duplicate entries in the JAR
|
||||
*/
|
||||
@Test
|
||||
public void testJarForDuplicates() throws Exception {
|
||||
public void testJarContents() throws Exception {
|
||||
String wildcard = "hapi-fhir-android-*.jar";
|
||||
Collection<File> files = FileUtils.listFiles(new File("target"), new WildcardFileFilter(wildcard), null);
|
||||
if (files.isEmpty()) {
|
||||
|
@ -67,6 +69,11 @@ public class BuiltJarIT {
|
|||
ourLog.info("Testing file: {}", file);
|
||||
|
||||
ZipFile zip = new ZipFile(file);
|
||||
|
||||
int totalClasses = 0;
|
||||
int totalMethods = 0;
|
||||
TreeSet<ClassMethodCount> topMethods = new TreeSet<ClassMethodCount>();
|
||||
|
||||
try {
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Enumeration<? extends ZipEntry> iter = zip.entries(); iter.hasMoreElements();) {
|
||||
|
@ -75,9 +82,28 @@ public class BuiltJarIT {
|
|||
if (!names.add(nextName)) {
|
||||
throw new Exception("File " + file + " contains duplicate contents: " + nextName);
|
||||
}
|
||||
|
||||
if (nextName.contains("$") == false) {
|
||||
if (nextName.endsWith(".class")) {
|
||||
String className = nextName.replace("/", ".").replace(".class", "");
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
int methodCount = clazz.getMethods().length;
|
||||
topMethods.add(new ClassMethodCount(className, methodCount));
|
||||
totalClasses++;
|
||||
totalMethods += methodCount;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ourLog.info("File {} contains {} entries", file, names.size());
|
||||
ourLog.info("Total classes {} - Total methods {}", totalClasses, totalMethods);
|
||||
ourLog.info("Top classes {}", new ArrayList<ClassMethodCount>(topMethods).subList(topMethods.size() - 10, topMethods.size()));
|
||||
|
||||
} finally {
|
||||
zip.close();
|
||||
|
@ -85,4 +111,42 @@ public class BuiltJarIT {
|
|||
}
|
||||
}
|
||||
|
||||
private static class ClassMethodCount implements Comparable<ClassMethodCount> {
|
||||
|
||||
private String myClassName;
|
||||
private int myMethodCount;
|
||||
|
||||
public ClassMethodCount(String theClassName, int theMethodCount) {
|
||||
myClassName = theClassName;
|
||||
myMethodCount = theMethodCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myClassName + "[" + myMethodCount + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ClassMethodCount theO) {
|
||||
return myMethodCount - theO.myMethodCount;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return myClassName;
|
||||
}
|
||||
|
||||
public void setClassName(String theClassName) {
|
||||
myClassName = theClassName;
|
||||
}
|
||||
|
||||
public int getMethodCount() {
|
||||
return myMethodCount;
|
||||
}
|
||||
|
||||
public void setMethodCount(int theMethodCount) {
|
||||
myMethodCount = theMethodCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -105,8 +105,10 @@ public abstract class BaseRuntimeElementDefinition<T extends IBase> {
|
|||
return getImplementingClass().newInstance();
|
||||
} else if (theArgument instanceof IValueSetEnumBinder) {
|
||||
return getImplementingClass().getConstructor(IValueSetEnumBinder.class).newInstance(theArgument);
|
||||
} else {
|
||||
} else if (theArgument instanceof IBaseEnumFactory) {
|
||||
return getImplementingClass().getConstructor(IBaseEnumFactory.class).newInstance(theArgument);
|
||||
} else {
|
||||
return getImplementingClass().getConstructor(theArgument.getClass()).newInstance(theArgument);
|
||||
}
|
||||
} catch (InstantiationException e) {
|
||||
throw new ConfigurationException("Failed to instantiate type:" + getImplementingClass().getName(), e);
|
||||
|
|
|
@ -27,12 +27,14 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.text.WordUtils;
|
||||
import org.hl7.fhir.instance.model.IBase;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
||||
import ca.uhn.fhir.i18n.HapiLocalizer;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
import ca.uhn.fhir.model.api.IFhirVersion;
|
||||
|
@ -77,8 +79,9 @@ public class FhirContext {
|
|||
private volatile Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinition = Collections.emptyMap();
|
||||
private volatile Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = Collections.emptyMap();
|
||||
private HapiLocalizer myLocalizer = new HapiLocalizer();
|
||||
private volatile Map<String, RuntimeResourceDefinition> myNameToElementDefinition = Collections.emptyMap();
|
||||
private Map<String, Class<? extends IBaseResource>> myNameToResourceType;
|
||||
private volatile Map<String, BaseRuntimeElementDefinition<?>> myNameToElementDefinition = Collections.emptyMap();
|
||||
private volatile Map<String, RuntimeResourceDefinition> myNameToResourceDefinition = Collections.emptyMap();
|
||||
private volatile Map<String, Class<? extends IBaseResource>> myNameToResourceType;
|
||||
private volatile INarrativeGenerator myNarrativeGenerator;
|
||||
private volatile IRestfulClientFactory myRestfulClientFactory;
|
||||
private volatile RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
|
||||
|
@ -136,6 +139,14 @@ public class FhirContext {
|
|||
return getLocalizer().getMessage(FhirContext.class, "unknownResourceName", theResourceName, theVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed
|
||||
* for extending the core library.
|
||||
*/
|
||||
public BaseRuntimeElementDefinition<?> getElementDefinition(String theElementName) {
|
||||
return myNameToElementDefinition.get(theElementName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed
|
||||
* for extending the core library.
|
||||
|
@ -241,7 +252,7 @@ public class FhirContext {
|
|||
|
||||
Validate.notBlank(resourceName, "Resource name must not be blank");
|
||||
|
||||
RuntimeResourceDefinition retVal = myNameToElementDefinition.get(resourceName);
|
||||
RuntimeResourceDefinition retVal = myNameToResourceDefinition.get(resourceName);
|
||||
|
||||
if (retVal == null) {
|
||||
Class<? extends IBaseResource> clazz = myNameToResourceType.get(resourceName.toLowerCase());
|
||||
|
@ -401,10 +412,14 @@ public class FhirContext {
|
|||
myRuntimeChildUndeclaredExtensionDefinition = scanner.getRuntimeChildUndeclaredExtensionDefinition();
|
||||
}
|
||||
|
||||
Map<String, RuntimeResourceDefinition> nameToElementDefinition = new HashMap<String, RuntimeResourceDefinition>();
|
||||
Map<String, BaseRuntimeElementDefinition<?>> nameToElementDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
||||
nameToElementDefinition.putAll(myNameToElementDefinition);
|
||||
nameToElementDefinition.putAll(scanner.getNameToResourceDefinitions());
|
||||
nameToElementDefinition.putAll(scanner.getNameToElementDefinitions());
|
||||
|
||||
Map<String, RuntimeResourceDefinition> nameToResourceDefinition = new HashMap<String, RuntimeResourceDefinition>();
|
||||
nameToResourceDefinition.putAll(myNameToResourceDefinition);
|
||||
nameToResourceDefinition.putAll(scanner.getNameToResourceDefinition());
|
||||
|
||||
Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> classToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
||||
classToElementDefinition.putAll(myClassToElementDefinition);
|
||||
classToElementDefinition.putAll(scanner.getClassToElementDefinitions());
|
||||
|
@ -416,6 +431,7 @@ public class FhirContext {
|
|||
myNameToElementDefinition = nameToElementDefinition;
|
||||
myClassToElementDefinition = classToElementDefinition;
|
||||
myIdToResourceDefinition = idToElementDefinition;
|
||||
myNameToResourceDefinition = nameToResourceDefinition;
|
||||
|
||||
myNameToResourceType = scanner.getNameToResourceType();
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public enum FhirVersionEnum {
|
|||
|
||||
DEV("ca.uhn.fhir.model.dev.FhirDev", null),
|
||||
|
||||
DSTU2_HL7ORG("org.hl7.fhir.instance.FhirDstu2Hl7Org", null);
|
||||
DSTU2_HL7ORG("org.hl7.fhir.instance.FhirDstu2Hl7Org", DSTU2);
|
||||
|
||||
|
||||
private final String myVersionClass;
|
||||
|
|
|
@ -101,6 +101,7 @@ class ModelScanner {
|
|||
private Set<Class<? extends IBase>> myScanAlso = new HashSet<Class<? extends IBase>>();
|
||||
private Set<Class<? extends ICodeEnum>> myScanAlsoCodeTable = new HashSet<Class<? extends ICodeEnum>>();
|
||||
private FhirVersionEnum myVersion;
|
||||
private Map<String, BaseRuntimeElementDefinition<?>> myNameToElementDefinitions = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
||||
|
||||
ModelScanner(FhirContext theContext, FhirVersionEnum theVersion, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Collection<Class<? extends IElement>> theResourceTypes) throws ConfigurationException {
|
||||
myContext = theContext;
|
||||
|
@ -338,6 +339,7 @@ class ModelScanner {
|
|||
resourceDef = new RuntimeCompositeDatatypeDefinition(theDatatypeDefinition, theClass);
|
||||
}
|
||||
myClassToElementDefinitions.put(theClass, resourceDef);
|
||||
myNameToElementDefinitions.put(resourceDef.getName(), resourceDef);
|
||||
scanCompositeElementForChildren(theClass, resourceDef);
|
||||
}
|
||||
|
||||
|
@ -654,6 +656,7 @@ class ModelScanner {
|
|||
resourceDef = new RuntimePrimitiveDatatypeDefinition(theDatatypeDefinition, theClass);
|
||||
}
|
||||
myClassToElementDefinitions.put(theClass, resourceDef);
|
||||
myNameToElementDefinitions.put(resourceName, resourceDef);
|
||||
|
||||
return resourceName;
|
||||
}
|
||||
|
@ -810,4 +813,12 @@ class ModelScanner {
|
|||
}
|
||||
}
|
||||
|
||||
public Map<String, BaseRuntimeElementDefinition<?>> getNameToElementDefinitions() {
|
||||
return myNameToElementDefinitions;
|
||||
}
|
||||
|
||||
public Map<String, RuntimeResourceDefinition> getNameToResourceDefinition() {
|
||||
return myNameToResourceDefinitions;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
BaseRuntimeElementDefinition<?> nextDef;
|
||||
if (IBaseResource.class.isAssignableFrom(next)) {
|
||||
elementName = getElementName() + StringUtils.capitalize(next.getSimpleName());
|
||||
alternateElementName = getElementName() + "Resource";
|
||||
alternateElementName = getElementName() + "Reference";
|
||||
List<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>();
|
||||
types.add((Class<? extends IBaseResource>) next);
|
||||
nextDef = new RuntimeResourceReferenceDefinition(elementName, types);
|
||||
|
@ -107,7 +107,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
if (IBaseResource.class.isAssignableFrom(next)) {
|
||||
Class<? extends IBase> refType = theContext.getVersion().getResourceReferenceType();
|
||||
myDatatypeToElementDefinition.put(refType, nextDef);
|
||||
alternateElementName = getElementName() + "Resource";
|
||||
alternateElementName = getElementName() + "Reference";
|
||||
myDatatypeToElementName.put(refType, alternateElementName);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,11 @@ public class RuntimeChildContainedResources extends BaseRuntimeDeclaredChildDefi
|
|||
|
||||
@Override
|
||||
public BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IBase> theType) {
|
||||
assert BaseContainedDt.class.isAssignableFrom(theType) || List.class.isAssignableFrom(theType);
|
||||
return myElem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChildNameByDatatype(Class<? extends IBase> theType) {
|
||||
assert BaseContainedDt.class.isAssignableFrom(theType) || List.class.isAssignableFrom(theType);
|
||||
return getElementName();
|
||||
}
|
||||
|
||||
|
|
|
@ -141,13 +141,21 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
|
|||
myDatatypeToDefinition.put(type, next.getValue());
|
||||
}
|
||||
|
||||
// Resource Reference
|
||||
myDatatypeToAttributeName.put(theContext.getVersion().getResourceReferenceType(), "valueResource");
|
||||
/*
|
||||
* Resource reference - The correct name is 'valueReference', but
|
||||
* we allow for valueResource because some incorrect parsers may use this
|
||||
*/
|
||||
addReferenceBinding(theContext, theClassToElementDefinitions, "valueResource");
|
||||
addReferenceBinding(theContext, theClassToElementDefinitions, "valueReference");
|
||||
}
|
||||
|
||||
private void addReferenceBinding(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions, String value) {
|
||||
myDatatypeToAttributeName.put(theContext.getVersion().getResourceReferenceType(), value);
|
||||
List<Class<? extends IBaseResource>> types = new ArrayList<Class<? extends IBaseResource>>();
|
||||
types.add(IBaseResource.class);
|
||||
RuntimeResourceReferenceDefinition def = new RuntimeResourceReferenceDefinition("valueResource", types);
|
||||
RuntimeResourceReferenceDefinition def = new RuntimeResourceReferenceDefinition(value, types);
|
||||
def.sealAndInitialize(theContext, theClassToElementDefinitions);
|
||||
myAttributeNameToDefinition.put("valueResource", def);
|
||||
myAttributeNameToDefinition.put(value, def);
|
||||
myDatatypeToDefinition.put(BaseResourceReferenceDt.class, def);
|
||||
myDatatypeToDefinition.put(theContext.getVersion().getResourceReferenceType(), def);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,14 @@ package ca.uhn.fhir.model.base.resource;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
|
||||
//@ResourceDef(name="Conformance")
|
||||
public interface BaseConformance extends IResource {
|
||||
public interface BaseConformance extends IResource, IBaseConformance {
|
||||
|
||||
public abstract StringDt getDescriptionElement();
|
||||
|
||||
|
|
|
@ -149,14 +149,14 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
* The version ID ("e.g. "456")
|
||||
*/
|
||||
public IdDt(String theResourceType, String theId, String theVersionId) {
|
||||
this(null,theResourceType,theId,theVersionId);
|
||||
this(null, theResourceType, theId, theVersionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theBaseUrl
|
||||
* The server base URL (e.g. "http://example.com/fhir")
|
||||
* The server base URL (e.g. "http://example.com/fhir")
|
||||
* @param theResourceType
|
||||
* The resource type (e.g. "Patient")
|
||||
* @param theId
|
||||
|
@ -201,14 +201,12 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
return ObjectUtils.equals(getResourceType(), theId.getResourceType()) && ObjectUtils.equals(getIdPart(), theId.getIdPart()) && ObjectUtils.equals(getVersionIdPart(), theId.getVersionIdPart());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theArg0) {
|
||||
if (!(theArg0 instanceof IdDt)) {
|
||||
return false;
|
||||
}
|
||||
IdDt id = (IdDt)theArg0;
|
||||
IdDt id = (IdDt) theArg0;
|
||||
return StringUtils.equals(getValueAsString(), id.getValueAsString());
|
||||
}
|
||||
|
||||
|
@ -231,9 +229,7 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns only the logical ID part of this ID. For example, given the ID
|
||||
* "http://example,.com/fhir/Patient/123/_history/456", this method would
|
||||
* return "123".
|
||||
* Returns only the logical ID part of this ID. For example, given the ID "http://example,.com/fhir/Patient/123/_history/456", this method would return "123".
|
||||
*/
|
||||
public String getIdPart() {
|
||||
return myUnqualifiedId;
|
||||
|
@ -282,19 +278,19 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
StringBuilder b = new StringBuilder();
|
||||
if (isNotBlank(myBaseUrl)) {
|
||||
b.append(myBaseUrl);
|
||||
if (myBaseUrl.charAt(myBaseUrl.length()-1)!='/') {
|
||||
if (myBaseUrl.charAt(myBaseUrl.length() - 1) != '/') {
|
||||
b.append('/');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isNotBlank(myResourceType)) {
|
||||
b.append(myResourceType);
|
||||
}
|
||||
|
||||
|
||||
if (b.length() > 0) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
|
||||
b.append(myUnqualifiedId);
|
||||
if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
|
@ -408,10 +404,10 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
myUnqualifiedId = null;
|
||||
myUnqualifiedVersionId = null;
|
||||
myResourceType = null;
|
||||
} else if (theValue.charAt(0)== '#') {
|
||||
} else if (theValue.charAt(0) == '#') {
|
||||
myValue = theValue;
|
||||
myUnqualifiedId = theValue;
|
||||
myUnqualifiedVersionId=null;
|
||||
myUnqualifiedVersionId = null;
|
||||
myResourceType = null;
|
||||
myHaveComponentParts = true;
|
||||
} else {
|
||||
|
@ -470,9 +466,8 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a new IdDt containing this IdDt's values but with no server base URL if one
|
||||
* is present in this IdDt. For example, if this IdDt contains the ID "http://foo/Patient/1",
|
||||
* this method will return a new IdDt containing ID "Patient/1".
|
||||
* Returns a new IdDt containing this IdDt's values but with no server base URL if one is present in this IdDt. For example, if this IdDt contains the ID "http://foo/Patient/1", this method will
|
||||
* return a new IdDt containing ID "Patient/1".
|
||||
*/
|
||||
public IdDt toUnqualified() {
|
||||
return new IdDt(getResourceType(), getIdPart(), getVersionIdPart());
|
||||
|
@ -552,7 +547,7 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
} else if (theResouce instanceof IResource) {
|
||||
((IResource) theResouce).setId(new IdDt(getValue()));
|
||||
} else if (theResouce instanceof IAnyResource) {
|
||||
((IAnyResource) theResouce).setId(getIdPart());
|
||||
((IAnyResource) theResouce).setId(getValue());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown resource class type, does not implement IResource or extend Resource");
|
||||
}
|
||||
|
@ -564,11 +559,15 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
public static IdDt of(IBaseResource theResouce) {
|
||||
if (theResouce == null) {
|
||||
throw new NullPointerException("theResource can not be null");
|
||||
} else if (theResouce instanceof IResource) {
|
||||
return ((IResource) theResouce).getId();
|
||||
} else if (theResouce instanceof IAnyResource) {
|
||||
// TODO: implement
|
||||
throw new UnsupportedOperationException();
|
||||
} else if (theResouce instanceof IBaseResource) {
|
||||
IIdType retVal = ((IBaseResource) theResouce).getId();
|
||||
if (retVal == null) {
|
||||
return null;
|
||||
} else if (retVal instanceof IdDt) {
|
||||
return (IdDt) retVal;
|
||||
} else {
|
||||
return new IdDt(retVal.getValue());
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown resource class type, does not implement IResource or extend Resource");
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ public abstract class BaseParser implements IParser {
|
|||
private ContainedResources myContainedResources;
|
||||
private FhirContext myContext;
|
||||
private String myServerBaseUrl;
|
||||
private boolean myStripVersionsFromReferences = true;
|
||||
private boolean mySuppressNarratives;
|
||||
|
||||
public BaseParser(FhirContext theContext) {
|
||||
|
@ -137,7 +138,6 @@ public abstract class BaseParser implements IParser {
|
|||
|
||||
}
|
||||
|
||||
|
||||
protected void containResourcesForEncoding(IBaseResource theResource) {
|
||||
ContainedResources contained = new ContainedResources();
|
||||
containResourcesForEncoding(contained, theResource, theResource);
|
||||
|
@ -157,17 +157,27 @@ public abstract class BaseParser implements IParser {
|
|||
reference = "#" + containedId.getValue();
|
||||
}
|
||||
} else if (theRef.getResource().getId() != null && theRef.getResource().getId().hasIdPart()) {
|
||||
reference = theRef.getResource().getId().getValue();
|
||||
if (isStripVersionsFromReferences()) {
|
||||
reference = theRef.getResource().getId().toVersionless().getValue();
|
||||
} else {
|
||||
reference = theRef.getResource().getId().getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return reference;
|
||||
} else {
|
||||
if (isNotBlank(myServerBaseUrl) && StringUtils.equals(myServerBaseUrl, ref.getBaseUrl())) {
|
||||
String reference = ref.toUnqualifiedVersionless().getValue();
|
||||
return reference;
|
||||
if (isStripVersionsFromReferences()) {
|
||||
return ref.toUnqualifiedVersionless().getValue();
|
||||
} else {
|
||||
return ref.toUnqualified().getValue();
|
||||
}
|
||||
} else {
|
||||
String reference = ref.toVersionless().getValue();
|
||||
return reference;
|
||||
if (isStripVersionsFromReferences()) {
|
||||
return ref.toVersionless().getValue();
|
||||
} else {
|
||||
return ref.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +255,13 @@ public abstract class BaseParser implements IParser {
|
|||
}
|
||||
|
||||
protected boolean isChildContained(BaseRuntimeElementDefinition<?> childDef, boolean theIncludedResource) {
|
||||
return (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES || childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST) && getContainedResources().isEmpty() == false && theIncludedResource == false;
|
||||
return (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES || childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST) && getContainedResources().isEmpty() == false
|
||||
&& theIncludedResource == false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStripVersionsFromReferences() {
|
||||
return myStripVersionsFromReferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -267,7 +283,7 @@ public abstract class BaseParser implements IParser {
|
|||
List<IBase> base = def.getChildByName("base").getAccessor().getValues(retVal);
|
||||
if (base != null && base.size() > 0) {
|
||||
IPrimitiveType<?> baseType = (IPrimitiveType<?>) base.get(0);
|
||||
IResource res = ((IResource) retVal);
|
||||
IBaseResource res = ((IBaseResource) retVal);
|
||||
res.setId(new IdDt(baseType.getValueAsString(), def.getName(), res.getId().getIdPart(), res.getId().getVersionIdPart()));
|
||||
}
|
||||
|
||||
|
@ -287,11 +303,11 @@ public abstract class BaseParser implements IParser {
|
|||
|
||||
List<IBase> entryResources = entryDef.getChildByName("resource").getAccessor().getValues(nextEntry);
|
||||
if (entryResources != null && entryResources.size() > 0) {
|
||||
IResource res = (IResource) entryResources.get(0);
|
||||
IBaseResource res = (IBaseResource) entryResources.get(0);
|
||||
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(res);
|
||||
String versionIdPart = res.getId().getVersionIdPart();
|
||||
if (isBlank(versionIdPart)) {
|
||||
versionIdPart = ResourceMetadataKeyEnum.VERSION.get(res);
|
||||
if (isBlank(versionIdPart) && res instanceof IResource) {
|
||||
versionIdPart = ResourceMetadataKeyEnum.VERSION.get((IResource) res);
|
||||
}
|
||||
|
||||
res.setId(new IdDt(baseType.getValueAsString(), resDef.getName(), res.getId().getIdPart(), versionIdPart));
|
||||
|
@ -335,6 +351,12 @@ public abstract class BaseParser implements IParser {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser setStripVersionsFromReferences(boolean theStripVersionsFromReferences) {
|
||||
myStripVersionsFromReferences = theStripVersionsFromReferences;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser setSuppressNarratives(boolean theSuppressNarratives) {
|
||||
mySuppressNarratives = theSuppressNarratives;
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.hl7.fhir.instance.model.IBaseResource;
|
|||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
|
||||
/**
|
||||
|
@ -178,4 +177,28 @@ public interface IParser {
|
|||
*/
|
||||
IParser setServerBaseUrl(String theUrl);
|
||||
|
||||
/**
|
||||
* If set to <code>true<code> (which is the default), resource references containing a version
|
||||
* will have the version removed when the resource is encoded. This is generally good behaviour because
|
||||
* in most situations, references from one resource to another should be to the resource by ID, not
|
||||
* by ID and version. In some cases though, it may be desirable to preserve the version in resource
|
||||
* links. In that case, this value should be set to <code>false</code>.
|
||||
*
|
||||
* @param theStripVersionsFromReferences Set this to <code>false<code> to prevent the parser from removing
|
||||
* resource versions from references.
|
||||
* @return Returns an instance of <code>this</code> parser so that method calls can be chained together
|
||||
*/
|
||||
IParser setStripVersionsFromReferences(boolean theStripVersionsFromReferences);
|
||||
|
||||
/**
|
||||
* If set to <code>true<code> (which is the default), resource references containing a version
|
||||
* will have the version removed when the resource is encoded. This is generally good behaviour because
|
||||
* in most situations, references from one resource to another should be to the resource by ID, not
|
||||
* by ID and version. In some cases though, it may be desirable to preserve the version in resource
|
||||
* links. In that case, this value should be set to <code>false</code>.
|
||||
*
|
||||
* @return Returns the parser instance's configuration setting for stripping versions from resource references when encoding. Default is <code>true</code>.
|
||||
*/
|
||||
boolean isStripVersionsFromReferences();
|
||||
|
||||
}
|
||||
|
|
|
@ -358,13 +358,14 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
switch (theChildDef.getChildType()) {
|
||||
case ID_DATATYPE: {
|
||||
IIdType value = (IIdType) theNextValue;
|
||||
if (isBlank(value.getIdPart())) {
|
||||
String encodedValue = "id".equals(theChildName) ? value.getIdPart() : value.getValue();
|
||||
if (isBlank(encodedValue)) {
|
||||
break;
|
||||
}
|
||||
if (theChildName != null) {
|
||||
theWriter.write(theChildName, value.getIdPart());
|
||||
theWriter.write(theChildName, encodedValue);
|
||||
} else {
|
||||
theWriter.write(value.getIdPart());
|
||||
theWriter.write(encodedValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -410,8 +411,8 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
} else {
|
||||
theWriter.writeStartObject();
|
||||
}
|
||||
if (theNextValue instanceof ExtensionDt) {
|
||||
theWriter.write("url", ((ExtensionDt) theNextValue).getUrlAsString());
|
||||
if (theNextValue instanceof IBaseExtension) {
|
||||
theWriter.write("url", ((IBaseExtension<?>) theNextValue).getUrl());
|
||||
}
|
||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theIsSubElementWithinResource);
|
||||
theWriter.writeEnd();
|
||||
|
@ -871,7 +872,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
IBaseHasExtensions element = (IBaseHasExtensions) theElement;
|
||||
List<? extends IBaseExtension<?>> ext = element.getExtension();
|
||||
for (IBaseExtension<?> next : ext) {
|
||||
if (next == null || next.isEmpty()) {
|
||||
if (next == null || (ElementUtil.isEmpty(next.getValue()) && next.getExtension().isEmpty())) {
|
||||
continue;
|
||||
}
|
||||
extensions.add(new HeldExtension(next, false));
|
||||
|
@ -1050,11 +1051,17 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
if ("resourceType".equals(nextName)) {
|
||||
continue;
|
||||
} else if ("id".equals(nextName)) {
|
||||
if (theObject.isNull(nextName)) {
|
||||
continue;
|
||||
}
|
||||
elementId = theObject.getString(nextName);
|
||||
if (myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
|
||||
continue;
|
||||
}
|
||||
} else if ("_id".equals(nextName)) {
|
||||
if (theObject.isNull(nextName)) {
|
||||
continue;
|
||||
}
|
||||
// _id is incorrect, but some early examples in the FHIR spec used it
|
||||
elementId = theObject.getString(nextName);
|
||||
continue;
|
||||
|
@ -1082,8 +1089,8 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
IBase object = (IBase) theState.getObject();
|
||||
if (object instanceof IIdentifiableElement) {
|
||||
((IIdentifiableElement) object).setElementSpecificId(elementId);
|
||||
} else if (object instanceof IResource) {
|
||||
((IResource) object).setId(new IdDt(elementId));
|
||||
} else if (object instanceof IBaseResource) {
|
||||
((IBaseResource) object).getId().setValue(elementId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1196,31 +1203,35 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
|
||||
@Override
|
||||
public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) {
|
||||
JsonReader reader = Json.createReader(theReader);
|
||||
JsonObject object = reader.readObject();
|
||||
|
||||
JsonValue resourceTypeObj = object.get("resourceType");
|
||||
assertObjectOfType(resourceTypeObj, JsonValue.ValueType.STRING, "resourceType");
|
||||
String resourceType = ((JsonString) resourceTypeObj).getString();
|
||||
|
||||
RuntimeResourceDefinition def;
|
||||
if (theResourceType != null) {
|
||||
def = myContext.getResourceDefinition(theResourceType);
|
||||
} else {
|
||||
def = myContext.getResourceDefinition(resourceType);
|
||||
try {
|
||||
JsonReader reader = Json.createReader(theReader);
|
||||
JsonObject object = reader.readObject();
|
||||
|
||||
JsonValue resourceTypeObj = object.get("resourceType");
|
||||
assertObjectOfType(resourceTypeObj, JsonValue.ValueType.STRING, "resourceType");
|
||||
String resourceType = ((JsonString) resourceTypeObj).getString();
|
||||
|
||||
RuntimeResourceDefinition def;
|
||||
if (theResourceType != null) {
|
||||
def = myContext.getResourceDefinition(theResourceType);
|
||||
} else {
|
||||
def = myContext.getResourceDefinition(resourceType);
|
||||
}
|
||||
|
||||
ParserState<? extends IBaseResource> state = ParserState.getPreResourceInstance(def.getImplementingClass(), myContext, true);
|
||||
state.enteringNewElement(null, def.getName());
|
||||
|
||||
parseChildren(object, state);
|
||||
|
||||
state.endingElement();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T retVal = (T) state.getObject();
|
||||
|
||||
return retVal;
|
||||
} catch (JsonParsingException e) {
|
||||
throw new DataFormatException("Failed to parse JSON: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
ParserState<? extends IBaseResource> state = ParserState.getPreResourceInstance(def.getImplementingClass(), myContext, true);
|
||||
state.enteringNewElement(null, def.getName());
|
||||
|
||||
parseChildren(object, state);
|
||||
|
||||
state.endingElement();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T retVal = (T) state.getObject();
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.hl7.fhir.instance.model.api.IBaseExtension;
|
|||
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
|
||||
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
|
||||
import org.hl7.fhir.instance.model.api.IBaseXhtml;
|
||||
import org.hl7.fhir.instance.model.api.IDomainResource;
|
||||
import org.hl7.fhir.instance.model.api.IReference;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||
|
@ -1682,7 +1683,7 @@ class ParserState<T> {
|
|||
switch (target.getChildType()) {
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance();
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance();
|
||||
myExtension.setValue(newChildInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
|
@ -1714,6 +1715,9 @@ class ParserState<T> {
|
|||
case UNDECL_EXT:
|
||||
case EXTENSION_DECLARED:
|
||||
case CONTAINED_RESOURCES:
|
||||
case CONTAINED_RESOURCE_LIST:
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_XHTML_HL7ORG:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1952,6 +1956,17 @@ class ParserState<T> {
|
|||
if (myTarget == null) {
|
||||
myObject = (T) getCurrentElement();
|
||||
}
|
||||
|
||||
if (getCurrentElement() instanceof IDomainResource) {
|
||||
IDomainResource elem = (IDomainResource) getCurrentElement();
|
||||
String resourceName = myContext.getResourceDefinition(elem).getName();
|
||||
String versionId = elem.getMeta().getVersionId();
|
||||
if (StringUtils.isNotBlank(versionId)) {
|
||||
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart() + "/_history/" + versionId);
|
||||
} else {
|
||||
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -458,11 +458,11 @@ public class XmlParser extends BaseParser implements IParser {
|
|||
|
||||
switch (childDef.getChildType()) {
|
||||
case ID_DATATYPE: {
|
||||
IIdType pd = (IIdType) nextValue;
|
||||
String value = pd.getIdPart();
|
||||
IIdType value = (IIdType) nextValue;
|
||||
String encodedValue = "id".equals(childName) ? value.getIdPart() : value.getValue();
|
||||
if (value != null) {
|
||||
theEventWriter.writeStartElement(childName);
|
||||
theEventWriter.writeAttribute("value", value);
|
||||
theEventWriter.writeAttribute("value", encodedValue);
|
||||
encodeExtensionsIfPresent(theResource, theEventWriter, nextValue, theIncludedResource);
|
||||
theEventWriter.writeEndElement();
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ public class XmlParser extends BaseParser implements IParser {
|
|||
IReference ref = (IReference) nextValue;
|
||||
if (!ref.isEmpty()) {
|
||||
theEventWriter.writeStartElement(childName);
|
||||
encodeResourceReferenceToStreamWriter(theEventWriter, ref);
|
||||
encodeResourceReferenceToStreamWriter(theEventWriter, ref, theResource, theIncludedResource);
|
||||
theEventWriter.writeEndElement();
|
||||
}
|
||||
break;
|
||||
|
@ -674,9 +674,11 @@ public class XmlParser extends BaseParser implements IParser {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, IReference theRef) throws XMLStreamException {
|
||||
private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, IReference theRef, IBaseResource theResource, boolean theIncludedResource) throws XMLStreamException {
|
||||
String reference = determineReferenceText(theRef);
|
||||
|
||||
encodeExtensionsIfPresent(theResource, theEventWriter, theRef, theIncludedResource);
|
||||
|
||||
if (StringUtils.isNotBlank(reference)) {
|
||||
theEventWriter.writeStartElement(RESREF_REFERENCE);
|
||||
theEventWriter.writeAttribute("value", reference);
|
||||
|
@ -890,7 +892,7 @@ public class XmlParser extends BaseParser implements IParser {
|
|||
|
||||
private void encodeUndeclaredExtensions(IBaseResource theResource, XMLStreamWriter theWriter, List<? extends IBaseExtension<?>> theExtensions, String tagName, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
||||
for (IBaseExtension<?> next : theExtensions) {
|
||||
if (next == null) {
|
||||
if (next == null || (ElementUtil.isEmpty(next.getValue()) && next.getExtension().isEmpty())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ package ca.uhn.fhir.rest.client;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
@ -39,6 +40,7 @@ import org.apache.http.client.methods.HttpRequestBase;
|
|||
import org.hl7.fhir.instance.model.IBase;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
|
@ -73,6 +75,8 @@ import ca.uhn.fhir.rest.gclient.IDelete;
|
|||
import ca.uhn.fhir.rest.gclient.IDeleteTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IDeleteWithQuery;
|
||||
import ca.uhn.fhir.rest.gclient.IDeleteWithQueryTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IFetchConformanceTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IFetchConformanceUntyped;
|
||||
import ca.uhn.fhir.rest.gclient.IGetPage;
|
||||
import ca.uhn.fhir.rest.gclient.IGetPageTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IGetTags;
|
||||
|
@ -141,8 +145,13 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
myContext = theContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BaseConformance conformance() {
|
||||
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
||||
throw new IllegalArgumentException("Must call conformance(" + IBaseConformance.class.getSimpleName() + ") for HL7.org structures");
|
||||
}
|
||||
|
||||
HttpGetClientInvocation invocation = MethodUtil.createConformanceInvocation();
|
||||
if (isKeepResponses()) {
|
||||
myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
|
||||
|
@ -166,7 +175,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return myContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodOutcome create(IResource theResource) {
|
||||
BaseHttpClientInvocation invocation = MethodUtil.createCreateInvocation(theResource, myContext);
|
||||
|
@ -352,7 +360,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
@Override
|
||||
public IOperation operation() {
|
||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) == false) {
|
||||
throw new IllegalStateException("Operations are only supported in FHIR DSTU2 and later. This client was created using a context configured for " + myContext.getVersion().getVersion().name());
|
||||
throw new IllegalStateException("Operations are only supported in FHIR DSTU2 and later. This client was created using a context configured for "
|
||||
+ myContext.getVersion().getVersion().name());
|
||||
}
|
||||
return new OperationInternal();
|
||||
}
|
||||
|
@ -362,6 +371,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return new ReadInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFetchConformanceUntyped fetchConformance() {
|
||||
return new FetchConformanceInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseResource> T read(Class<T> theType, String theId) {
|
||||
return read(theType, new IdDt(theId));
|
||||
|
@ -374,7 +388,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IResource read(UriDt theUrl) {
|
||||
public IBaseResource read(UriDt theUrl) {
|
||||
IdDt id = new IdDt(theUrl);
|
||||
String resourceType = id.getResourceType();
|
||||
if (isBlank(resourceType)) {
|
||||
|
@ -384,7 +398,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
if (def == null) {
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(I18N_CANNOT_DETEMINE_RESOURCE_TYPE, theUrl.getValueAsString()));
|
||||
}
|
||||
return (IResource) read(def.getImplementingClass(), id);
|
||||
return (IBaseResource) read(def.getImplementingClass(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -449,7 +463,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> transaction(List<IResource> theResources) {
|
||||
public List<IBaseResource> transaction(List<IBaseResource> theResources) {
|
||||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(theResources, myContext);
|
||||
if (isKeepResponses()) {
|
||||
myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
|
||||
|
@ -457,7 +471,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
Bundle resp = invokeClient(myContext, new BundleResponseHandler(null), invocation, myLogRequestAndResponse);
|
||||
|
||||
return resp.toListOfResources();
|
||||
return new ArrayList<IBaseResource>(resp.toListOfResources());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -680,7 +694,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ICreateTyped resource(IResource theResource) {
|
||||
public ICreateTyped resource(IBaseResource theResource) {
|
||||
Validate.notNull(theResource, "Resource can not be null");
|
||||
myResource = theResource;
|
||||
return this;
|
||||
|
@ -736,7 +750,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private class DeleteInternal extends BaseClientExecutable<IDeleteTyped, BaseOperationOutcome> implements IDelete, IDeleteTyped, IDeleteWithQuery, IDeleteWithQueryTyped {
|
||||
|
||||
private CriterionList myCriterionList;
|
||||
private IdDt myId;
|
||||
private IIdType myId;
|
||||
private String myResourceType;
|
||||
private String mySearchUrl;
|
||||
|
||||
|
@ -775,7 +789,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IDeleteTyped resourceById(IdDt theId) {
|
||||
public IDeleteTyped resourceById(IIdType theId) {
|
||||
Validate.notNull(theId, "theId can not be null");
|
||||
if (theId.hasResourceType() == false || theId.hasIdPart() == false) {
|
||||
throw new IllegalArgumentException("theId must contain a resource type and logical ID at a minimum (e.g. Patient/1234)found: " + theId.getValue());
|
||||
|
@ -914,7 +928,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private class HistoryInternal extends BaseClientExecutable implements IHistory, IHistoryUntyped, IHistoryTyped {
|
||||
|
||||
private Integer myCount;
|
||||
private IdDt myId;
|
||||
private IIdType myId;
|
||||
private Class<? extends IBaseBundle> myReturnType;
|
||||
private InstantDt mySince;
|
||||
private Class<? extends IBaseResource> myType;
|
||||
|
@ -967,7 +981,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IHistoryUntyped onInstance(IdDt theId) {
|
||||
public IHistoryUntyped onInstance(IIdType theId) {
|
||||
if (theId.hasResourceType() == false) {
|
||||
throw new IllegalArgumentException("Resource ID does not have a resource type: " + theId.getValue());
|
||||
}
|
||||
|
@ -1026,7 +1040,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
@SuppressWarnings("rawtypes")
|
||||
private class OperationInternal extends BaseClientExecutable implements IOperation, IOperationUnnamed, IOperationUntyped, IOperationUntypedWithInput {
|
||||
|
||||
private IdDt myId;
|
||||
private IIdType myId;
|
||||
private String myOperationName;
|
||||
private IBaseParameters myParameters;
|
||||
private Class<? extends IBaseResource> myType;
|
||||
|
@ -1054,12 +1068,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
handler = new ResourceResponseHandler(myParameters.getClass(), null);
|
||||
|
||||
Object retVal = invoke(null, handler, invocation);
|
||||
if (myContext.getResourceDefinition((IBaseResource)retVal).getName().equals("Parameters")) {
|
||||
if (myContext.getResourceDefinition((IBaseResource) retVal).getName().equals("Parameters")) {
|
||||
return retVal;
|
||||
} else {
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition("Parameters");
|
||||
IBaseResource parameters = def.newInstance();
|
||||
|
||||
|
||||
BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter");
|
||||
BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter");
|
||||
IBase parameter = paramChildElem.newInstance();
|
||||
|
@ -1067,7 +1081,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
BaseRuntimeChildDefinition resourceElem = paramChildElem.getChildByName("resource");
|
||||
resourceElem.getMutator().addValue(parameter, (IBase) retVal);
|
||||
|
||||
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
@ -1075,12 +1089,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
@Override
|
||||
public IOperationUntyped named(String theName) {
|
||||
Validate.notBlank(theName, "theName can not be null");
|
||||
myOperationName =theName;
|
||||
myOperationName = theName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOperationUnnamed onInstance(IdDt theId) {
|
||||
public IOperationUnnamed onInstance(IIdType theId) {
|
||||
myId = theId;
|
||||
return this;
|
||||
}
|
||||
|
@ -1113,7 +1127,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type: " + theOutputParameterType.getName());
|
||||
}
|
||||
if (!"Parameters".equals(def.getName())) {
|
||||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type for a resource named " + "Parameters" + " - " + theOutputParameterType.getName() + " is a resource named: " + def.getName());
|
||||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type for a resource named " + "Parameters" + " - " + theOutputParameterType.getName()
|
||||
+ " is a resource named: " + def.getName());
|
||||
}
|
||||
myParameters = (IBaseParameters) def.newInstance();
|
||||
return this;
|
||||
|
@ -1290,7 +1305,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
private final class ResourceListResponseHandler implements IClientResponseHandler<List<IResource>> {
|
||||
private final class ResourceListResponseHandler implements IClientResponseHandler<List<IBaseResource>> {
|
||||
|
||||
private Class<? extends IResource> myType;
|
||||
|
||||
|
@ -1300,17 +1315,17 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<IResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||
Class<? extends IBaseResource> bundleType = myContext.getResourceDefinition("Bundle").getImplementingClass();
|
||||
ResourceResponseHandler<IBaseResource> handler = new ResourceResponseHandler<IBaseResource>((Class<IBaseResource>) bundleType, null);
|
||||
IBaseResource response = handler.invokeClient(theResponseMimeType, theResponseReader, theResponseStatusCode, theHeaders);
|
||||
IVersionSpecificBundleFactory bundleFactory = myContext.newBundleFactory();
|
||||
bundleFactory.initializeWithBundleResource((IResource) response);
|
||||
bundleFactory.initializeWithBundleResource((IBaseResource) response);
|
||||
return bundleFactory.toListOfResources();
|
||||
} else {
|
||||
return new BundleResponseHandler(myType).invokeClient(theResponseMimeType, theResponseReader, theResponseStatusCode, theHeaders).toListOfResources();
|
||||
return new ArrayList<IBaseResource>(new BundleResponseHandler(myType).invokeClient(theResponseMimeType, theResponseReader, theResponseStatusCode, theHeaders).toListOfResources());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1340,7 +1355,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
}
|
||||
|
||||
private class SearchInternal extends BaseClientExecutable<IQuery, Bundle> implements IQuery, IUntypedQuery {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private class SearchInternal extends BaseClientExecutable<IQuery<Object>, Object> implements IQuery<Object>, IUntypedQuery {
|
||||
|
||||
private String myCompartmentName;
|
||||
private CriterionList myCriterion = new CriterionList();
|
||||
|
@ -1352,6 +1368,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private Class<? extends IBaseResource> myResourceType;
|
||||
private SearchStyleEnum mySearchStyle;
|
||||
private List<SortInternal> mySort = new ArrayList<SortInternal>();
|
||||
private Class<? extends IBaseBundle> myReturnBundleType;
|
||||
|
||||
public SearchInternal() {
|
||||
myResourceType = null;
|
||||
|
@ -1365,7 +1382,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Bundle execute() {
|
||||
public IBase execute() {
|
||||
|
||||
Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
|
||||
// Map<String, List<String>> initial = createExtraParams();
|
||||
|
@ -1391,7 +1408,17 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
addParam(params, Constants.PARAM_COUNT, Integer.toString(myParamLimit));
|
||||
}
|
||||
|
||||
BundleResponseHandler binding = new BundleResponseHandler(myResourceType);
|
||||
if (myReturnBundleType == null && myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
||||
throw new IllegalArgumentException("When using the client with HL7.org structures, you must specify "
|
||||
+ "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method");
|
||||
}
|
||||
|
||||
IClientResponseHandler binding;
|
||||
if (myReturnBundleType != null) {
|
||||
binding = new ResourceResponseHandler(myReturnBundleType, null);
|
||||
} else {
|
||||
binding = new BundleResponseHandler(myResourceType);
|
||||
}
|
||||
|
||||
IdDt resourceId = myResourceId != null ? new IdDt(myResourceId) : null;
|
||||
|
||||
|
@ -1407,7 +1434,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IQuery forResource(Class<? extends IResource> theResourceType) {
|
||||
public IQuery forResource(Class<? extends IBaseResource> theResourceType) {
|
||||
setType(theResourceType);
|
||||
return this;
|
||||
}
|
||||
|
@ -1434,7 +1461,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return this;
|
||||
}
|
||||
|
||||
private void setType(Class<? extends IResource> theResourceType) {
|
||||
private void setType(Class<? extends IBaseResource> theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
RuntimeResourceDefinition definition = myContext.getResourceDefinition(theResourceType);
|
||||
myResourceName = definition.getName();
|
||||
|
@ -1472,13 +1499,23 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IQuery revinclude(Include theInclude) {
|
||||
public IQuery revInclude(Include theInclude) {
|
||||
myRevInclude.add(theInclude);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClientExecutable returnBundle(Class theClass) {
|
||||
if (theClass == null) {
|
||||
throw new NullPointerException("theClass must not be null");
|
||||
}
|
||||
myReturnBundleType = theClass;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static class SortInternal implements ISort {
|
||||
|
||||
private SearchInternal myFor;
|
||||
|
@ -1537,14 +1574,14 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private final class TransactionExecutable<T> extends BaseClientExecutable<ITransactionTyped<T>, T> implements ITransactionTyped<T> {
|
||||
|
||||
private Bundle myBundle;
|
||||
private List<IResource> myResources;
|
||||
private List<IBaseResource> myResources;
|
||||
private IBaseBundle myBaseBundle;
|
||||
|
||||
public TransactionExecutable(Bundle theResources) {
|
||||
myBundle = theResources;
|
||||
}
|
||||
|
||||
public TransactionExecutable(List<IResource> theResources) {
|
||||
public TransactionExecutable(List<IBaseResource> theResources) {
|
||||
myResources = theResources;
|
||||
}
|
||||
|
||||
|
@ -1561,9 +1598,9 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myResources, myContext);
|
||||
return (T) invoke(params, binding, invocation);
|
||||
} else if (myBaseBundle != null) {
|
||||
ResourceResponseHandler binding = new ResourceResponseHandler(myBaseBundle.getClass(),null);
|
||||
ResourceResponseHandler binding = new ResourceResponseHandler(myBaseBundle.getClass(), null);
|
||||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myBaseBundle, myContext);
|
||||
return (T) invoke(params, binding, invocation);
|
||||
return (T) invoke(params, binding, invocation);
|
||||
} else {
|
||||
BundleResponseHandler binding = new BundleResponseHandler(null);
|
||||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myBundle, myContext);
|
||||
|
@ -1582,9 +1619,9 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ITransactionTyped<List<IResource>> withResources(List<IResource> theResources) {
|
||||
public ITransactionTyped<List<IBaseResource>> withResources(List<IBaseResource> theResources) {
|
||||
Validate.notNull(theResources, "theResources must not be null");
|
||||
return new TransactionExecutable<List<IResource>>(theResources);
|
||||
return new TransactionExecutable<List<IBaseResource>>(theResources);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1658,7 +1695,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IUpdateTyped resource(IResource theResource) {
|
||||
public IUpdateTyped resource(IBaseResource theResource) {
|
||||
Validate.notNull(theResource, "Resource can not be null");
|
||||
myResource = theResource;
|
||||
return this;
|
||||
|
@ -1703,4 +1740,36 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private class FetchConformanceInternal extends BaseClientExecutable implements IFetchConformanceUntyped, IFetchConformanceTyped {
|
||||
private RuntimeResourceDefinition myType;
|
||||
|
||||
@Override
|
||||
public Object execute() {
|
||||
ResourceResponseHandler binding = new ResourceResponseHandler(myType.getImplementingClass(), null);
|
||||
HttpGetClientInvocation invocation = MethodUtil.createConformanceInvocation();
|
||||
return invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends IBaseConformance> IFetchConformanceTyped<T> ofType(Class<T> theResourceType) {
|
||||
Validate.notNull(theResourceType, "theResourceType must not be null");
|
||||
myType = myContext.getResourceDefinition(theResourceType);
|
||||
if (myType == null) {
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(I18N_CANNOT_DETEMINE_RESOURCE_TYPE, theResourceType));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.rest.gclient.ICreate;
|
||||
import ca.uhn.fhir.rest.gclient.IDelete;
|
||||
import ca.uhn.fhir.rest.gclient.IFetchConformanceUntyped;
|
||||
import ca.uhn.fhir.rest.gclient.IGetPage;
|
||||
import ca.uhn.fhir.rest.gclient.IGetTags;
|
||||
import ca.uhn.fhir.rest.gclient.IHistory;
|
||||
|
@ -49,9 +50,17 @@ public interface IGenericClient extends IRestfulClient {
|
|||
|
||||
/**
|
||||
* Retrieves and returns the server conformance statement
|
||||
*
|
||||
* @deprecated Use {@link #fetchConformance()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
BaseConformance conformance();
|
||||
|
||||
/**
|
||||
* Retrieves the server's conformance statement
|
||||
*/
|
||||
IFetchConformanceUntyped fetchConformance();
|
||||
|
||||
/**
|
||||
* Fluent method for the "create" operation, which creates a new resource instance on the server
|
||||
*/
|
||||
|
@ -217,7 +226,7 @@ public interface IGenericClient extends IRestfulClient {
|
|||
* The absolute URL, e.g. "http://example.com/fhir/Patient/123"
|
||||
* @return The returned resource from the server
|
||||
*/
|
||||
IResource read(UriDt theUrl);
|
||||
IBaseResource read(UriDt theUrl);
|
||||
|
||||
/**
|
||||
* Register a new interceptor for this client. An interceptor can be used to add additional logging, or add security
|
||||
|
@ -274,7 +283,7 @@ public interface IGenericClient extends IRestfulClient {
|
|||
*
|
||||
*/
|
||||
@Deprecated
|
||||
List<IResource> transaction(List<IResource> theResources);
|
||||
List<IBaseResource> transaction(List<IBaseResource> theResources);
|
||||
|
||||
/**
|
||||
* Remove an intercaptor that was previously registered using
|
||||
|
@ -363,4 +372,5 @@ public interface IGenericClient extends IRestfulClient {
|
|||
*/
|
||||
<T extends IBaseResource> T vread(Class<T> theType, String theId, String theVersionId);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -43,15 +43,17 @@ import org.apache.http.impl.client.HttpClientBuilder;
|
|||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.client.ProxyAuthenticationStrategy;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.IPrimitiveType;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.model.base.resource.BaseConformance;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
|
||||
public class RestfulClientFactory implements IRestfulClientFactory {
|
||||
|
||||
|
@ -267,26 +269,34 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
myHttpClient = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void validateServerBase(String theServerBase, HttpClient theHttpClient) {
|
||||
|
||||
GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this);
|
||||
client.setDontValidateConformance(true);
|
||||
|
||||
BaseConformance conformance;
|
||||
IBaseResource conformance;
|
||||
try {
|
||||
conformance = client.conformance();
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class implementingClass = myContext.getResourceDefinition("Conformance").getImplementingClass();
|
||||
conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute();
|
||||
} catch (FhirClientConnectionException e) {
|
||||
throw new FhirClientConnectionException(myContext.getLocalizer().getMessage(RestfulClientFactory.class, "failedToRetrieveConformance", theServerBase + Constants.URL_TOKEN_METADATA), e);
|
||||
}
|
||||
|
||||
String serverFhirVersionString = conformance.getFhirVersionElement().getValueAsString();
|
||||
FhirTerser t = myContext.newTerser();
|
||||
String serverFhirVersionString = null;
|
||||
Object value = t.getSingleValueOrNull(conformance, "fhirVersion");
|
||||
if (value instanceof IPrimitiveType) {
|
||||
serverFhirVersionString = ((IPrimitiveType<?>) value).getValueAsString();
|
||||
}
|
||||
FhirVersionEnum serverFhirVersionEnum = null;
|
||||
if (StringUtils.isBlank(serverFhirVersionString)) {
|
||||
// we'll be lenient and accept this
|
||||
} else {
|
||||
if (serverFhirVersionString.startsWith("0.80") || serverFhirVersionString.startsWith("0.0.8")) {
|
||||
serverFhirVersionEnum = FhirVersionEnum.DSTU1;
|
||||
} else if (serverFhirVersionString.startsWith("0.4")) {
|
||||
} else if (serverFhirVersionString.startsWith("0.4") || serverFhirVersionString.startsWith("0.5")) {
|
||||
serverFhirVersionEnum = FhirVersionEnum.DSTU2;
|
||||
} else {
|
||||
// we'll be lenient and accept this
|
||||
|
|
|
@ -21,8 +21,7 @@ package ca.uhn.fhir.rest.gclient;
|
|||
*/
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
public interface IBaseOn<T> {
|
||||
|
||||
|
@ -43,6 +42,6 @@ public interface IBaseOn<T> {
|
|||
*
|
||||
* @throws IllegalArgumentException If <code>theId</code> does not contain at least a resource type and ID
|
||||
*/
|
||||
T onInstance(IdDt theId);
|
||||
T onInstance(IIdType theId);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
|
@ -23,7 +23,7 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
*/
|
||||
|
||||
public interface ICreate {
|
||||
ICreateTyped resource(IResource theResource);
|
||||
ICreateTyped resource(IBaseResource theResource);
|
||||
|
||||
ICreateTyped resource(String theResourceAsText);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
|
@ -27,7 +28,7 @@ public interface IDelete {
|
|||
|
||||
IDeleteTyped resource(IResource theResource);
|
||||
|
||||
IDeleteTyped resourceById(IdDt theId);
|
||||
IDeleteTyped resourceById(IIdType theId);
|
||||
|
||||
IDeleteTyped resourceById(String theResourceType, String theLogicalId);
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
|
||||
public interface IFetchConformanceTyped<T extends IBaseConformance> extends IClientExecutable<IFetchConformanceTyped<T>, T> {
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
|
||||
public interface IFetchConformanceUntyped {
|
||||
|
||||
/**
|
||||
* Retrieve the conformance statement using the given model type
|
||||
*/
|
||||
<T extends IBaseConformance> IFetchConformanceTyped<T> ofType(Class<T> theType);
|
||||
|
||||
}
|
|
@ -20,20 +20,21 @@ package ca.uhn.fhir.rest.gclient;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.rest.method.SearchStyleEnum;
|
||||
|
||||
public interface IQuery extends IClientExecutable<IQuery, Bundle>, IBaseQuery<IQuery> {
|
||||
public interface IQuery<T> extends IClientExecutable<IQuery<T>, T>, IBaseQuery<IQuery<T>> {
|
||||
|
||||
/**
|
||||
* Add an "_include" specification
|
||||
*/
|
||||
IQuery include(Include theInclude);
|
||||
IQuery<T> include(Include theInclude);
|
||||
|
||||
ISort sort();
|
||||
ISort<T> sort();
|
||||
|
||||
IQuery limitTo(int theLimitTo);
|
||||
IQuery<T> limitTo(int theLimitTo);
|
||||
|
||||
/**
|
||||
* Forces the query to perform the search using the given method (allowable methods are described in the
|
||||
|
@ -42,15 +43,21 @@ public interface IQuery extends IClientExecutable<IQuery, Bundle>, IBaseQuery<IQ
|
|||
* @see SearchStyleEnum
|
||||
* @since 0.6
|
||||
*/
|
||||
IQuery usingStyle(SearchStyleEnum theStyle);
|
||||
IQuery<T> usingStyle(SearchStyleEnum theStyle);
|
||||
|
||||
IQuery withIdAndCompartment(String theResourceId, String theCompartmentName);
|
||||
IQuery<T> withIdAndCompartment(String theResourceId, String theCompartmentName);
|
||||
|
||||
/**
|
||||
* Add a "_revinclude" specification
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
IQuery revinclude(Include theIncludeTarget);
|
||||
IQuery<T> revInclude(Include theIncludeTarget);
|
||||
|
||||
/**
|
||||
* Request that the client return the specified bundle type, e.g. <code>org.hl7.fhir.instance.model.Bundle.class</code>
|
||||
* or <code>ca.uhn.fhir.model.dstu2.resource.Bundle.class</code>
|
||||
*/
|
||||
<B extends IBaseBundle> IClientExecutable<IQuery<B>, B> returnBundle(Class<B> theClass);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@ package ca.uhn.fhir.rest.gclient;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
public interface ISort {
|
||||
public interface ISort<T> {
|
||||
|
||||
IQuery ascending(IParam theParam);
|
||||
IQuery<T> ascending(IParam theParam);
|
||||
|
||||
IQuery defaultOrder(IParam theParam);
|
||||
IQuery<T> defaultOrder(IParam theParam);
|
||||
|
||||
IQuery descending(IParam theParam);
|
||||
IQuery<T> descending(IParam theParam);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,17 +22,17 @@ package ca.uhn.fhir.rest.gclient;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
||||
public interface ITransaction {
|
||||
|
||||
/**
|
||||
* Use a list of resources as the transaction input
|
||||
*/
|
||||
ITransactionTyped<List<IResource>> withResources(List<IResource> theResources);
|
||||
ITransactionTyped<List<IBaseResource>> withResources(List<IBaseResource> theResources);
|
||||
|
||||
/**
|
||||
* Use a DSTU1 Bundle (Atom) as the transaction input
|
||||
|
|
|
@ -20,15 +20,17 @@ package ca.uhn.fhir.rest.gclient;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
|
||||
|
||||
public interface IUntypedQuery {
|
||||
|
||||
IQuery forAllResources();
|
||||
IQuery<Bundle> forAllResources();
|
||||
|
||||
IQuery forResource(String theResourceName);
|
||||
IQuery<Bundle> forResource(String theResourceName);
|
||||
|
||||
IQuery forResource(Class<? extends IResource> theClass);
|
||||
IQuery<Bundle> forResource(Class<? extends IBaseResource> theClass);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,11 +20,11 @@ package ca.uhn.fhir.rest.gclient;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
public interface IUpdate {
|
||||
|
||||
IUpdateTyped resource(IResource theResource);
|
||||
IUpdateTyped resource(IBaseResource theResource);
|
||||
|
||||
IUpdateTyped resource(String theResourceBody);
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ import org.hl7.fhir.instance.model.api.IBaseBinary;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
@ -64,7 +63,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
|
|||
private String myIfNoneExistString;
|
||||
private Map<String, List<String>> myParams;
|
||||
private final IBaseResource myResource;
|
||||
private final List<IResource> myResources;
|
||||
private final List<IBaseResource> myResources;
|
||||
private final TagList myTagList;
|
||||
private final String myUrlPath;
|
||||
|
||||
|
@ -104,7 +103,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
|
|||
myBundleType = null;
|
||||
}
|
||||
|
||||
public BaseHttpClientInvocationWithContents(FhirContext theContext, List<IResource> theResources, BundleTypeEnum theBundleType) {
|
||||
public BaseHttpClientInvocationWithContents(FhirContext theContext, List<IBaseResource> theResources, BundleTypeEnum theBundleType) {
|
||||
myContext = theContext;
|
||||
myResource = null;
|
||||
myTagList = null;
|
||||
|
|
|
@ -510,9 +510,9 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
|||
} else if (response instanceof IResource) {
|
||||
return BundleProviders.newList((IResource) response);
|
||||
} else if (response instanceof Collection) {
|
||||
List<IResource> retVal = new ArrayList<IResource>();
|
||||
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
for (Object next : ((Collection<?>) response)) {
|
||||
retVal.add((IResource) next);
|
||||
retVal.add((IBaseResource) next);
|
||||
}
|
||||
return BundleProviders.newList(retVal);
|
||||
} else {
|
||||
|
|
|
@ -255,7 +255,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
case BUNDLE: {
|
||||
|
||||
if (getMethodReturnType() == MethodReturnTypeEnum.BUNDLE_RESOURCE) {
|
||||
IResource resource;
|
||||
IBaseResource resource;
|
||||
if (resultObj instanceof IBundleProvider) {
|
||||
IBundleProvider result = (IBundleProvider) resultObj;
|
||||
resource = result.getResources(0, 1).get(0);
|
||||
|
@ -326,7 +326,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
throw new InternalErrorException("Method returned multiple resources");
|
||||
}
|
||||
|
||||
IResource resource = result.getResources(0, 1).get(0);
|
||||
IBaseResource resource = result.getResources(0, 1).get(0);
|
||||
|
||||
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
|
||||
IServerInterceptor next = theServer.getInterceptors().get(i);
|
||||
|
|
|
@ -26,6 +26,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
|
@ -140,7 +142,7 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public static HttpDeleteClientInvocation createDeleteInvocation(IdDt theId) {
|
||||
public static HttpDeleteClientInvocation createDeleteInvocation(IIdType theId) {
|
||||
HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theId);
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -186,15 +186,15 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> getResources(int theFromIndex, int theToIndex) {
|
||||
List<IResource> retVal = resources.getResources(theFromIndex, theToIndex);
|
||||
public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
|
||||
List<IBaseResource> retVal = resources.getResources(theFromIndex, theToIndex);
|
||||
int index = theFromIndex;
|
||||
for (IResource nextResource : retVal) {
|
||||
for (IBaseResource nextResource : retVal) {
|
||||
if (nextResource.getId() == null || isBlank(nextResource.getId().getIdPart())) {
|
||||
throw new InternalErrorException("Server provided resource at index " + index + " with no ID set (using IResource#setId(IdDt))");
|
||||
}
|
||||
if (isBlank(nextResource.getId().getVersionIdPart())) {
|
||||
IdDt versionId = (IdDt) ResourceMetadataKeyEnum.VERSION_ID.get(nextResource);
|
||||
if (isBlank(nextResource.getId().getVersionIdPart()) && nextResource instanceof IResource) {
|
||||
IdDt versionId = (IdDt) ResourceMetadataKeyEnum.VERSION_ID.get((IResource) nextResource);
|
||||
if (versionId == null || versionId.isEmpty()) {
|
||||
throw new InternalErrorException("Server provided resource at index " + index + " with no Version ID set (using IResource#setId(IdDt))");
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ import java.util.Map;
|
|||
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class HttpDeleteClientInvocation extends BaseHttpClientInvocation {
|
|||
private String myUrlPath;
|
||||
private Map<String, List<String>> myParams;
|
||||
|
||||
public HttpDeleteClientInvocation(IdDt theId) {
|
||||
public HttpDeleteClientInvocation(IIdType theId) {
|
||||
super();
|
||||
myUrlPath = theId.toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.hl7.fhir.instance.model.IBaseResource;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
|
||||
|
@ -48,7 +47,7 @@ public class HttpPostClientInvocation extends BaseHttpClientInvocationWithConten
|
|||
super(theContext, theTagList, theUrlExtension);
|
||||
}
|
||||
|
||||
public HttpPostClientInvocation(FhirContext theContext, List<IResource> theResources, BundleTypeEnum theBundleType) {
|
||||
public HttpPostClientInvocation(FhirContext theContext, List<IBaseResource> theResources, BundleTypeEnum theBundleType) {
|
||||
super(theContext, theResources, theBundleType);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ import ca.uhn.fhir.model.api.Bundle;
|
|||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
|
@ -237,12 +236,12 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
|
||||
Map<String, List<String>> params = new HashMap<String, List<String>>();
|
||||
for (Object nextParameter : parameters) {
|
||||
StringDt nextNameDt = (StringDt) t.getSingleValueOrNull((IBase) nextParameter, "name");
|
||||
IPrimitiveType<?> nextNameDt = (IPrimitiveType<?>) t.getSingleValueOrNull((IBase) nextParameter, "name");
|
||||
if (nextNameDt == null || nextNameDt.isEmpty()) {
|
||||
ourLog.warn("Ignoring input parameter with no value in Parameters.parameter.name in operation client invocation");
|
||||
continue;
|
||||
}
|
||||
String nextName = nextNameDt.getValue();
|
||||
String nextName = nextNameDt.getValueAsString();
|
||||
if (!params.containsKey(nextName)) {
|
||||
params.put(nextName, new ArrayList<String>());
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
|||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IAccessor;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.context.RuntimeChildPrimitiveDatatypeDefinition;
|
||||
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
|
@ -51,6 +52,7 @@ class OperationParamBinder implements IParameter {
|
|||
|
||||
private final String myName;
|
||||
private Class<?> myParameterType;
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Class<? extends Collection> myInnerCollectionType;
|
||||
private final String myOperationName;
|
||||
|
||||
|
@ -72,30 +74,36 @@ class OperationParamBinder implements IParameter {
|
|||
BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter");
|
||||
BaseRuntimeElementCompositeDefinition<?> paramChildElem = (BaseRuntimeElementCompositeDefinition<?>) paramChild.getChildByName("parameter");
|
||||
|
||||
addClientParameter(theSourceClientArgument, theTargetResource, paramChild, paramChildElem);
|
||||
addClientParameter(theContext, theSourceClientArgument, theTargetResource, paramChild, paramChildElem);
|
||||
}
|
||||
|
||||
private void addClientParameter(Object theSourceClientArgument, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem) {
|
||||
private void addClientParameter(FhirContext theContext, Object theSourceClientArgument, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem) {
|
||||
if (theSourceClientArgument instanceof IBaseResource) {
|
||||
IBase parameter = createParameterRepetition(theTargetResource, paramChild, paramChildElem);
|
||||
IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem);
|
||||
paramChildElem.getChildByName("resource").getMutator().addValue(parameter, (IBaseResource) theSourceClientArgument);
|
||||
} else if (theSourceClientArgument instanceof IBaseDatatype) {
|
||||
IBase parameter = createParameterRepetition(theTargetResource, paramChild, paramChildElem);
|
||||
IBase parameter = createParameterRepetition(theContext, theTargetResource, paramChild, paramChildElem);
|
||||
paramChildElem.getChildByName("value[x]").getMutator().addValue(parameter, (IBaseDatatype) theSourceClientArgument);
|
||||
} else if (theSourceClientArgument instanceof Collection) {
|
||||
Collection<?> collection = (Collection<?>) theSourceClientArgument;
|
||||
for (Object next : collection) {
|
||||
addClientParameter(next, theTargetResource, paramChild, paramChildElem);
|
||||
addClientParameter(theContext, next, theTargetResource, paramChild, paramChildElem);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to handle value of type " + theSourceClientArgument.getClass() + " for paramater " + myName);
|
||||
}
|
||||
}
|
||||
|
||||
private IBase createParameterRepetition(IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem) {
|
||||
private IBase createParameterRepetition(FhirContext theContext, IBaseResource theTargetResource, BaseRuntimeChildDefinition paramChild, BaseRuntimeElementCompositeDefinition<?> paramChildElem) {
|
||||
IBase parameter = paramChildElem.newInstance();
|
||||
paramChild.getMutator().addValue(theTargetResource, parameter);
|
||||
paramChildElem.getChildByName("name").getMutator().addValue(parameter, new StringDt(myName));
|
||||
IPrimitiveType<?> value;
|
||||
if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
||||
value = (IPrimitiveType<?>) theContext.getElementDefinition("string").newInstance(myName);
|
||||
} else {
|
||||
value = new StringDt(myName);
|
||||
}
|
||||
paramChildElem.getChildByName("name").getMutator().addValue(parameter, value);
|
||||
return parameter;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,8 +205,8 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
|||
if (theRequest.getServer().getETagSupport() == ETagSupportEnum.ENABLED) {
|
||||
String ifNoneMatch = ((Request)theRequest).getServletRequest().getHeader(Constants.HEADER_IF_NONE_MATCH_LC);
|
||||
if (retVal.size() == 1 && StringUtils.isNotBlank(ifNoneMatch)) {
|
||||
List<IResource> responseResources = retVal.getResources(0, 1);
|
||||
IResource responseResource = responseResources.get(0);
|
||||
List<IBaseResource> responseResources = retVal.getResources(0, 1);
|
||||
IBaseResource responseResource = responseResources.get(0);
|
||||
|
||||
ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch);
|
||||
if (responseResource.getId() != null && responseResource.getId().hasVersionIdPart()) {
|
||||
|
|
|
@ -20,13 +20,14 @@ package ca.uhn.fhir.rest.method;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
|
@ -117,7 +118,7 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
|
|||
return createTransactionInvocation(bundle, context);
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IResource> resources = (List<IResource>) theArgs[myTransactionParamIndex];
|
||||
List<IBaseResource> resources = (List<IBaseResource>) theArgs[myTransactionParamIndex];
|
||||
return createTransactionInvocation(resources, context);
|
||||
}
|
||||
}
|
||||
|
@ -161,10 +162,10 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
|
|||
* " entries, but server method response contained " + retVal.size() + " entries (must be the same)"); } }
|
||||
*/
|
||||
|
||||
List<IResource> retResources = retVal.getResources(0, retVal.size());
|
||||
List<IBaseResource> retResources = retVal.getResources(0, retVal.size());
|
||||
for (int i = 0; i < retResources.size(); i++) {
|
||||
IdDt oldId = oldIds.get(retResources.get(i));
|
||||
IResource newRes = retResources.get(i);
|
||||
IBaseResource newRes = retResources.get(i);
|
||||
if (newRes.getId() == null || newRes.getId().isEmpty()) {
|
||||
if (!(newRes instanceof BaseOperationOutcome)) {
|
||||
throw new InternalErrorException("Transaction method returned resource at index " + i + " with no id specified - IResource#setId(IdDt)");
|
||||
|
@ -172,8 +173,8 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
|
|||
}
|
||||
|
||||
if (oldId != null && !oldId.isEmpty()) {
|
||||
if (!oldId.equals(newRes.getId())) {
|
||||
newRes.getResourceMetadata().put(ResourceMetadataKeyEnum.PREVIOUS_ID, oldId);
|
||||
if (!oldId.equals(newRes.getId()) && newRes instanceof IResource) {
|
||||
((IResource)newRes).getResourceMetadata().put(ResourceMetadataKeyEnum.PREVIOUS_ID, oldId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +195,7 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
|
|||
return new HttpPostClientInvocation(theContext, theBundle);
|
||||
}
|
||||
|
||||
public static BaseHttpClientInvocation createTransactionInvocation(List<IResource> theResources, FhirContext theContext) {
|
||||
public static BaseHttpClientInvocation createTransactionInvocation(List<IBaseResource> theResources, FhirContext theContext) {
|
||||
return new HttpPostClientInvocation(theContext, theResources, BundleTypeEnum.TRANSACTION);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ package ca.uhn.fhir.rest.server;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
|
||||
|
@ -43,7 +45,7 @@ public class BundleProviders {
|
|||
final InstantDt published = InstantDt.withCurrentTime();
|
||||
return new IBundleProvider() {
|
||||
@Override
|
||||
public List<IResource> getResources(int theFromIndex, int theToIndex) {
|
||||
public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
@ -64,11 +66,11 @@ public class BundleProviders {
|
|||
};
|
||||
}
|
||||
|
||||
public static IBundleProvider newList(IResource theResource) {
|
||||
public static IBundleProvider newList(IBaseResource theResource) {
|
||||
return new SimpleBundleProvider(theResource);
|
||||
}
|
||||
|
||||
public static IBundleProvider newList(List<IResource> theResources) {
|
||||
public static IBundleProvider newList(List<IBaseResource> theResources) {
|
||||
return new SimpleBundleProvider(theResources);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ import java.util.UUID;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
|
@ -57,7 +59,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
|
||||
|
||||
@Override
|
||||
public void addResourcesToBundle(List<IResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes) {
|
||||
public void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes) {
|
||||
if (myBundle == null) {
|
||||
myBundle = new Bundle();
|
||||
}
|
||||
|
@ -65,14 +67,15 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
List<IResource> includedResources = new ArrayList<IResource>();
|
||||
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
|
||||
|
||||
for (IResource next : theResult) {
|
||||
for (IBaseResource next : theResult) {
|
||||
if (next.getId().isEmpty() == false) {
|
||||
addedResourceIds.add(next.getId());
|
||||
addedResourceIds.add((IdDt) next.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (IResource next : theResult) {
|
||||
|
||||
for (IBaseResource nextBaseRes : theResult) {
|
||||
IResource next = (IResource)nextBaseRes;
|
||||
|
||||
Set<String> containedIds = new HashSet<String>();
|
||||
for (IResource nextContained : next.getContained().getContainedResources()) {
|
||||
if (nextContained.getId().isEmpty() == false) {
|
||||
|
@ -152,7 +155,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
public void initializeBundleFromBundleProvider(RestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint, int theOffset, Integer theLimit, String theSearchId, BundleTypeEnum theBundleType, Set<Include> theIncludes) {
|
||||
int numToReturn;
|
||||
String searchId = null;
|
||||
List<IResource> resourceList;
|
||||
List<IBaseResource> resourceList;
|
||||
if (theServer.getPagingProvider() == null) {
|
||||
numToReturn = theResult.size();
|
||||
resourceList = theResult.getResources(0, numToReturn);
|
||||
|
@ -180,7 +183,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
}
|
||||
|
||||
for (IResource next : resourceList) {
|
||||
for (IBaseResource next : resourceList) {
|
||||
if (next.getId() == null || next.getId().isEmpty()) {
|
||||
if (!(next instanceof BaseOperationOutcome)) {
|
||||
throw new InternalErrorException("Server method returned resource of type[" + next.getClass().getSimpleName() + "] with no ID specified (IResource#setId(IdDt) must be called)");
|
||||
|
@ -189,7 +192,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
|
||||
if (theServer.getAddProfileTag() != AddProfileTagEnum.NEVER) {
|
||||
for (IResource nextRes : resourceList) {
|
||||
for (IBaseResource nextRes : resourceList) {
|
||||
RuntimeResourceDefinition def = theServer.getFhirContext().getResourceDefinition(nextRes);
|
||||
if (theServer.getAddProfileTag() == AddProfileTagEnum.ALWAYS || !def.isStandardProfile()) {
|
||||
RestfulServerUtils.addProfileToBundleEntry(theServer.getFhirContext(), nextRes, theServerBase);
|
||||
|
@ -197,7 +200,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
}
|
||||
|
||||
addResourcesToBundle(resourceList, theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
||||
addResourcesToBundle(new ArrayList<IBaseResource>(resourceList), theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
||||
addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
|
||||
|
||||
myBundle.setPublished(theResult.getPublished());
|
||||
|
@ -261,7 +264,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initializeBundleFromResourceList(String theAuthor, List<IResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
||||
public void initializeBundleFromResourceList(String theAuthor, List<IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
||||
myBundle = new Bundle();
|
||||
|
||||
myBundle.getAuthorName().setValue(theAuthor);
|
||||
|
@ -271,17 +274,18 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
myBundle.getLinkSelf().setValue(theCompleteUrl);
|
||||
myBundle.getType().setValueAsEnum(theBundleType);
|
||||
|
||||
List<IResource> includedResources = new ArrayList<IResource>();
|
||||
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
|
||||
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
|
||||
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
|
||||
|
||||
for (IResource next : theResult) {
|
||||
for (IBaseResource next : theResult) {
|
||||
if (next.getId().isEmpty() == false) {
|
||||
addedResourceIds.add(next.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (IResource next : theResult) {
|
||||
|
||||
for (IBaseResource nextRes : theResult) {
|
||||
IResource next = (IResource) nextRes;
|
||||
|
||||
Set<String> containedIds = new HashSet<String>();
|
||||
for (IResource nextContained : next.getContained().getContainedResources()) {
|
||||
if (nextContained.getId().isEmpty() == false) {
|
||||
|
@ -301,26 +305,26 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
|
||||
List<BaseResourceReferenceDt> references = myContext.newTerser().getAllPopulatedChildElementsOfType(next, BaseResourceReferenceDt.class);
|
||||
do {
|
||||
List<IResource> addedResourcesThisPass = new ArrayList<IResource>();
|
||||
List<IBaseResource> addedResourcesThisPass = new ArrayList<IBaseResource>();
|
||||
|
||||
for (BaseResourceReferenceDt nextRef : references) {
|
||||
IResource nextRes = (IResource) nextRef.getResource();
|
||||
if (nextRes != null) {
|
||||
if (nextRes.getId().hasIdPart()) {
|
||||
if (containedIds.contains(nextRes.getId().getValue())) {
|
||||
IBaseResource nextRefRes = (IBaseResource) nextRef.getResource();
|
||||
if (nextRefRes != null) {
|
||||
if (nextRefRes.getId().hasIdPart()) {
|
||||
if (containedIds.contains(nextRefRes.getId().getValue())) {
|
||||
// Don't add contained IDs as top level resources
|
||||
continue;
|
||||
}
|
||||
|
||||
IdDt id = nextRes.getId();
|
||||
IIdType id = nextRefRes.getId();
|
||||
if (id.hasResourceType() == false) {
|
||||
String resName = myContext.getResourceDefinition(nextRes).getName();
|
||||
String resName = myContext.getResourceDefinition(nextRefRes).getName();
|
||||
id = id.withResourceType(resName);
|
||||
}
|
||||
|
||||
if (!addedResourceIds.contains(id)) {
|
||||
addedResourceIds.add(id);
|
||||
addedResourcesThisPass.add(nextRes);
|
||||
addedResourcesThisPass.add(nextRefRes);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -329,7 +333,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
|
||||
// Linked resources may themselves have linked resources
|
||||
references = new ArrayList<BaseResourceReferenceDt>();
|
||||
for (IResource iResource : addedResourcesThisPass) {
|
||||
for (IBaseResource iResource : addedResourcesThisPass) {
|
||||
List<BaseResourceReferenceDt> newReferences = myContext.newTerser().getAllPopulatedChildElementsOfType(iResource, BaseResourceReferenceDt.class);
|
||||
references.addAll(newReferences);
|
||||
}
|
||||
|
@ -345,8 +349,8 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
/*
|
||||
* Actually add the resources to the bundle
|
||||
*/
|
||||
for (IResource next : includedResources) {
|
||||
BundleEntry entry = myBundle.addResource(next, myContext, theServerBase);
|
||||
for (IBaseResource next : includedResources) {
|
||||
BundleEntry entry = myBundle.addResource((IResource) next, myContext, theServerBase);
|
||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||
if (entry.getSearchMode().isEmpty()) {
|
||||
entry.getSearchMode().setValueAsEnum(BundleEntrySearchModeEnum.INCLUDE);
|
||||
|
@ -358,14 +362,14 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initializeWithBundleResource(IResource theResource) {
|
||||
public void initializeWithBundleResource(IBaseResource theResource) {
|
||||
throw new UnsupportedOperationException("DSTU1 server doesn't support resource style bundles");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<IResource> toListOfResources() {
|
||||
return myBundle.toListOfResources();
|
||||
public List<IBaseResource> toListOfResources() {
|
||||
return new ArrayList<IBaseResource>( myBundle.toListOfResources());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ package ca.uhn.fhir.rest.server;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
|
||||
public interface IBundleProvider {
|
||||
|
@ -37,7 +38,7 @@ public interface IBundleProvider {
|
|||
* @param theToIndex The high index (exclusive) to return
|
||||
* @return A list of resources. The size of this list must be at least <code>theToIndex - theFromIndex</code>.
|
||||
*/
|
||||
List<IResource> getResources(int theFromIndex, int theToIndex);
|
||||
List<IBaseResource> getResources(int theFromIndex, int theToIndex);
|
||||
|
||||
/**
|
||||
* Optionally may be used to signal a preferred page size to the server, e.g. because
|
||||
|
|
|
@ -23,8 +23,9 @@ package ca.uhn.fhir.rest.server;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
|
||||
|
@ -34,7 +35,7 @@ import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
|||
*/
|
||||
public interface IVersionSpecificBundleFactory {
|
||||
|
||||
void addResourcesToBundle(List<IResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes);
|
||||
void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes);
|
||||
|
||||
void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType);
|
||||
|
||||
|
@ -43,12 +44,12 @@ public interface IVersionSpecificBundleFactory {
|
|||
|
||||
Bundle getDstu1Bundle();
|
||||
|
||||
IResource getResourceBundle();
|
||||
IBaseResource getResourceBundle();
|
||||
|
||||
void initializeBundleFromResourceList(String theAuthor, List<IResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType);
|
||||
void initializeBundleFromResourceList(String theAuthor, List<IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType);
|
||||
|
||||
void initializeWithBundleResource(IResource theResource);
|
||||
void initializeWithBundleResource(IBaseResource theResource);
|
||||
|
||||
List<IResource> toListOfResources();
|
||||
List<IBaseResource> toListOfResources();
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.io.OutputStreamWriter;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -39,7 +40,10 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.utils.DateUtils;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
|
@ -49,7 +53,6 @@ import ca.uhn.fhir.model.api.Include;
|
|||
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.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.method.Request;
|
||||
|
@ -72,13 +75,13 @@ public class RestfulServerUtils {
|
|||
return count;
|
||||
}
|
||||
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase) throws IOException {
|
||||
theHttpResponse.setStatus(stausCode);
|
||||
|
||||
if (theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {
|
||||
String resName = theServer.getFhirContext().getResourceDefinition(theResource).getName();
|
||||
IdDt fullId = theResource.getId().withServerBase(theServerBase, resName);
|
||||
IIdType fullId = theResource.getId().withServerBase(theServerBase, resName);
|
||||
theHttpResponse.addHeader(Constants.HEADER_CONTENT_LOCATION, fullId.getValue());
|
||||
}
|
||||
|
||||
|
@ -130,24 +133,31 @@ public class RestfulServerUtils {
|
|||
|
||||
theServer.addHeadersToResponse(theHttpResponse);
|
||||
|
||||
InstantDt lastUpdated = ResourceMetadataKeyEnum.UPDATED.get(theResource);
|
||||
if (lastUpdated != null && lastUpdated.isEmpty() == false) {
|
||||
theHttpResponse.addHeader(Constants.HEADER_LAST_MODIFIED, DateUtils.formatDate(lastUpdated.getValue()));
|
||||
}
|
||||
|
||||
TagList list = (TagList) theResource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
|
||||
if (list != null) {
|
||||
for (Tag tag : list) {
|
||||
if (StringUtils.isNotBlank(tag.getTerm())) {
|
||||
theHttpResponse.addHeader(Constants.HEADER_CATEGORY, tag.toHeaderValue());
|
||||
if (theResource instanceof IResource) {
|
||||
InstantDt lastUpdated = ResourceMetadataKeyEnum.UPDATED.get((IResource) theResource);
|
||||
if (lastUpdated != null && lastUpdated.isEmpty() == false) {
|
||||
theHttpResponse.addHeader(Constants.HEADER_LAST_MODIFIED, DateUtils.formatDate(lastUpdated.getValue()));
|
||||
}
|
||||
|
||||
TagList list = (TagList) ((IResource)theResource).getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
|
||||
if (list != null) {
|
||||
for (Tag tag : list) {
|
||||
if (StringUtils.isNotBlank(tag.getTerm())) {
|
||||
theHttpResponse.addHeader(Constants.HEADER_CATEGORY, tag.toHeaderValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Date lastUpdated = ((IAnyResource)theResource).getMeta().getLastUpdated();
|
||||
if (lastUpdated != null) {
|
||||
theHttpResponse.addHeader(Constants.HEADER_LAST_MODIFIED, DateUtils.formatDate(lastUpdated));
|
||||
}
|
||||
}
|
||||
|
||||
Writer writer = getWriter(theHttpResponse, theRespondGzip);
|
||||
try {
|
||||
if (theNarrativeMode == RestfulServer.NarrativeModeEnum.ONLY) {
|
||||
writer.append(theResource.getText().getDiv().getValueAsString());
|
||||
if (theNarrativeMode == RestfulServer.NarrativeModeEnum.ONLY && theResource instanceof IResource) {
|
||||
writer.append(((IResource)theResource).getText().getDiv().getValueAsString());
|
||||
} else {
|
||||
IParser parser = getNewParser(theServer.getFhirContext(), responseEncoding, thePrettyPrint, theNarrativeMode);
|
||||
parser.setServerBaseUrl(theServerBase);
|
||||
|
@ -267,18 +277,19 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void addProfileToBundleEntry(FhirContext theContext, IResource theResource, String theServerBase) {
|
||||
|
||||
TagList tl = ResourceMetadataKeyEnum.TAG_LIST.get(theResource);
|
||||
if (tl == null) {
|
||||
tl = new TagList();
|
||||
ResourceMetadataKeyEnum.TAG_LIST.put(theResource, tl);
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition nextDef = theContext.getResourceDefinition(theResource);
|
||||
String profile = nextDef.getResourceProfile(theServerBase);
|
||||
if (isNotBlank(profile)) {
|
||||
tl.add(new Tag(Tag.HL7_ORG_PROFILE_TAG, profile, null));
|
||||
public static void addProfileToBundleEntry(FhirContext theContext, IBaseResource theResource, String theServerBase) {
|
||||
if (theResource instanceof IResource) {
|
||||
TagList tl = ResourceMetadataKeyEnum.TAG_LIST.get((IResource) theResource);
|
||||
if (tl == null) {
|
||||
tl = new TagList();
|
||||
ResourceMetadataKeyEnum.TAG_LIST.put((IResource) theResource, tl);
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition nextDef = theContext.getResourceDefinition(theResource);
|
||||
String profile = nextDef.getResourceProfile(theServerBase);
|
||||
if (isNotBlank(profile)) {
|
||||
tl.add(new Tag(Tag.HL7_ORG_PROFILE_TAG, profile, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,14 +413,14 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
|
||||
int stausCode = 200;
|
||||
RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
|
||||
theServerBase);
|
||||
}
|
||||
|
||||
public static void validateResourceListNotNull(List<IResource> theResourceList) {
|
||||
public static void validateResourceListNotNull(List<? extends IBaseResource> theResourceList) {
|
||||
if (theResourceList == null) {
|
||||
throw new InternalErrorException("IBundleProvider returned a null list of resources - This is not allowed");
|
||||
}
|
||||
|
|
|
@ -23,18 +23,19 @@ package ca.uhn.fhir.rest.server;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
|
||||
public class SimpleBundleProvider implements IBundleProvider {
|
||||
|
||||
private List<IResource> myList;
|
||||
private List<IBaseResource> myList;
|
||||
|
||||
public SimpleBundleProvider(List<IResource> theList) {
|
||||
public SimpleBundleProvider(List<IBaseResource> theList) {
|
||||
myList = theList;
|
||||
}
|
||||
|
||||
public SimpleBundleProvider(IResource theResource) {
|
||||
public SimpleBundleProvider(IBaseResource theResource) {
|
||||
myList = Collections.singletonList(theResource);
|
||||
}
|
||||
|
||||
|
@ -46,7 +47,7 @@ public class SimpleBundleProvider implements IBundleProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> getResources(int theFromIndex, int theToIndex) {
|
||||
public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
|
||||
return myList.subList(theFromIndex, Math.min(theToIndex, myList.size()));
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.List;
|
|||
import org.hl7.fhir.instance.model.IBase;
|
||||
|
||||
import ca.uhn.fhir.model.api.ICompositeElement;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
|
||||
public class ElementUtil {
|
||||
|
||||
|
@ -62,6 +63,19 @@ public class ElementUtil {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(IElement... theElements) {
|
||||
if (theElements == null) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < theElements.length; i++) {
|
||||
IBase next = theElements[i];
|
||||
if (next != null && !next.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(List<? extends IBase> theElements) {
|
||||
if (theElements == null) {
|
||||
return true;
|
||||
|
|
|
@ -2,6 +2,8 @@ package org.hl7.fhir.instance.model;
|
|||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package org.hl7.fhir.instance.model.api;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
public interface IBaseConformance extends IBaseResource {
|
||||
|
||||
}
|
|
@ -22,7 +22,7 @@ package org.hl7.fhir.instance.model.api;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public interface IDomainResource {
|
||||
public interface IDomainResource extends IAnyResource {
|
||||
|
||||
List<? extends IAnyResource> getContained();
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.hl7.fhir.instance.model.api;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -55,4 +57,16 @@ public interface IIdType {
|
|||
|
||||
String getVersionIdPart();
|
||||
|
||||
IIdType toUnqualified();
|
||||
|
||||
boolean hasResourceType();
|
||||
|
||||
IIdType withResourceType(String theResName);
|
||||
|
||||
String getResourceType();
|
||||
|
||||
IIdType withServerBase(String theServerBase, String theResourceName);
|
||||
|
||||
boolean isAbsolute();
|
||||
|
||||
}
|
||||
|
|
|
@ -30,4 +30,8 @@ public interface IMetaType extends ICompositeType {
|
|||
|
||||
IMetaType setLastUpdated(Date theHeaderDateValue);
|
||||
|
||||
Date getLastUpdated();
|
||||
|
||||
String getVersionId();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -14,7 +15,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||
|
@ -191,7 +191,7 @@ public class ContainedResourceEncodingTest {
|
|||
observation.setPerformer(performers);
|
||||
|
||||
|
||||
List<IResource> list = new ArrayList<IResource>();
|
||||
List<IBaseResource> list = new ArrayList<IBaseResource>();
|
||||
list.add(dr);
|
||||
|
||||
IVersionSpecificBundleFactory factory = ctx.newBundleFactory();
|
||||
|
@ -233,7 +233,7 @@ public class ContainedResourceEncodingTest {
|
|||
observation.setPerformer(performers);
|
||||
|
||||
|
||||
List<IResource> list = new ArrayList<IResource>();
|
||||
List<IBaseResource> list = new ArrayList<IBaseResource>();
|
||||
list.add(dr);
|
||||
|
||||
IVersionSpecificBundleFactory factory = ctx.newBundleFactory();
|
||||
|
|
|
@ -687,7 +687,7 @@ public class GenericClientTest {
|
|||
Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.encodedJson()
|
||||
.revinclude(Provenance.INCLUDE_TARGET)
|
||||
.revInclude(Provenance.INCLUDE_TARGET)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
|
|
|
@ -1,26 +1,36 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.resource.Practitioner;
|
||||
import ca.uhn.fhir.model.dstu.resource.Specimen;
|
||||
|
||||
/**
|
||||
* Created by Bill de Beaubien on 3/3/2015.
|
||||
*/
|
||||
public class Dstu1BundleFactoryTest {
|
||||
private static FhirContext ourCtx;
|
||||
private List<IResource> myResourceList;
|
||||
private List<IBaseResource> myResourceList;
|
||||
private Dstu1BundleFactory myBundleFactory;
|
||||
|
||||
@BeforeClass
|
||||
|
@ -71,7 +81,7 @@ public class Dstu1BundleFactoryTest {
|
|||
specimen1.setSubject(new ResourceReferenceDt(patient));
|
||||
specimen1.getCollection().setCollector(new ResourceReferenceDt(practitioner));
|
||||
|
||||
myResourceList = Arrays.asList(new IResource[]{diagnosticReport});
|
||||
myResourceList = Arrays.asList(new IBaseResource[]{diagnosticReport});
|
||||
|
||||
myBundleFactory = new Dstu1BundleFactory(ourCtx);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -19,6 +24,7 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -284,7 +290,7 @@ public class PagingTest {
|
|||
builder.setConnectionManager(connectionManager);
|
||||
ourClient = builder.build();
|
||||
|
||||
List<IResource> retVal = new ArrayList<IResource>();
|
||||
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Patient patient = new Patient();
|
||||
patient.setId("" + i);
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
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.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -33,6 +38,7 @@ import org.eclipse.jetty.servlet.ServletHandler;
|
|||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hamcrest.core.StringEndsWith;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
@ -95,7 +101,7 @@ public class RestfulServerMethodTest {
|
|||
@Test
|
||||
public void testCreateBundleDoesntCreateDoubleEntries() {
|
||||
|
||||
List<IResource> resources = new ArrayList<IResource>();
|
||||
List<IBaseResource> resources = new ArrayList<IBaseResource>();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setId("Patient/1");
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<dependency>
|
||||
<groupId>xmlunit</groupId>
|
||||
<artifactId>xmlunit</artifactId>
|
||||
<version>1.5</version>
|
||||
<version>1.6</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -31,9 +31,11 @@ import java.util.UUID;
|
|||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.rest.server.*;
|
||||
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
|
@ -63,7 +65,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addResourcesToBundle(List<IResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes) {
|
||||
public void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes) {
|
||||
if (myBundle == null) {
|
||||
myBundle = new Bundle();
|
||||
}
|
||||
|
@ -71,13 +73,14 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
List<IResource> includedResources = new ArrayList<IResource>();
|
||||
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
|
||||
|
||||
for (IResource next : theResult) {
|
||||
for (IBaseResource next : theResult) {
|
||||
if (next.getId().isEmpty() == false) {
|
||||
addedResourceIds.add(next.getId());
|
||||
addedResourceIds.add((IdDt) next.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (IResource next : theResult) {
|
||||
for (IBaseResource nextBaseRes : theResult) {
|
||||
IResource next = (IResource) nextBaseRes;
|
||||
|
||||
Set<String> containedIds = new HashSet<String>();
|
||||
for (IResource nextContained : next.getContained().getContainedResources()) {
|
||||
|
@ -197,7 +200,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
public void initializeBundleFromBundleProvider(RestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint, int theOffset, Integer theLimit, String theSearchId, BundleTypeEnum theBundleType, Set<Include> theIncludes) {
|
||||
int numToReturn;
|
||||
String searchId = null;
|
||||
List<IResource> resourceList;
|
||||
List<IBaseResource> resourceList;
|
||||
if (theServer.getPagingProvider() == null) {
|
||||
numToReturn = theResult.size();
|
||||
resourceList = theResult.getResources(0, numToReturn);
|
||||
|
@ -225,7 +228,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
}
|
||||
|
||||
for (IResource next : resourceList) {
|
||||
for (IBaseResource next : resourceList) {
|
||||
if (next.getId() == null || next.getId().isEmpty()) {
|
||||
if (!(next instanceof BaseOperationOutcome)) {
|
||||
throw new InternalErrorException("Server method returned resource of type[" + next.getClass().getSimpleName() + "] with no ID specified (IResource#setId(IdDt) must be called)");
|
||||
|
@ -234,7 +237,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
|
||||
if (theServer.getAddProfileTag() != AddProfileTagEnum.NEVER) {
|
||||
for (IResource nextRes : resourceList) {
|
||||
for (IBaseResource nextRes : resourceList) {
|
||||
RuntimeResourceDefinition def = theServer.getFhirContext().getResourceDefinition(nextRes);
|
||||
if (theServer.getAddProfileTag() == AddProfileTagEnum.ALWAYS || !def.isStandardProfile()) {
|
||||
RestfulServerUtils.addProfileToBundleEntry(theServer.getFhirContext(), nextRes, theServerBase);
|
||||
|
@ -242,7 +245,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
}
|
||||
|
||||
addResourcesToBundle(resourceList, theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
||||
addResourcesToBundle(new ArrayList<IBaseResource>(resourceList), theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
||||
addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
|
||||
|
||||
if (theServer.getPagingProvider() != null) {
|
||||
|
@ -273,7 +276,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initializeBundleFromResourceList(String theAuthor, List<IResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
||||
public void initializeBundleFromResourceList(String theAuthor, List<IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
||||
myBundle = new Bundle();
|
||||
|
||||
myBundle.setId(UUID.randomUUID().toString());
|
||||
|
@ -285,7 +288,8 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
|
||||
|
||||
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
|
||||
for (IResource next : theResources) {
|
||||
for (IBaseResource nextBaseRes : theResources) {
|
||||
IResource next = (IResource)nextBaseRes;
|
||||
Entry nextEntry = myBundle.addEntry();
|
||||
|
||||
nextEntry.setResource(next);
|
||||
|
@ -308,18 +312,18 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
myBundle.getTotalElement().setValue(theTotalResults);
|
||||
}
|
||||
|
||||
private void addResourcesForSearch(List<IResource> theResult) {
|
||||
List<IResource> includedResources = new ArrayList<IResource>();
|
||||
Set<IdDt> addedResourceIds = new HashSet<IdDt>();
|
||||
private void addResourcesForSearch(List<IBaseResource> theResult) {
|
||||
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
|
||||
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
|
||||
|
||||
for (IResource next : theResult) {
|
||||
for (IBaseResource next : theResult) {
|
||||
if (next.getId().isEmpty() == false) {
|
||||
addedResourceIds.add(next.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (IResource next : theResult) {
|
||||
|
||||
for (IBaseResource nextBaseRes : theResult) {
|
||||
IResource next = (IResource)nextBaseRes;
|
||||
Set<String> containedIds = new HashSet<String>();
|
||||
for (IResource nextContained : next.getContained().getContainedResources()) {
|
||||
if (nextContained.getId().isEmpty() == false) {
|
||||
|
@ -383,19 +387,19 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
|||
/*
|
||||
* Actually add the resources to the bundle
|
||||
*/
|
||||
for (IResource next : includedResources) {
|
||||
myBundle.addEntry().setResource(next).getSearch().setMode(SearchEntryModeEnum.INCLUDE);
|
||||
for (IBaseResource next : includedResources) {
|
||||
myBundle.addEntry().setResource((IResource) next).getSearch().setMode(SearchEntryModeEnum.INCLUDE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeWithBundleResource(IResource theBundle) {
|
||||
public void initializeWithBundleResource(IBaseResource theBundle) {
|
||||
myBundle = (Bundle) theBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> toListOfResources() {
|
||||
ArrayList<IResource> retVal = new ArrayList<IResource>();
|
||||
public List<IBaseResource> toListOfResources() {
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
for (Entry next : myBundle.getEntry()) {
|
||||
if (next.getResource()!=null) {
|
||||
retVal.add(next.getResource());
|
||||
|
|
|
@ -58,6 +58,28 @@ public class JsonParserDstu2Test {
|
|||
assertEquals("{\"resourceType\":\"Binary\",\"id\":\"11\",\"meta\":{\"versionId\":\"22\"},\"contentType\":\"foo\",\"content\":\"AQIDBA==\"}", val);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodingNullExtension() {
|
||||
Patient p = new Patient();
|
||||
ExtensionDt extension = new ExtensionDt(false, "http://foo#bar");
|
||||
p.addUndeclaredExtension(extension);
|
||||
String str = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
assertEquals("{\"resourceType\":\"Patient\"}", str);
|
||||
|
||||
extension.setValue(new StringDt());
|
||||
|
||||
str = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
assertEquals("{\"resourceType\":\"Patient\"}", str);
|
||||
|
||||
extension.setValue(new StringDt(""));
|
||||
|
||||
str = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
assertEquals("{\"resourceType\":\"Patient\"}", str);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #144 and #146
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import javax.xml.stream.FactoryConfigurationError;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLEventWriter;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.custommonkey.xmlunit.DetailedDiff;
|
||||
import org.custommonkey.xmlunit.Diff;
|
||||
import org.custommonkey.xmlunit.Difference;
|
||||
import org.custommonkey.xmlunit.DifferenceListener;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.XmlUtil;
|
||||
|
||||
public class RoundTripDstu2Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RoundTripDstu2Test.class);
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||
|
||||
@Test
|
||||
public void testRoundTrip() throws Exception {
|
||||
ZipInputStream is = new ZipInputStream(new FileInputStream("src/test/resources/examples.zip"));
|
||||
try {
|
||||
while (true) {
|
||||
ZipEntry nextEntry = is.getNextEntry();
|
||||
if (nextEntry == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
ByteArrayOutputStream oos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[2048];
|
||||
int len = 0;
|
||||
while ((len = is.read(buffer)) > 0) {
|
||||
oos.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
String exampleText = oos.toString("UTF-8");
|
||||
ourLog.info("Next file: {} - Size: {} bytes", nextEntry.getName(), exampleText.length());
|
||||
if (!nextEntry.getName().contains("diagnosticreport-examples-lab")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
IBaseResource parsed = ourCtx.newXmlParser().parseResource(exampleText);
|
||||
String encodedXml = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(parsed);
|
||||
|
||||
exampleText = cleanXml(exampleText);
|
||||
encodedXml = cleanXml(encodedXml);
|
||||
|
||||
DetailedDiff d = new DetailedDiff(new Diff(new StringReader(exampleText), new StringReader(encodedXml)));
|
||||
// d.overrideDifferenceListener(new DifferenceListener() {
|
||||
//
|
||||
// @Override
|
||||
// public void skippedComparison(Node theControl, Node theTest) {
|
||||
// ourLog.info("" + theControl);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int differenceFound(Difference theDifference) {
|
||||
// ourLog.info("" + theDifference);
|
||||
// return 0;
|
||||
// }
|
||||
// });
|
||||
|
||||
boolean similar = d.similar();
|
||||
if (!similar) {
|
||||
exampleText = exampleText.replace(" xmlns=\"http://hl7.org/fhir\"", "");
|
||||
encodedXml = encodedXml.replace(" xmlns=\"http://hl7.org/fhir\"", "");
|
||||
if (exampleText.length() != encodedXml.length()) {
|
||||
// ourLog.info("Expected: " + exampleText);
|
||||
// ourLog.info("Actual : " + encodedXml);
|
||||
assertTrue(d.toString(), similar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String cleanXml(String exampleText) throws Error, Exception {
|
||||
XMLEventReader read = XmlUtil.createXmlReader(new StringReader(exampleText));
|
||||
StringWriter sw = new StringWriter();
|
||||
XMLEventWriter write = XmlUtil.createXmlWriter(sw);
|
||||
while (read.hasNext()) {
|
||||
XMLEvent nextEvent = read.nextEvent();
|
||||
if (nextEvent.getEventType() == XMLStreamConstants.COMMENT) {
|
||||
continue;
|
||||
}
|
||||
write.add(nextEvent);
|
||||
}
|
||||
write.add(read);
|
||||
sw.close();
|
||||
return sw.toString().replaceAll("<!--.*-->", "").replace("\n", " ").replace("\r", " ").replaceAll(">\\s+<", "><").replaceAll("<\\?.*\\?>", "").replaceAll("\\s+", " ");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,16 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.emptyOrNullString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
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.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
|
@ -29,12 +38,15 @@ import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
|||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ContainedDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.DurationDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ElementDefinitionDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ElementDefinitionDt.Binding;
|
||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.AllergyIntolerance;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Composition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DataElement;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Medication;
|
||||
import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription;
|
||||
|
@ -60,6 +72,282 @@ public class XmlParserDstu2Test {
|
|||
XMLUnit.setIgnoreWhitespace(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainedResourceInExtensionUndeclared() {
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("PATIENT");
|
||||
|
||||
Organization o = new Organization();
|
||||
o.setName("ORG");
|
||||
p.addUndeclaredExtension(new ExtensionDt(false, "urn:foo", new ResourceReferenceDt(o)));
|
||||
|
||||
String str = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
ourLog.info(str);
|
||||
|
||||
p = ourCtx.newXmlParser().parseResource(Patient.class, str);
|
||||
assertEquals("PATIENT", p.getName().get(0).getFamily().get(0).getValue());
|
||||
|
||||
List<ExtensionDt> exts = p.getUndeclaredExtensionsByUrl("urn:foo");
|
||||
assertEquals(1, exts.size());
|
||||
ResourceReferenceDt rr = (ResourceReferenceDt)exts.get(0).getValue();
|
||||
o = (Organization) rr.getResource();
|
||||
assertEquals("ORG", o.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeAndParseExtensionOnResourceReference() {
|
||||
DataElement de = new DataElement();
|
||||
Binding b = de.addElement().getBinding();
|
||||
b.setName("BINDING");
|
||||
|
||||
Organization o = new Organization();
|
||||
o.setName("ORG");
|
||||
b.addUndeclaredExtension(new ExtensionDt(false, "urn:foo", new ResourceReferenceDt(o)));
|
||||
|
||||
String str = ourCtx.newXmlParser().encodeResourceToString(de);
|
||||
ourLog.info(str);
|
||||
|
||||
de = ourCtx.newXmlParser().parseResource(DataElement.class, str);
|
||||
b = de.getElement().get(0).getBinding();
|
||||
assertEquals("BINDING", b.getName());
|
||||
|
||||
List<ExtensionDt> exts = b.getUndeclaredExtensionsByUrl("urn:foo");
|
||||
assertEquals(1, exts.size());
|
||||
ResourceReferenceDt rr = (ResourceReferenceDt)exts.get(0).getValue();
|
||||
o = (Organization) rr.getResource();
|
||||
assertEquals("ORG", o.getName());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeExtensionOnResourceReference() {
|
||||
//@formatter:off
|
||||
String input = "<DataElement>" +
|
||||
"<id value=\"gender\"/>"+
|
||||
"<contained>"+
|
||||
"<ValueSet>"+
|
||||
"<id value=\"2179414\"/>"+
|
||||
"<url value=\"2179414\"/>"+
|
||||
"<version value=\"1.0\"/>"+
|
||||
"<name value=\"Gender Code\"/>"+
|
||||
"<description value=\"All codes representing the gender of a person.\"/>"+
|
||||
"<status value=\"active\"/>"+
|
||||
"<compose>"+
|
||||
"<include>"+
|
||||
"<system value=\"http://ncit.nci.nih.gov\"/>"+
|
||||
"<concept>"+
|
||||
"<code value=\"C17998\"/>"+
|
||||
"<display value=\"Unknown\"/>"+
|
||||
"</concept>"+
|
||||
"<concept>"+
|
||||
"<code value=\"C20197\"/>"+
|
||||
"<display value=\"Male\"/>"+
|
||||
"</concept>"+
|
||||
"<concept>"+
|
||||
"<code value=\"C16576\"/>"+
|
||||
"<display value=\"Female\"/>"+
|
||||
"</concept>"+
|
||||
"<concept>"+
|
||||
"<code value=\"C38046\"/>"+
|
||||
"<display value=\"Not specified\"/>"+
|
||||
"</concept>"+
|
||||
"</include>"+
|
||||
"</compose>"+
|
||||
"</ValueSet>"+
|
||||
"</contained>"+
|
||||
"<contained>"+
|
||||
"<ValueSet>"+
|
||||
"<id value=\"2179414-permitted\"/>"+
|
||||
"<status value=\"active\"/>"+
|
||||
"<define>"+
|
||||
"<system value=\"http://example.org/fhir/2179414\"/>"+
|
||||
"<caseSensitive value=\"true\"/>"+
|
||||
"<concept>"+
|
||||
"<code value=\"0\"/>"+
|
||||
"</concept>"+
|
||||
"<concept>"+
|
||||
"<code value=\"1\"/>"+
|
||||
"</concept>"+
|
||||
"<concept>"+
|
||||
"<code value=\"2\"/>"+
|
||||
"</concept>"+
|
||||
"<concept>"+
|
||||
"<code value=\"3\"/>"+
|
||||
"</concept>"+
|
||||
"</define>"+
|
||||
"</ValueSet>"+
|
||||
"</contained>"+
|
||||
"<contained>"+
|
||||
"<ConceptMap>"+
|
||||
"<id value=\"2179414-cm\"/>"+
|
||||
"<status value=\"active\"/>"+
|
||||
"<sourceReference>"+
|
||||
"<reference value=\"#2179414\"/>"+
|
||||
"</sourceReference>"+
|
||||
"<targetReference>"+
|
||||
"<reference value=\"#2179414-permitted\"/>"+
|
||||
"</targetReference>"+
|
||||
"<element>"+
|
||||
"<code value=\"C17998\"/>"+
|
||||
"<map>"+
|
||||
"<code value=\"0\"/>"+
|
||||
"<equivalence value=\"equal\"/>"+
|
||||
"</map>"+
|
||||
"</element>"+
|
||||
"<element>"+
|
||||
"<code value=\"C20197\"/>"+
|
||||
"<map>"+
|
||||
"<code value=\"1\"/>"+
|
||||
"<equivalence value=\"equal\"/>"+
|
||||
"</map>"+
|
||||
"</element>"+
|
||||
"<element>"+
|
||||
"<code value=\"C16576\"/>"+
|
||||
"<map>"+
|
||||
"<code value=\"2\"/>"+
|
||||
"<equivalence value=\"equal\"/>"+
|
||||
"</map>"+
|
||||
"</element>"+
|
||||
"<element>"+
|
||||
"<code value=\"C38046\"/>"+
|
||||
"<map>"+
|
||||
"<code value=\"3\"/>"+
|
||||
"<equivalence value=\"equal\"/>"+
|
||||
"</map>"+
|
||||
"</element>"+
|
||||
"</ConceptMap>"+
|
||||
"</contained>"+
|
||||
"<identifier>"+
|
||||
"<value value=\"2179650\"/>"+
|
||||
"</identifier>"+
|
||||
"<version value=\"1.0\"/>"+
|
||||
"<name value=\"Gender Code\"/>"+
|
||||
"<useContext>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/FBPP\"/>"+
|
||||
"<display value=\"FBPP Pooled Database\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/PhenX\"/>"+
|
||||
"<display value=\"Demographics\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/EligibilityCriteria\"/>"+
|
||||
"<display value=\"Pt. Administrative\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/UAMSClinicalResearch\"/>"+
|
||||
"<display value=\"UAMS New CDEs\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/PhenX\"/>"+
|
||||
"<display value=\"Substance Abuse and \"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Category\"/>"+
|
||||
"<display value=\"CSAERS Adverse Event\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/PhenX\"/>"+
|
||||
"<display value=\"Core: Tier 1\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Category\"/>"+
|
||||
"<display value=\"Case Report Forms\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Category\"/>"+
|
||||
"<display value=\"CSAERS Review Set\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Demonstration%20Applications\"/>"+
|
||||
"<display value=\"CIAF\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/NIDA%20CTN%20Usage\"/>"+
|
||||
"<display value=\"Clinical Research\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/NIDA%20CTN%20Usage\"/>"+
|
||||
"<display value=\"Electronic Health Re\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Condition\"/>"+
|
||||
"<display value=\"Barretts Esophagus\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Condition\"/>"+
|
||||
"<display value=\"Bladder Cancer\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Condition\"/>"+
|
||||
"<display value=\"Oral Leukoplakia\"/>"+
|
||||
"</coding>"+
|
||||
"<coding>"+
|
||||
"<system value=\"http://example.org/Condition\"/>"+
|
||||
"<display value=\"Sulindac for Breast\"/>"+
|
||||
"</coding>"+
|
||||
"</useContext>"+
|
||||
"<status value=\"active\"/>"+
|
||||
"<publisher value=\"DCP\"/>"+
|
||||
"<element>"+
|
||||
"<extension url=\"http://hl7.org/fhir/StructureDefinition/minLength\">"+
|
||||
"<valueInteger value=\"1\"/>"+
|
||||
"</extension>"+
|
||||
"<extension url=\"http://hl7.org/fhir/StructureDefinition/elementdefinition-question\">"+
|
||||
"<valueString value=\"Gender\"/>"+
|
||||
"</extension>"+
|
||||
"<path value=\"Gender\"/>"+
|
||||
"<definition value=\"The code representing the gender of a person.\"/>"+
|
||||
"<type>"+
|
||||
"<code value=\"CodeableConcept\"/>"+
|
||||
"</type>"+
|
||||
"<maxLength value=\"13\"/>"+
|
||||
"<binding>"+
|
||||
"<name value=\"Gender\"/>"+
|
||||
"<strength value=\"required\"/>"+
|
||||
"<valueSetReference>"+
|
||||
"<extension url=\"http://hl7.org/fhir/StructureDefinition/11179-permitted-value-valueset\">"+
|
||||
"<valueReference>"+
|
||||
"<reference value=\"#2179414-permitted\"/>"+
|
||||
"</valueReference>"+
|
||||
"</extension>"+
|
||||
"<extension url=\"http://hl7.org/fhir/StructureDefinition/11179-permitted-value-conceptmap\">"+
|
||||
"<valueReference>"+
|
||||
"<reference value=\"#2179414-cm\"/>"+
|
||||
"</valueReference>"+
|
||||
"</extension>"+
|
||||
"<reference value=\"#2179414\"/>"+
|
||||
"</valueSetReference>"+
|
||||
"</binding>"+
|
||||
"</element>"+
|
||||
"</DataElement>";
|
||||
//@formatter:on
|
||||
DataElement de = ourCtx.newXmlParser().parseResource(DataElement.class, input);
|
||||
String output = ourCtx.newXmlParser().encodeResourceToString(de).replace(" xmlns=\"http://hl7.org/fhir\"", "");
|
||||
|
||||
ElementDefinitionDt elem = de.getElement().get(0);
|
||||
Binding b = elem.getBinding();
|
||||
assertEquals("Gender", b.getName());
|
||||
|
||||
ResourceReferenceDt ref = (ResourceReferenceDt) b.getValueSet();
|
||||
assertEquals("#2179414", ref.getReference().getValue());
|
||||
|
||||
assertEquals(2, ref.getUndeclaredExtensions().size());
|
||||
ExtensionDt ext = ref.getUndeclaredExtensions().get(0);
|
||||
assertEquals("http://hl7.org/fhir/StructureDefinition/11179-permitted-value-valueset", ext.getUrl());
|
||||
assertEquals(ResourceReferenceDt.class, ext.getValue().getClass());
|
||||
assertEquals("#2179414-permitted", ((ResourceReferenceDt)ext.getValue()).getReference().getValue());
|
||||
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(de));
|
||||
|
||||
assertThat(output, containsString("http://hl7.org/fhir/StructureDefinition/11179-permitted-value-valueset"));
|
||||
|
||||
ourLog.info("Expected: {}", input);
|
||||
ourLog.info("Actual : {}", output);
|
||||
assertEquals(input, output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeBinaryWithNoContentType() {
|
||||
Binary b = new Binary();
|
||||
|
@ -71,6 +359,60 @@ public class XmlParserDstu2Test {
|
|||
assertEquals("<Binary xmlns=\"http://hl7.org/fhir\"><content value=\"AQIDBA==\"/></Binary>", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoreExtensions() throws Exception {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
|
||||
|
||||
ExtensionDt ext = new ExtensionDt();
|
||||
ext.setUrl("http://example.com/extensions#someext");
|
||||
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
|
||||
|
||||
// Add the extension to the resource
|
||||
patient.addUndeclaredExtension(ext);
|
||||
// END SNIPPET: resourceExtension
|
||||
|
||||
// START SNIPPET: resourceStringExtension
|
||||
HumanNameDt name = patient.addName();
|
||||
name.addFamily("Shmoe");
|
||||
StringDt given = name.addGiven();
|
||||
given.setValue("Joe");
|
||||
ExtensionDt ext2 = new ExtensionDt().setUrl("http://examples.com#givenext").setValue(new StringDt("given"));
|
||||
given.addUndeclaredExtension(ext2);
|
||||
|
||||
StringDt given2 = name.addGiven();
|
||||
given2.setValue("Shmoe");
|
||||
ExtensionDt given2ext = new ExtensionDt().setUrl("http://examples.com#givenext_parent");
|
||||
given2.addUndeclaredExtension(given2ext);
|
||||
ExtensionDt givenExtChild = new ExtensionDt();
|
||||
givenExtChild.setUrl("http://examples.com#givenext_child").setValue(new StringDt("CHILD"));
|
||||
given2ext.addUndeclaredExtension(givenExtChild);
|
||||
// END SNIPPET: resourceStringExtension
|
||||
|
||||
// START SNIPPET: subExtension
|
||||
ExtensionDt parent = new ExtensionDt().setUrl("http://example.com#parent");
|
||||
patient.addUndeclaredExtension(parent);
|
||||
|
||||
ExtensionDt child1 = new ExtensionDt().setUrl("http://example.com#child").setValue(new StringDt("value1"));
|
||||
parent.addUndeclaredExtension(child1);
|
||||
|
||||
ExtensionDt child2 = new ExtensionDt().setUrl("http://example.com#child").setValue(new StringDt("value1"));
|
||||
parent.addUndeclaredExtension(child2);
|
||||
// END SNIPPET: subExtension
|
||||
|
||||
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
ourLog.info(output);
|
||||
|
||||
String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
|
||||
assertThat(enc, containsString("<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://example.com/extensions#someext\"><valueDateTime value=\"2011-01-02T11:13:15\"/></extension>"));
|
||||
assertThat(
|
||||
enc,
|
||||
containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension></extension>"));
|
||||
assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
|
||||
assertThat(enc, containsString("<given value=\"Shmoe\"><extension url=\"http://examples.com#givenext_parent\"><extension url=\"http://examples.com#givenext_child\"><valueString value=\"CHILD\"/></extension></extension></given>"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeNonContained() {
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.apache.http.client.methods.HttpUriRequest;
|
|||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
@ -64,7 +65,7 @@ public class BundleTypeTest {
|
|||
p1.addIdentifier().setSystem("urn:system").setValue("value");
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://foo");
|
||||
client.transaction().withResources(Arrays.asList((IResource) p1)).execute();
|
||||
client.transaction().withResources(Arrays.asList((IBaseResource) p1)).execute();
|
||||
|
||||
HttpUriRequest value = capt.getValue();
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public class ClientServerValidationTestDstu2 {
|
|||
@Test
|
||||
public void testServerReturnsAppropriateVersionForDstu2_040() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.4.0");
|
||||
conf.setFhirVersion("0.5.0");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
|||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
@ -34,6 +35,7 @@ import org.mockito.stubbing.Answer;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
@ -42,7 +44,7 @@ import ca.uhn.fhir.parser.IParser;
|
|||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
|
||||
public class GenericClientTestDstu2 {
|
||||
public class GenericClientDstu2Test {
|
||||
private static FhirContext ourCtx;
|
||||
private HttpClient myHttpClient;
|
||||
private HttpResponse myHttpResponse;
|
||||
|
@ -78,7 +80,7 @@ public class GenericClientTestDstu2 {
|
|||
Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.encodedJson()
|
||||
.revinclude(ca.uhn.fhir.model.dstu2.resource.Provenance.INCLUDE_TARGET)
|
||||
.revInclude(new Include("Provenance:target"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
|
@ -577,7 +579,7 @@ public class GenericClientTestDstu2 {
|
|||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
List<IResource> input = new ArrayList<IResource>();
|
||||
List<IBaseResource> input = new ArrayList<IBaseResource>();
|
||||
|
||||
Patient p1 = new Patient(); // No ID
|
||||
p1.addName().addFamily("PATIENT1");
|
||||
|
@ -589,7 +591,7 @@ public class GenericClientTestDstu2 {
|
|||
input.add(p2);
|
||||
|
||||
//@formatter:off
|
||||
List<IResource> response = client.transaction()
|
||||
List<IBaseResource> response = client.transaction()
|
||||
.withResources(input)
|
||||
.encodedJson()
|
||||
.execute();
|
|
@ -1,7 +1,10 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -20,6 +23,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -356,7 +360,7 @@ public class OperationServerTest {
|
|||
public IBundleProvider opInstanceReturnsBundleProvider() {
|
||||
ourLastMethod = "$OP_INSTANCE_BUNDLE_PROVIDER";
|
||||
|
||||
List<IResource> resources = new ArrayList<IResource>();
|
||||
List<IBaseResource> resources = new ArrayList<IBaseResource>();
|
||||
for (int i =0; i < 100;i++) {
|
||||
Patient p = new Patient();
|
||||
p.setId("Patient/" + i);
|
||||
|
|
|
@ -1,23 +1,33 @@
|
|||
package ca.uhn.fhir.rest.server.provider.dstu2;
|
||||
|
||||
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.*;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Specimen;
|
||||
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||
|
||||
public class Dstu2BundleFactoryTest {
|
||||
private static FhirContext ourCtx;
|
||||
private List<IResource> myResourceList;
|
||||
private List<IBaseResource> myResourceList;
|
||||
private Dstu2BundleFactory myBundleFactory;
|
||||
|
||||
@BeforeClass
|
||||
|
@ -68,7 +78,7 @@ public class Dstu2BundleFactoryTest {
|
|||
specimen1.setSubject(new ResourceReferenceDt(patient));
|
||||
specimen1.getCollection().setCollector(new ResourceReferenceDt(practitioner));
|
||||
|
||||
myResourceList = Arrays.asList(new IResource[]{diagnosticReport});
|
||||
myResourceList = Arrays.asList(new IBaseResource[]{diagnosticReport});
|
||||
|
||||
myBundleFactory = new Dstu2BundleFactory(ourCtx);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,406 @@
|
|||
package ca.uhn.fhir.rest.server.provider.dstu2hl7org;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Structures - DSTU2 (FHIR v0.4.0)
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 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 static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.Bundle;
|
||||
import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.instance.model.Bundle.BundleLinkComponent;
|
||||
import org.hl7.fhir.instance.model.Bundle.HttpVerb;
|
||||
import org.hl7.fhir.instance.model.Bundle.SearchEntryMode;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.IdType;
|
||||
import org.hl7.fhir.instance.model.InstantType;
|
||||
import org.hl7.fhir.instance.model.OperationOutcome;
|
||||
import org.hl7.fhir.instance.model.Resource;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IDomainResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IReference;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
||||
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
||||
|
||||
public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
|
||||
|
||||
private Bundle myBundle;
|
||||
private FhirContext myContext;
|
||||
|
||||
public Dstu2Hl7OrgBundleFactory(FhirContext theContext) {
|
||||
myContext = theContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes) {
|
||||
if (myBundle == null) {
|
||||
myBundle = new Bundle();
|
||||
}
|
||||
|
||||
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
|
||||
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
|
||||
|
||||
for (IBaseResource next : theResult) {
|
||||
if (next.getId().isEmpty() == false) {
|
||||
addedResourceIds.add(next.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (IBaseResource nextBaseRes : theResult) {
|
||||
if (!(nextBaseRes instanceof IDomainResource)) {
|
||||
continue;
|
||||
}
|
||||
IDomainResource next = (IDomainResource) nextBaseRes;
|
||||
|
||||
Set<String> containedIds = new HashSet<String>();
|
||||
for (IAnyResource nextContained : next.getContained()) {
|
||||
if (nextContained.getId().isEmpty() == false) {
|
||||
containedIds.add(nextContained.getId().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
List<ResourceReferenceInfo> references = myContext.newTerser().getAllResourceReferences(next);
|
||||
do {
|
||||
List<IBaseResource> addedResourcesThisPass = new ArrayList<IBaseResource>();
|
||||
|
||||
for (ResourceReferenceInfo nextRefInfo : references) {
|
||||
if (!theBundleInclusionRule.shouldIncludeReferencedResource(nextRefInfo, theIncludes))
|
||||
continue;
|
||||
|
||||
IBaseResource nextRes = (IBaseResource) nextRefInfo.getResourceReference().getResource();
|
||||
if (nextRes != null) {
|
||||
if (nextRes.getId().hasIdPart()) {
|
||||
if (containedIds.contains(nextRes.getId().getValue())) {
|
||||
// Don't add contained IDs as top level resources
|
||||
continue;
|
||||
}
|
||||
|
||||
IdType id = (IdType) nextRes.getId();
|
||||
if (id.hasResourceType() == false) {
|
||||
String resName = myContext.getResourceDefinition(nextRes).getName();
|
||||
id = id.withResourceType(resName);
|
||||
}
|
||||
|
||||
if (!addedResourceIds.contains(id)) {
|
||||
addedResourceIds.add(id);
|
||||
addedResourcesThisPass.add(nextRes);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
includedResources.addAll(addedResourcesThisPass);
|
||||
|
||||
// Linked resources may themselves have linked resources
|
||||
references = new ArrayList<ResourceReferenceInfo>();
|
||||
for (IBaseResource iResource : addedResourcesThisPass) {
|
||||
List<ResourceReferenceInfo> newReferences = myContext.newTerser().getAllResourceReferences(iResource);
|
||||
references.addAll(newReferences);
|
||||
}
|
||||
} while (references.isEmpty() == false);
|
||||
|
||||
BundleEntryComponent entry = myBundle.addEntry().setResource((Resource) next);
|
||||
|
||||
// BundleEntrySearchModeEnum searchMode = ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(next);
|
||||
// if (searchMode != null) {
|
||||
// entry.getSearch().getModeElement().setValue(searchMode.getCode());
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually add the resources to the bundle
|
||||
*/
|
||||
for (IBaseResource next : includedResources) {
|
||||
myBundle.addEntry().setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType) {
|
||||
|
||||
if (myBundle.getId().isEmpty()) {
|
||||
myBundle.setId(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
InstantDt published = new InstantDt();
|
||||
published.setToCurrentTimeInLocalTimeZone();
|
||||
|
||||
if (!hasLink(Constants.LINK_SELF, myBundle) && isNotBlank(theCompleteUrl)) {
|
||||
myBundle.addLink().setRelation("self").setUrl(theCompleteUrl);
|
||||
}
|
||||
|
||||
if (isBlank(myBundle.getBase()) && isNotBlank(theServerBase)) {
|
||||
myBundle.setBase(theServerBase);
|
||||
}
|
||||
|
||||
if (myBundle.getTypeElement().isEmpty() && theBundleType != null) {
|
||||
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
|
||||
}
|
||||
|
||||
if (myBundle.getTotalElement().isEmpty() && theTotalResults != null) {
|
||||
myBundle.getTotalElement().setValue(theTotalResults);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasLink(String theLinkType, Bundle theBundle) {
|
||||
for (BundleLinkComponent next : theBundle.getLink()) {
|
||||
if (theLinkType.equals(next.getRelation())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeBundleFromBundleProvider(RestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint, int theOffset, Integer theLimit, String theSearchId, BundleTypeEnum theBundleType, Set<Include> theIncludes) {
|
||||
int numToReturn;
|
||||
String searchId = null;
|
||||
List<IBaseResource> resourceList;
|
||||
if (theServer.getPagingProvider() == null) {
|
||||
numToReturn = theResult.size();
|
||||
resourceList = theResult.getResources(0, numToReturn);
|
||||
RestfulServerUtils.validateResourceListNotNull(resourceList);
|
||||
|
||||
} else {
|
||||
IPagingProvider pagingProvider = theServer.getPagingProvider();
|
||||
if (theLimit == null) {
|
||||
numToReturn = pagingProvider.getDefaultPageSize();
|
||||
} else {
|
||||
numToReturn = Math.min(pagingProvider.getMaximumPageSize(), theLimit);
|
||||
}
|
||||
|
||||
numToReturn = Math.min(numToReturn, theResult.size() - theOffset);
|
||||
resourceList = theResult.getResources(theOffset, numToReturn + theOffset);
|
||||
RestfulServerUtils.validateResourceListNotNull(resourceList);
|
||||
|
||||
if (theSearchId != null) {
|
||||
searchId = theSearchId;
|
||||
} else {
|
||||
if (theResult.size() > numToReturn) {
|
||||
searchId = pagingProvider.storeResultList(theResult);
|
||||
Validate.notNull(searchId, "Paging provider returned null searchId");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (IBaseResource next : resourceList) {
|
||||
if (next.getId() == null || next.getId().isEmpty()) {
|
||||
if (!(next instanceof OperationOutcome)) {
|
||||
throw new InternalErrorException("Server method returned resource of type[" + next.getClass().getSimpleName() + "] with no ID specified (IBaseResource#setId(IdDt) must be called)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theServer.getAddProfileTag() != AddProfileTagEnum.NEVER) {
|
||||
for (IBaseResource nextRes : resourceList) {
|
||||
RuntimeResourceDefinition def = theServer.getFhirContext().getResourceDefinition(nextRes);
|
||||
if (theServer.getAddProfileTag() == AddProfileTagEnum.ALWAYS || !def.isStandardProfile()) {
|
||||
RestfulServerUtils.addProfileToBundleEntry(theServer.getFhirContext(), nextRes, theServerBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addResourcesToBundle(resourceList, theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
||||
addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
|
||||
|
||||
if (theServer.getPagingProvider() != null) {
|
||||
int limit;
|
||||
limit = theLimit != null ? theLimit : theServer.getPagingProvider().getDefaultPageSize();
|
||||
limit = Math.min(limit, theServer.getPagingProvider().getMaximumPageSize());
|
||||
|
||||
if (searchId != null) {
|
||||
if (theOffset + numToReturn < theResult.size()) {
|
||||
myBundle.addLink().setRelation(Constants.LINK_NEXT).setUrl(RestfulServerUtils.createPagingLink(theIncludes, theServerBase, searchId, theOffset + numToReturn, numToReturn, theResponseEncoding, thePrettyPrint));
|
||||
}
|
||||
if (theOffset > 0) {
|
||||
int start = Math.max(0, theOffset - limit);
|
||||
myBundle.addLink().setRelation(Constants.LINK_PREVIOUS).setUrl(RestfulServerUtils.createPagingLink(theIncludes, theServerBase, searchId, start, limit, theResponseEncoding, thePrettyPrint));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ca.uhn.fhir.model.api.Bundle getDstu1Bundle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaseResource getResourceBundle() {
|
||||
return myBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeBundleFromResourceList(String theAuthor, List<IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
||||
myBundle = new Bundle();
|
||||
|
||||
myBundle.setId(UUID.randomUUID().toString());
|
||||
|
||||
myBundle.getMeta().setLastUpdatedElement(InstantType.withCurrentTime());
|
||||
|
||||
myBundle.addLink().setRelation(Constants.LINK_FHIR_BASE).setUrl(theServerBase);
|
||||
myBundle.addLink().setRelation(Constants.LINK_SELF).setUrl(theCompleteUrl);
|
||||
myBundle.getTypeElement().setValueAsString(theBundleType.getCode());
|
||||
|
||||
if (theBundleType.equals(BundleTypeEnum.TRANSACTION)) {
|
||||
for (IBaseResource nextBaseRes : theResources) {
|
||||
IBaseResource next = (IBaseResource)nextBaseRes;
|
||||
BundleEntryComponent nextEntry = myBundle.addEntry();
|
||||
|
||||
nextEntry.setResource((Resource) next);
|
||||
if (next.getId().isEmpty()) {
|
||||
nextEntry.getTransaction().setMethod(HttpVerb.POST);
|
||||
} else {
|
||||
nextEntry.getTransaction().setMethod(HttpVerb.PUT);
|
||||
if (next.getId().isAbsolute()) {
|
||||
nextEntry.getTransaction().setUrl(next.getId().getValue());
|
||||
} else {
|
||||
String resourceType = myContext.getResourceDefinition(next).getName();
|
||||
nextEntry.getTransaction().setUrl(new IdType(theServerBase, resourceType, next.getId().getIdPart(), next.getId().getVersionIdPart()).getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addResourcesForSearch(theResources);
|
||||
}
|
||||
|
||||
myBundle.getTotalElement().setValue(theTotalResults);
|
||||
}
|
||||
|
||||
private void addResourcesForSearch(List<IBaseResource> theResult) {
|
||||
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
|
||||
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
|
||||
|
||||
for (IBaseResource next : theResult) {
|
||||
if (next.getId().isEmpty() == false) {
|
||||
addedResourceIds.add(next.getId());
|
||||
}
|
||||
}
|
||||
|
||||
for (IBaseResource nextBaseRes : theResult) {
|
||||
IDomainResource next = (IDomainResource)nextBaseRes;
|
||||
Set<String> containedIds = new HashSet<String>();
|
||||
for (IBaseResource nextContained : next.getContained()) {
|
||||
if (nextContained.getId().isEmpty() == false) {
|
||||
containedIds.add(nextContained.getId().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
List<IReference> references = myContext.newTerser().getAllPopulatedChildElementsOfType(next, IReference.class);
|
||||
do {
|
||||
List<IBaseResource> addedResourcesThisPass = new ArrayList<IBaseResource>();
|
||||
|
||||
for (IReference nextRef : references) {
|
||||
IBaseResource nextRes = (IBaseResource) nextRef.getResource();
|
||||
if (nextRes != null) {
|
||||
if (nextRes.getId().hasIdPart()) {
|
||||
if (containedIds.contains(nextRes.getId().getValue())) {
|
||||
// Don't add contained IDs as top level resources
|
||||
continue;
|
||||
}
|
||||
|
||||
IIdType id = nextRes.getId();
|
||||
if (id.hasResourceType() == false) {
|
||||
String resName = myContext.getResourceDefinition(nextRes).getName();
|
||||
id = id.withResourceType(resName);
|
||||
}
|
||||
|
||||
if (!addedResourceIds.contains(id)) {
|
||||
addedResourceIds.add(id);
|
||||
addedResourcesThisPass.add(nextRes);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Linked resources may themselves have linked resources
|
||||
references = new ArrayList<IReference>();
|
||||
for (IBaseResource iResource : addedResourcesThisPass) {
|
||||
List<IReference> newReferences = myContext.newTerser().getAllPopulatedChildElementsOfType(iResource, IReference.class);
|
||||
references.addAll(newReferences);
|
||||
}
|
||||
|
||||
includedResources.addAll(addedResourcesThisPass);
|
||||
|
||||
} while (references.isEmpty() == false);
|
||||
|
||||
myBundle.addEntry().setResource((Resource) next);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually add the resources to the bundle
|
||||
*/
|
||||
for (IBaseResource next : includedResources) {
|
||||
myBundle.addEntry().setResource((Resource) next).getSearch().setMode(SearchEntryMode.INCLUDE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeWithBundleResource(IBaseResource theBundle) {
|
||||
myBundle = (Bundle) theBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IBaseResource> toListOfResources() {
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
for (BundleEntryComponent next : myBundle.getEntry()) {
|
||||
if (next.getResource()!=null) {
|
||||
retVal.add(next.getResource());
|
||||
} else if (next.getTransactionResponse().getLocationElement().isEmpty() == false) {
|
||||
IdType id = new IdType(next.getTransactionResponse().getLocation());
|
||||
String resourceType = id.getResourceType();
|
||||
if (isNotBlank(resourceType)) {
|
||||
IBaseResource res = (IBaseResource) myContext.getResourceDefinition(resourceType).newInstance();
|
||||
res.setId(id);
|
||||
retVal.add(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
|
@ -38,6 +38,7 @@ import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
|||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.provider.dstu2hl7org.Dstu2Hl7OrgBundleFactory;
|
||||
|
||||
public class FhirDstu2Hl7Org implements IFhirVersion {
|
||||
|
||||
|
@ -109,7 +110,7 @@ public class FhirDstu2Hl7Org implements IFhirVersion {
|
|||
|
||||
@Override
|
||||
public IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext) {
|
||||
throw new UnsupportedOperationException();
|
||||
return new Dstu2Hl7OrgBundleFactory(theContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
|||
|
||||
retVal.setPublisher(myPublisher);
|
||||
retVal.setDateElement(DateTimeType.now());
|
||||
retVal.setFhirVersion("0.4.0"); // TODO: pull from model
|
||||
retVal.setFhirVersion("0.5.0"); // TODO: pull from model
|
||||
retVal.setAcceptUnknown(false); // TODO: make this configurable - this is a fairly big effort since the parser
|
||||
// needs to be modified to actually allow it
|
||||
|
||||
|
|
|
@ -292,7 +292,8 @@ public class Narrative extends Element implements INarrative {
|
|||
*/
|
||||
public void setDivAsString(String theString) throws Exception {
|
||||
if (StringUtils.isNotBlank(theString)) {
|
||||
div = new XhtmlParser().parseFragment(theString);
|
||||
div = new XhtmlNode();
|
||||
div.setValueAsString(theString);
|
||||
} else {
|
||||
div = null;
|
||||
}
|
||||
|
@ -300,7 +301,7 @@ public class Narrative extends Element implements INarrative {
|
|||
|
||||
public String getDivAsString() throws Exception {
|
||||
if (div != null && !div.isEmpty()) {
|
||||
return new XhtmlComposer().compose(div);
|
||||
return div.getValueAsString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -39,11 +39,12 @@ import org.hl7.fhir.instance.model.annotations.SearchParamDefinition;
|
|||
import org.hl7.fhir.instance.model.annotations.Block;
|
||||
import org.hl7.fhir.instance.model.annotations.Child;
|
||||
import org.hl7.fhir.instance.model.annotations.Description;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
/**
|
||||
* This special resource type is used to represent [operation](operations.html] request and response. It has no other use, and there is no RESTful end=point associated with it.
|
||||
*/
|
||||
@ResourceDef(name="Parameters", profile="http://hl7.org/fhir/Profile/Parameters")
|
||||
public class Parameters extends Resource {
|
||||
public class Parameters extends Resource implements IBaseParameters {
|
||||
|
||||
@Block()
|
||||
public static class ParametersParameterComponent extends BackboneElement {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.hl7.fhir.instance.model;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
|
||||
|
@ -26,7 +27,7 @@ public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>
|
|||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && getValue() == null;
|
||||
return super.isEmpty() && StringUtils.isBlank(getValueAsString());
|
||||
}
|
||||
|
||||
public PrimitiveType<T> setValue(T theValue) {
|
||||
|
|
|
@ -132,7 +132,13 @@ public abstract class Resource extends Base implements IAnyResource {
|
|||
* @param value The logical id of the resource, as used in the url for the resoure. Once assigned, this value never changes.
|
||||
*/
|
||||
public Resource setId(IIdType value) {
|
||||
this.id = (IdType) value;
|
||||
if (value == null) {
|
||||
this.id = null;
|
||||
} else if (value instanceof IdType) {
|
||||
this.id = (IdType) value;
|
||||
} else {
|
||||
this.id = new IdType(value.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,15 +72,6 @@ public class StringType extends PrimitiveType<String> {
|
|||
return getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this datatype has no extensions, and has either a <code>null</code> value or an empty ("") value.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
boolean retVal = super.isEmpty() && StringUtils.isBlank(getValue());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parse(String theValue) {
|
||||
return theValue;
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.IPrimitiveType;
|
||||
import org.hl7.fhir.instance.model.annotations.DatatypeDef;
|
||||
import org.hl7.fhir.instance.model.api.IBaseXhtml;
|
||||
|
@ -285,6 +286,9 @@ public class XhtmlNode implements IBaseXhtml {
|
|||
}
|
||||
|
||||
public String getValueAsString() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new XhtmlComposer().compose(this);
|
||||
} catch (Exception e) {
|
||||
|
@ -295,9 +299,30 @@ public class XhtmlNode implements IBaseXhtml {
|
|||
|
||||
@Override
|
||||
public void setValueAsString(String theValue) throws IllegalArgumentException {
|
||||
this.Attributes = null;
|
||||
this.childNodes = null;
|
||||
this.content = null;
|
||||
this.name = null;
|
||||
this.nodeType= null;
|
||||
if (theValue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String val = theValue.trim();
|
||||
if (StringUtils.isBlank(theValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val.startsWith("<")) {
|
||||
val = "<div>" + val + "</div>";
|
||||
}
|
||||
if (val.startsWith("<?") && val.endsWith("?>")) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO: this is ugly
|
||||
XhtmlNode fragment = new XhtmlParser().parseFragment(theValue);
|
||||
XhtmlNode fragment = new XhtmlParser().parseFragment(val);
|
||||
this.Attributes = fragment.Attributes;
|
||||
this.childNodes = fragment.childNodes;
|
||||
this.content = fragment.content;
|
||||
|
|
|
@ -919,9 +919,10 @@ private boolean elementIsOk(String name) throws Exception {
|
|||
throw new Exception("Unable to Parse HTML - does not start with tag. Found "+peekChar()+descLoc());
|
||||
readChar();
|
||||
String n = readName().toLowerCase();
|
||||
readToTagEnd();
|
||||
XhtmlNode result = new XhtmlNode(NodeType.Element);
|
||||
result.setName(n);
|
||||
parseAttributes(result);
|
||||
readToTagEnd();
|
||||
unwindPoint = null;
|
||||
List<XhtmlNode> p = new ArrayList<XhtmlNode>();
|
||||
parseElementInner(result, p);
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
# This file contains version definitions
|
||||
|
||||
resource.Alert=org.hl7.fhir.instance.model.Alert
|
||||
resource.AllergyIntolerance=org.hl7.fhir.instance.model.AllergyIntolerance
|
||||
resource.Appointment=org.hl7.fhir.instance.model.Appointment
|
||||
resource.AppointmentResponse=org.hl7.fhir.instance.model.AppointmentResponse
|
||||
resource.AuditEvent=org.hl7.fhir.instance.model.AuditEvent
|
||||
resource.Basic=org.hl7.fhir.instance.model.Basic
|
||||
resource.Binary=org.hl7.fhir.instance.model.Binary
|
||||
resource.BodySite=org.hl7.fhir.instance.model.BodySite
|
||||
resource.Bundle=org.hl7.fhir.instance.model.Bundle
|
||||
resource.CarePlan=org.hl7.fhir.instance.model.CarePlan
|
||||
resource.CarePlan2=org.hl7.fhir.instance.model.CarePlan2
|
||||
resource.Claim=org.hl7.fhir.instance.model.Claim
|
||||
resource.ClaimResponse=org.hl7.fhir.instance.model.ClaimResponse
|
||||
resource.ClinicalAssessment=org.hl7.fhir.instance.model.ClinicalAssessment
|
||||
resource.ClinicalImpression=org.hl7.fhir.instance.model.ClinicalImpression
|
||||
resource.Communication=org.hl7.fhir.instance.model.Communication
|
||||
resource.CommunicationRequest=org.hl7.fhir.instance.model.CommunicationRequest
|
||||
resource.Composition=org.hl7.fhir.instance.model.Composition
|
||||
|
@ -36,8 +39,8 @@ resource.EnrollmentRequest=org.hl7.fhir.instance.model.EnrollmentRequest
|
|||
resource.EnrollmentResponse=org.hl7.fhir.instance.model.EnrollmentResponse
|
||||
resource.EpisodeOfCare=org.hl7.fhir.instance.model.EpisodeOfCare
|
||||
resource.ExplanationOfBenefit=org.hl7.fhir.instance.model.ExplanationOfBenefit
|
||||
resource.ExtensionDefinition=org.hl7.fhir.instance.model.ExtensionDefinition
|
||||
resource.FamilyHistory=org.hl7.fhir.instance.model.FamilyHistory
|
||||
resource.FamilyMemberHistory=org.hl7.fhir.instance.model.FamilyMemberHistory
|
||||
resource.Flag=org.hl7.fhir.instance.model.Flag
|
||||
resource.Goal=org.hl7.fhir.instance.model.Goal
|
||||
resource.Group=org.hl7.fhir.instance.model.Group
|
||||
resource.HealthcareService=org.hl7.fhir.instance.model.HealthcareService
|
||||
|
@ -45,8 +48,7 @@ resource.ImagingObjectSelection=org.hl7.fhir.instance.model.ImagingObjectSelecti
|
|||
resource.ImagingStudy=org.hl7.fhir.instance.model.ImagingStudy
|
||||
resource.Immunization=org.hl7.fhir.instance.model.Immunization
|
||||
resource.ImmunizationRecommendation=org.hl7.fhir.instance.model.ImmunizationRecommendation
|
||||
resource.InstitutionalClaim=org.hl7.fhir.instance.model.InstitutionalClaim
|
||||
resource.List=org.hl7.fhir.instance.model.List_
|
||||
resource.List=org.hl7.fhir.instance.model.ListResource
|
||||
resource.Location=org.hl7.fhir.instance.model.Location
|
||||
resource.Media=org.hl7.fhir.instance.model.Media
|
||||
resource.Medication=org.hl7.fhir.instance.model.Medication
|
||||
|
@ -60,61 +62,52 @@ resource.NutritionOrder=org.hl7.fhir.instance.model.NutritionOrder
|
|||
resource.Observation=org.hl7.fhir.instance.model.Observation
|
||||
resource.OperationDefinition=org.hl7.fhir.instance.model.OperationDefinition
|
||||
resource.OperationOutcome=org.hl7.fhir.instance.model.OperationOutcome
|
||||
resource.OralHealthClaim=org.hl7.fhir.instance.model.OralHealthClaim
|
||||
resource.Order=org.hl7.fhir.instance.model.Order
|
||||
resource.OrderResponse=org.hl7.fhir.instance.model.OrderResponse
|
||||
resource.Organization=org.hl7.fhir.instance.model.Organization
|
||||
resource.Other=org.hl7.fhir.instance.model.Other
|
||||
resource.Parameters=org.hl7.fhir.instance.model.Parameters
|
||||
resource.Patient=org.hl7.fhir.instance.model.Patient
|
||||
resource.PaymentNotice=org.hl7.fhir.instance.model.PaymentNotice
|
||||
resource.PaymentReconciliation=org.hl7.fhir.instance.model.PaymentReconciliation
|
||||
resource.PendedRequest=org.hl7.fhir.instance.model.PendedRequest
|
||||
resource.Person=org.hl7.fhir.instance.model.Person
|
||||
resource.PharmacyClaim=org.hl7.fhir.instance.model.PharmacyClaim
|
||||
resource.Practitioner=org.hl7.fhir.instance.model.Practitioner
|
||||
resource.Procedure=org.hl7.fhir.instance.model.Procedure
|
||||
resource.ProcedureRequest=org.hl7.fhir.instance.model.ProcedureRequest
|
||||
resource.ProfessionalClaim=org.hl7.fhir.instance.model.ProfessionalClaim
|
||||
resource.Profile=org.hl7.fhir.instance.model.Profile
|
||||
resource.ProcessRequest=org.hl7.fhir.instance.model.ProcessRequest
|
||||
resource.ProcessResponse=org.hl7.fhir.instance.model.ProcessResponse
|
||||
resource.Provenance=org.hl7.fhir.instance.model.Provenance
|
||||
resource.Questionnaire=org.hl7.fhir.instance.model.Questionnaire
|
||||
resource.QuestionnaireAnswers=org.hl7.fhir.instance.model.QuestionnaireAnswers
|
||||
resource.Readjudicate=org.hl7.fhir.instance.model.Readjudicate
|
||||
resource.ReferralRequest=org.hl7.fhir.instance.model.ReferralRequest
|
||||
resource.RelatedPerson=org.hl7.fhir.instance.model.RelatedPerson
|
||||
resource.Reversal=org.hl7.fhir.instance.model.Reversal
|
||||
resource.RiskAssessment=org.hl7.fhir.instance.model.RiskAssessment
|
||||
resource.Schedule=org.hl7.fhir.instance.model.Schedule
|
||||
resource.SearchParameter=org.hl7.fhir.instance.model.SearchParameter
|
||||
resource.SecurityEvent=org.hl7.fhir.instance.model.SecurityEvent
|
||||
resource.Slot=org.hl7.fhir.instance.model.Slot
|
||||
resource.Specimen=org.hl7.fhir.instance.model.Specimen
|
||||
resource.StatusRequest=org.hl7.fhir.instance.model.StatusRequest
|
||||
resource.StatusResponse=org.hl7.fhir.instance.model.StatusResponse
|
||||
resource.StructureDefinition=org.hl7.fhir.instance.model.StructureDefinition
|
||||
resource.Subscription=org.hl7.fhir.instance.model.Subscription
|
||||
resource.Substance=org.hl7.fhir.instance.model.Substance
|
||||
resource.Supply=org.hl7.fhir.instance.model.Supply
|
||||
resource.SupportingDocumentation=org.hl7.fhir.instance.model.SupportingDocumentation
|
||||
resource.ValueSet=org.hl7.fhir.instance.model.ValueSet
|
||||
resource.VisionClaim=org.hl7.fhir.instance.model.VisionClaim
|
||||
resource.VisionPrescription=org.hl7.fhir.instance.model.VisionPrescription
|
||||
|
||||
datatype.Address=org.hl7.fhir.instance.model.Address
|
||||
datatype.Attachment=org.hl7.fhir.instance.model.Attachment
|
||||
datatype.CodeableConcept=org.hl7.fhir.instance.model.CodeableConcept
|
||||
datatype.Coding=org.hl7.fhir.instance.model.Coding
|
||||
datatype.ContactPoint=org.hl7.fhir.instance.model.ContactPoint
|
||||
datatype.ElementDefinition=org.hl7.fhir.instance.model.ElementDefinition
|
||||
datatype.HumanName=org.hl7.fhir.instance.model.HumanName
|
||||
datatype.Identifier=org.hl7.fhir.instance.model.Identifier
|
||||
datatype.Meta=org.hl7.fhir.instance.model.Meta
|
||||
datatype.Period=org.hl7.fhir.instance.model.Period
|
||||
datatype.Quantity=org.hl7.fhir.instance.model.Quantity
|
||||
datatype.Range=org.hl7.fhir.instance.model.Range
|
||||
datatype.Ratio=org.hl7.fhir.instance.model.Ratio
|
||||
datatype.Reference=org.hl7.fhir.instance.model.Reference
|
||||
datatype.SampledData=org.hl7.fhir.instance.model.SampledData
|
||||
datatype.Timing=org.hl7.fhir.instance.model.Timing
|
||||
datatype.Address=org.hl7.fhir.instance.model.AddressType
|
||||
datatype.Attachment=org.hl7.fhir.instance.model.AttachmentType
|
||||
datatype.CodeableConcept=org.hl7.fhir.instance.model.CodeableConceptType
|
||||
datatype.Coding=org.hl7.fhir.instance.model.CodingType
|
||||
datatype.ContactPoint=org.hl7.fhir.instance.model.ContactPointType
|
||||
datatype.ElementDefinition=org.hl7.fhir.instance.model.ElementDefinitionType
|
||||
datatype.HumanName=org.hl7.fhir.instance.model.HumanNameType
|
||||
datatype.Identifier=org.hl7.fhir.instance.model.IdentifierType
|
||||
datatype.Meta=org.hl7.fhir.instance.model.MetaType
|
||||
datatype.Period=org.hl7.fhir.instance.model.PeriodType
|
||||
datatype.Quantity=org.hl7.fhir.instance.model.QuantityType
|
||||
datatype.Range=org.hl7.fhir.instance.model.RangeType
|
||||
datatype.Ratio=org.hl7.fhir.instance.model.RatioType
|
||||
datatype.SampledData=org.hl7.fhir.instance.model.SampledDataType
|
||||
datatype.Signature=org.hl7.fhir.instance.model.SignatureType
|
||||
datatype.Timing=org.hl7.fhir.instance.model.TimingType
|
||||
datatype.base64Binary=org.hl7.fhir.instance.model.Base64BinaryType
|
||||
datatype.boolean=org.hl7.fhir.instance.model.BooleanType
|
||||
datatype.code=org.hl7.fhir.instance.model.CodeType
|
||||
|
@ -122,9 +115,13 @@ datatype.date=org.hl7.fhir.instance.model.DateType
|
|||
datatype.dateTime=org.hl7.fhir.instance.model.DateTimeType
|
||||
datatype.decimal=org.hl7.fhir.instance.model.DecimalType
|
||||
datatype.id=org.hl7.fhir.instance.model.IdType
|
||||
datatype.idref=org.hl7.fhir.instance.model.IdrefType
|
||||
datatype.instant=org.hl7.fhir.instance.model.InstantType
|
||||
datatype.integer=org.hl7.fhir.instance.model.IntegerType
|
||||
datatype.oid=org.hl7.fhir.instance.model.OidType
|
||||
datatype.positiveInt=org.hl7.fhir.instance.model.PositiveIntType
|
||||
datatype.string=org.hl7.fhir.instance.model.StringType
|
||||
datatype.time=org.hl7.fhir.instance.model.TimeType
|
||||
datatype.unsignedInt=org.hl7.fhir.instance.model.UnsignedIntType
|
||||
datatype.uri=org.hl7.fhir.instance.model.UriType
|
||||
datatype.xhtml=org.hl7.fhir.instance.model.XhtmlType
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.hl7.fhir.instance.model.IntegerType;
|
|||
import org.hl7.fhir.instance.model.List_;
|
||||
import org.hl7.fhir.instance.model.Meta;
|
||||
import org.hl7.fhir.instance.model.Narrative;
|
||||
import org.hl7.fhir.instance.model.Parameters;
|
||||
import org.hl7.fhir.instance.model.PrimitiveType;
|
||||
import org.hl7.fhir.instance.model.Reference;
|
||||
import org.hl7.fhir.instance.model.Resource;
|
||||
|
@ -43,6 +44,7 @@ import org.hl7.fhir.instance.model.api.IBaseExtension;
|
|||
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
|
||||
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
|
||||
import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IBaseXhtml;
|
||||
import org.hl7.fhir.instance.model.api.ICoding;
|
||||
import org.hl7.fhir.instance.model.api.IDatatypeElement;
|
||||
|
@ -199,6 +201,11 @@ public class ModelInheritanceTest {
|
|||
assertTrue(IReference.class.isAssignableFrom(Reference.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParameters() {
|
||||
assertTrue(IBaseParameters.class.isAssignableFrom(Parameters.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResource() {
|
||||
assertTrue(IAnyResource.class.isAssignableFrom(Resource.class));
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package ca.uhn.fhir.model;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.hl7.fhir.instance.model.Narrative;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.junit.Test;
|
||||
|
||||
public class XhtmlNodeTest {
|
||||
|
||||
@Test
|
||||
public void testNamespaces() {
|
||||
|
||||
Narrative type = new Narrative();
|
||||
XhtmlNode div = type.getDiv();
|
||||
div.setValue("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">hello</xhtml:div>");
|
||||
|
||||
assertEquals("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">hello</xhtml:div>", div.getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -5,14 +5,12 @@ import static org.hamcrest.Matchers.not;
|
|||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -37,8 +35,6 @@ import org.hl7.fhir.instance.model.Bundle;
|
|||
import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.instance.model.CodeableConcept;
|
||||
import org.hl7.fhir.instance.model.Composition;
|
||||
import org.hl7.fhir.instance.model.Conformance;
|
||||
import org.hl7.fhir.instance.model.Conformance.ConformanceRestResourceComponent;
|
||||
import org.hl7.fhir.instance.model.DateTimeType;
|
||||
import org.hl7.fhir.instance.model.DateType;
|
||||
import org.hl7.fhir.instance.model.DecimalType;
|
||||
|
@ -56,12 +52,10 @@ import org.hl7.fhir.instance.model.Narrative.NarrativeStatus;
|
|||
import org.hl7.fhir.instance.model.Observation;
|
||||
import org.hl7.fhir.instance.model.Organization;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.hl7.fhir.instance.model.Profile;
|
||||
import org.hl7.fhir.instance.model.Reference;
|
||||
import org.hl7.fhir.instance.model.Resource;
|
||||
import org.hl7.fhir.instance.model.Specimen;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
@ -70,19 +64,298 @@ import ca.uhn.fhir.context.ConfigurationException;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
|
||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredAddressExtension;
|
||||
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredExtension;
|
||||
import ca.uhn.fhir.parser.JsonParserHl7OrgTest.MyPatientWithOneDeclaredAddressExtension;
|
||||
import ca.uhn.fhir.parser.JsonParserHl7OrgTest.MyPatientWithOneDeclaredExtension;
|
||||
|
||||
public class XmlParserTest {
|
||||
public class XmlParserHl7OrgDstu2Test {
|
||||
|
||||
private static FhirContext ourCtx;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserTest.class);
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserHl7OrgDstu2Test.class);
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass2() {
|
||||
System.setProperty("file.encoding", "ISO-8859-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainedResourceInExtensionUndeclared() {
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("PATIENT");
|
||||
|
||||
Organization o = new Organization();
|
||||
o.setName("ORG");
|
||||
p.addExtension().setUrl("urn:foo").setValue(new Reference(o));
|
||||
|
||||
String str = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
ourLog.info(str);
|
||||
|
||||
p = ourCtx.newXmlParser().parseResource(Patient.class, str);
|
||||
assertEquals("PATIENT", p.getName().get(0).getFamily().get(0).getValue());
|
||||
|
||||
List<Extension> exts = p.getExtension();
|
||||
assertEquals(1, exts.size());
|
||||
Reference rr = (Reference)exts.get(0).getValue();
|
||||
o = (Organization) rr.getResource();
|
||||
assertEquals("ORG", o.getName());
|
||||
}
|
||||
|
||||
// TODO: uncomment with new model updates
|
||||
// @Test
|
||||
// public void testEncodeAndParseExtensionOnResourceReference() {
|
||||
// DataElement de = new DataElement();
|
||||
// Binding b = de.addElement().getBinding();
|
||||
// b.setName("BINDING");
|
||||
//
|
||||
// Organization o = new Organization();
|
||||
// o.setName("ORG");
|
||||
// b.addUndeclaredExtension(new ExtensionDt(false, "urn:foo", new ResourceReferenceDt(o)));
|
||||
//
|
||||
// String str = ourCtx.newXmlParser().encodeResourceToString(de);
|
||||
// ourLog.info(str);
|
||||
//
|
||||
// de = ourCtx.newXmlParser().parseResource(DataElement.class, str);
|
||||
// b = de.getElement().get(0).getBinding();
|
||||
// assertEquals("BINDING", b.getName());
|
||||
//
|
||||
// List<ExtensionDt> exts = b.getUndeclaredExtensionsByUrl("urn:foo");
|
||||
// assertEquals(1, exts.size());
|
||||
// ResourceReferenceDt rr = (ResourceReferenceDt)exts.get(0).getValue();
|
||||
// o = (Organization) rr.getResource();
|
||||
// assertEquals("ORG", o.getName());
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testParseAndEncodeExtensionOnResourceReference() {
|
||||
// //@formatter:off
|
||||
// String input = "<DataElement>" +
|
||||
// "<id value=\"gender\"/>"+
|
||||
// "<contained>"+
|
||||
// "<ValueSet>"+
|
||||
// "<id value=\"2179414\"/>"+
|
||||
// "<url value=\"2179414\"/>"+
|
||||
// "<version value=\"1.0\"/>"+
|
||||
// "<name value=\"Gender Code\"/>"+
|
||||
// "<description value=\"All codes representing the gender of a person.\"/>"+
|
||||
// "<status value=\"active\"/>"+
|
||||
// "<compose>"+
|
||||
// "<include>"+
|
||||
// "<system value=\"http://ncit.nci.nih.gov\"/>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"C17998\"/>"+
|
||||
// "<display value=\"Unknown\"/>"+
|
||||
// "</concept>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"C20197\"/>"+
|
||||
// "<display value=\"Male\"/>"+
|
||||
// "</concept>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"C16576\"/>"+
|
||||
// "<display value=\"Female\"/>"+
|
||||
// "</concept>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"C38046\"/>"+
|
||||
// "<display value=\"Not specified\"/>"+
|
||||
// "</concept>"+
|
||||
// "</include>"+
|
||||
// "</compose>"+
|
||||
// "</ValueSet>"+
|
||||
// "</contained>"+
|
||||
// "<contained>"+
|
||||
// "<ValueSet>"+
|
||||
// "<id value=\"2179414-permitted\"/>"+
|
||||
// "<status value=\"active\"/>"+
|
||||
// "<define>"+
|
||||
// "<system value=\"http://example.org/fhir/2179414\"/>"+
|
||||
// "<caseSensitive value=\"true\"/>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"0\"/>"+
|
||||
// "</concept>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"1\"/>"+
|
||||
// "</concept>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"2\"/>"+
|
||||
// "</concept>"+
|
||||
// "<concept>"+
|
||||
// "<code value=\"3\"/>"+
|
||||
// "</concept>"+
|
||||
// "</define>"+
|
||||
// "</ValueSet>"+
|
||||
// "</contained>"+
|
||||
// "<contained>"+
|
||||
// "<ConceptMap>"+
|
||||
// "<id value=\"2179414-cm\"/>"+
|
||||
// "<status value=\"active\"/>"+
|
||||
// "<sourceReference>"+
|
||||
// "<reference value=\"#2179414\"/>"+
|
||||
// "</sourceReference>"+
|
||||
// "<targetReference>"+
|
||||
// "<reference value=\"#2179414-permitted\"/>"+
|
||||
// "</targetReference>"+
|
||||
// "<element>"+
|
||||
// "<code value=\"C17998\"/>"+
|
||||
// "<map>"+
|
||||
// "<code value=\"0\"/>"+
|
||||
// "<equivalence value=\"equal\"/>"+
|
||||
// "</map>"+
|
||||
// "</element>"+
|
||||
// "<element>"+
|
||||
// "<code value=\"C20197\"/>"+
|
||||
// "<map>"+
|
||||
// "<code value=\"1\"/>"+
|
||||
// "<equivalence value=\"equal\"/>"+
|
||||
// "</map>"+
|
||||
// "</element>"+
|
||||
// "<element>"+
|
||||
// "<code value=\"C16576\"/>"+
|
||||
// "<map>"+
|
||||
// "<code value=\"2\"/>"+
|
||||
// "<equivalence value=\"equal\"/>"+
|
||||
// "</map>"+
|
||||
// "</element>"+
|
||||
// "<element>"+
|
||||
// "<code value=\"C38046\"/>"+
|
||||
// "<map>"+
|
||||
// "<code value=\"3\"/>"+
|
||||
// "<equivalence value=\"equal\"/>"+
|
||||
// "</map>"+
|
||||
// "</element>"+
|
||||
// "</ConceptMap>"+
|
||||
// "</contained>"+
|
||||
// "<identifier>"+
|
||||
// "<value value=\"2179650\"/>"+
|
||||
// "</identifier>"+
|
||||
// "<version value=\"1.0\"/>"+
|
||||
// "<name value=\"Gender Code\"/>"+
|
||||
// "<useContext>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/FBPP\"/>"+
|
||||
// "<display value=\"FBPP Pooled Database\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/PhenX\"/>"+
|
||||
// "<display value=\"Demographics\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/EligibilityCriteria\"/>"+
|
||||
// "<display value=\"Pt. Administrative\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/UAMSClinicalResearch\"/>"+
|
||||
// "<display value=\"UAMS New CDEs\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/PhenX\"/>"+
|
||||
// "<display value=\"Substance Abuse and \"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Category\"/>"+
|
||||
// "<display value=\"CSAERS Adverse Event\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/PhenX\"/>"+
|
||||
// "<display value=\"Core: Tier 1\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Category\"/>"+
|
||||
// "<display value=\"Case Report Forms\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Category\"/>"+
|
||||
// "<display value=\"CSAERS Review Set\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Demonstration%20Applications\"/>"+
|
||||
// "<display value=\"CIAF\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/NIDA%20CTN%20Usage\"/>"+
|
||||
// "<display value=\"Clinical Research\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/NIDA%20CTN%20Usage\"/>"+
|
||||
// "<display value=\"Electronic Health Re\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Condition\"/>"+
|
||||
// "<display value=\"Barretts Esophagus\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Condition\"/>"+
|
||||
// "<display value=\"Bladder Cancer\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Condition\"/>"+
|
||||
// "<display value=\"Oral Leukoplakia\"/>"+
|
||||
// "</coding>"+
|
||||
// "<coding>"+
|
||||
// "<system value=\"http://example.org/Condition\"/>"+
|
||||
// "<display value=\"Sulindac for Breast\"/>"+
|
||||
// "</coding>"+
|
||||
// "</useContext>"+
|
||||
// "<status value=\"active\"/>"+
|
||||
// "<publisher value=\"DCP\"/>"+
|
||||
// "<element>"+
|
||||
// "<extension url=\"http://hl7.org/fhir/StructureDefinition/minLength\">"+
|
||||
// "<valueInteger value=\"1\"/>"+
|
||||
// "</extension>"+
|
||||
// "<extension url=\"http://hl7.org/fhir/StructureDefinition/elementdefinition-question\">"+
|
||||
// "<valueString value=\"Gender\"/>"+
|
||||
// "</extension>"+
|
||||
// "<path value=\"Gender\"/>"+
|
||||
// "<definition value=\"The code representing the gender of a person.\"/>"+
|
||||
// "<type>"+
|
||||
// "<code value=\"CodeableConcept\"/>"+
|
||||
// "</type>"+
|
||||
// "<maxLength value=\"13\"/>"+
|
||||
// "<binding>"+
|
||||
// "<name value=\"Gender\"/>"+
|
||||
// "<strength value=\"required\"/>"+
|
||||
// "<valueSetReference>"+
|
||||
// "<extension url=\"http://hl7.org/fhir/StructureDefinition/11179-permitted-value-valueset\">"+
|
||||
// "<valueReference>"+
|
||||
// "<reference value=\"#2179414-permitted\"/>"+
|
||||
// "</valueReference>"+
|
||||
// "</extension>"+
|
||||
// "<extension url=\"http://hl7.org/fhir/StructureDefinition/11179-permitted-value-conceptmap\">"+
|
||||
// "<valueReference>"+
|
||||
// "<reference value=\"#2179414-cm\"/>"+
|
||||
// "</valueReference>"+
|
||||
// "</extension>"+
|
||||
// "<reference value=\"#2179414\"/>"+
|
||||
// "</valueSetReference>"+
|
||||
// "</binding>"+
|
||||
// "</element>"+
|
||||
// "</DataElement>";
|
||||
// //@formatter:on
|
||||
// DataElement de = ourCtx.newXmlParser().parseResource(DataElement.class, input);
|
||||
// String output = ourCtx.newXmlParser().encodeResourceToString(de).replace(" xmlns=\"http://hl7.org/fhir\"", "");
|
||||
//
|
||||
// ElementDefinitionDt elem = de.getElement().get(0);
|
||||
// Binding b = elem.getBinding();
|
||||
// assertEquals("Gender", b.getName());
|
||||
//
|
||||
// ResourceReferenceDt ref = (ResourceReferenceDt) b.getValueSet();
|
||||
// assertEquals("#2179414", ref.getReference().getValue());
|
||||
//
|
||||
// assertEquals(2, ref.getUndeclaredExtensions().size());
|
||||
// ExtensionDt ext = ref.getUndeclaredExtensions().get(0);
|
||||
// assertEquals("http://hl7.org/fhir/StructureDefinition/11179-permitted-value-valueset", ext.getUrl());
|
||||
// assertEquals(ResourceReferenceDt.class, ext.getValue().getClass());
|
||||
// assertEquals("#2179414-permitted", ((ResourceReferenceDt)ext.getValue()).getReference().getValue());
|
||||
//
|
||||
// ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(de));
|
||||
//
|
||||
// assertThat(output, containsString("http://hl7.org/fhir/StructureDefinition/11179-permitted-value-valueset"));
|
||||
//
|
||||
// ourLog.info("Expected: {}", input);
|
||||
// ourLog.info("Actual : {}", output);
|
||||
// assertEquals(input, output);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeBinaryWithNoContentType() {
|
||||
Binary b = new Binary();
|
||||
|
@ -94,6 +367,80 @@ public class XmlParserTest {
|
|||
assertEquals("<Binary xmlns=\"http://hl7.org/fhir\"><content value=\"AQIDBA==\"/></Binary>", output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoreExtensions() throws Exception {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
|
||||
|
||||
Extension ext = new Extension();
|
||||
ext.setUrl("http://example.com/extensions#someext");
|
||||
ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
|
||||
|
||||
// Add the extension to the resource
|
||||
patient.getExtension().add(ext);
|
||||
// END SNIPPET: resourceExtension
|
||||
|
||||
// START SNIPPET: resourceStringExtension
|
||||
HumanName name = patient.addName();
|
||||
name.addFamily("Shmoe");
|
||||
StringType given = name.addGivenElement();
|
||||
given.setValue("Joe");
|
||||
Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given"));
|
||||
given.getExtension().add(ext2);
|
||||
|
||||
StringType given2 = name.addGivenElement();
|
||||
given2.setValue("Shmoe");
|
||||
Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent");
|
||||
given2.getExtension().add(given2ext);
|
||||
given2ext.addExtension().setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD"));
|
||||
// END SNIPPET: resourceStringExtension
|
||||
|
||||
// START SNIPPET: subExtension
|
||||
Extension parent = new Extension().setUrl("http://example.com#parent");
|
||||
patient.getExtension().add(parent);
|
||||
|
||||
Extension child1 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
|
||||
parent.getExtension().add(child1);
|
||||
|
||||
Extension child2 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
|
||||
parent.getExtension().add(child2);
|
||||
// END SNIPPET: subExtension
|
||||
|
||||
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
ourLog.info(output);
|
||||
|
||||
String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
|
||||
assertThat(enc, containsString("<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://example.com/extensions#someext\"><valueDateTime value=\"2011-01-02T11:13:15\"/></extension>"));
|
||||
assertThat(
|
||||
enc,
|
||||
containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension></extension>"));
|
||||
assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
|
||||
assertThat(enc, containsString("<given value=\"Shmoe\"><extension url=\"http://examples.com#givenext_parent\"><extension url=\"http://examples.com#givenext_child\"><valueString value=\"CHILD\"/></extension></extension></given>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodingNullExtension() {
|
||||
Patient p = new Patient();
|
||||
Extension extension = new Extension().setUrl("http://foo#bar");
|
||||
p.getExtension().add(extension);
|
||||
String str = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"/>", str);
|
||||
|
||||
extension.setValue(new StringType());
|
||||
|
||||
str = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"/>", str);
|
||||
|
||||
extension.setValue(new StringType(""));
|
||||
|
||||
str = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"/>", str);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeNonContained() {
|
||||
// Create an organization
|
||||
|
@ -341,14 +688,18 @@ public class XmlParserTest {
|
|||
String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
|
||||
ourLog.info(bundleString);
|
||||
|
||||
List<String> strings = new ArrayList<String>();
|
||||
strings.addAll(Arrays.asList("<published>", pub.getValueAsString(), "</published>"));
|
||||
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
|
||||
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
|
||||
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
|
||||
//@formatter:on
|
||||
String[] strings = {
|
||||
"<Bundle xmlns=\"http://hl7.org/fhir\">",
|
||||
"<lastUpdated value=\"" + pub.getValueAsString() + "\"/>",
|
||||
"<Patient xmlns=\"http://hl7.org/fhir\">",
|
||||
"<id value=\"1\"/>",
|
||||
"<Patient xmlns=\"http://hl7.org/fhir\">",
|
||||
"<id value=\"2\"/>"
|
||||
};
|
||||
//@formatter:off
|
||||
|
||||
assertThat(bundleString, StringContainsInOrder.stringContainsInOrder(strings));
|
||||
assertThat(bundleString, not(containsString("at:by")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -362,7 +713,13 @@ public class XmlParserTest {
|
|||
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
|
||||
ourLog.info(val);
|
||||
|
||||
assertThat(val, StringContains.containsString("<category term=\"term\" label=\"label\" scheme=\"scheme\"/>"));
|
||||
//@formatter:off
|
||||
assertThat(val, stringContainsInOrder("<tag>",
|
||||
"<system value=\"scheme\"/>",
|
||||
"<code value=\"term\"/>",
|
||||
"<display value=\"label\"/>",
|
||||
"</tag>"));
|
||||
//@formatter:on
|
||||
|
||||
b = ourCtx.newXmlParser().parseResource(Bundle.class, val);
|
||||
assertEquals(1, b.getEntry().size());
|
||||
|
@ -370,8 +727,6 @@ public class XmlParserTest {
|
|||
assertEquals("scheme", b.getEntry().get(0).getResource().getMeta().getTag().get(0).getSystem());
|
||||
assertEquals("term", b.getEntry().get(0).getResource().getMeta().getTag().get(0).getCode());
|
||||
assertEquals("label", b.getEntry().get(0).getResource().getMeta().getTag().get(0).getDisplay());
|
||||
assertNull(b.getEntry().get(0).getResource());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -433,7 +788,7 @@ public class XmlParserTest {
|
|||
int idx = str.indexOf("reference value=\"#") + "reference value=\"#".length();
|
||||
int idx2 = str.indexOf('"', idx + 1);
|
||||
String id = str.substring(idx, idx2);
|
||||
assertThat(str, StringContains.containsString("<Specimen xmlns=\"http://hl7.org/fhir\" id=\"" + id + "\">"));
|
||||
assertThat(str, stringContainsInOrder("<Specimen xmlns=\"http://hl7.org/fhir\">", "<id value=\"" + id + "\"/>"));
|
||||
assertThat(str, IsNot.not(StringContains.containsString("<?xml version='1.0'?>")));
|
||||
|
||||
}
|
||||
|
@ -467,12 +822,12 @@ public class XmlParserTest {
|
|||
|
||||
String val = parser.encodeResourceToString(patient);
|
||||
ourLog.info(val);
|
||||
assertThat(val, StringContains.containsString("<extension url=\"urn:foo\"><valueResource><reference value=\"Organization/123\"/></valueResource></extension>"));
|
||||
assertThat(val, StringContains.containsString("<extension url=\"urn:foo\"><valueReference><reference value=\"Organization/123\"/></valueReference></extension>"));
|
||||
|
||||
MyPatientWithOneDeclaredExtension actual = parser.parseResource(MyPatientWithOneDeclaredExtension.class, val);
|
||||
assertEquals(AddressUse.HOME, patient.getAddress().get(0).getUse());
|
||||
Reference ref = actual.getFoo();
|
||||
assertEquals("Organization/123", ref.getReference());
|
||||
assertEquals("Organization/123", ref.getReference().getValue());
|
||||
|
||||
}
|
||||
|
||||
|
@ -1016,13 +1371,7 @@ public class XmlParserTest {
|
|||
ourLog.info(str);
|
||||
|
||||
assertThat(str, stringContainsInOrder(Arrays.asList("<text value=\"B\"/>", "<text value=\"C\"/>", "<text value=\"A\"/>")));
|
||||
assertThat(str, stringContainsInOrder(Arrays.asList("<contained>", "</contained>")));
|
||||
|
||||
// Only one (outer) contained block
|
||||
int idx0 = str.indexOf("<contained>");
|
||||
int idx1 = str.indexOf("<contained>", idx0 + 1);
|
||||
assertNotEquals(-1, idx0);
|
||||
assertEquals(-1, idx1);
|
||||
assertThat(str, stringContainsInOrder(Arrays.asList("<contained>", "</contained>", "<contained>", "</contained>")));
|
||||
|
||||
Observation obs = ourCtx.newXmlParser().parseResource(Observation.class, str);
|
||||
assertEquals("A", obs.getCode().getText());
|
||||
|
@ -1038,35 +1387,12 @@ public class XmlParserTest {
|
|||
@Test
|
||||
public void testParseBinaryResource() {
|
||||
|
||||
Binary val = ourCtx.newXmlParser().parseResource(Binary.class, "<Binary xmlns=\"http://hl7.org/fhir\" contentType=\"foo\">AQIDBA==</Binary>");
|
||||
Binary val = ourCtx.newXmlParser().parseResource(Binary.class, "<Binary xmlns=\"http://hl7.org/fhir\"><contentType value=\"foo\"/><content value=\"AQIDBA==\"/></Binary>");
|
||||
assertEquals("foo", val.getContentType());
|
||||
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, val.getContent());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseBundleWithMixedReturnTypes() {
|
||||
InputStreamReader str = new InputStreamReader(getClass().getResourceAsStream("/mixed-return-bundle.xml"));
|
||||
Bundle b = ourCtx.newXmlParser().parseResource(Bundle.class, str);
|
||||
assertEquals(Patient.class, b.getEntry().get(0).getResource().getClass());
|
||||
assertEquals(Patient.class, b.getEntry().get(1).getResource().getClass());
|
||||
assertEquals(Organization.class, b.getEntry().get(2).getResource().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseContainedResources() throws IOException {
|
||||
|
||||
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/contained-diagnosticreport.xml"));
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
DiagnosticReport bundle = p.parseResource(DiagnosticReport.class, msg);
|
||||
|
||||
Reference result0 = bundle.getResult().get(0);
|
||||
Observation obs = (Observation) result0.getResource();
|
||||
|
||||
assertNotNull(obs);
|
||||
assertEquals("718-7", obs.getCode().getCoding().get(0).getCode());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseEncodeNarrative() {
|
||||
|
@ -1088,18 +1414,6 @@ public class XmlParserTest {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* This sample has extra elements in <searchParam> that are not actually a part of the spec any more..
|
||||
*/
|
||||
@Test
|
||||
public void testParseFuroreMetadataWithExtraElements() throws IOException {
|
||||
String msg = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/furore-conformance.xml"));
|
||||
|
||||
IParser p = new FhirContext(ValueSet.class).newXmlParser();
|
||||
Conformance conf = p.parseResource(Conformance.class, msg);
|
||||
ConformanceRestResourceComponent res = conf.getRest().get(0).getResource().get(0);
|
||||
assertEquals("_id", res.getSearchParam().get(1).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseLanguage() {
|
|
@ -0,0 +1,79 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
||||
public class BundleTypeTest {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BundleTypeTest.class);
|
||||
private FhirContext ourCtx;
|
||||
private HttpClient ourHttpClient;
|
||||
|
||||
private HttpResponse ourHttpResponse;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ourCtx = FhirContext.forDstu2Hl7Org();
|
||||
|
||||
ourHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ourCtx.getRestfulClientFactory().setHttpClient(ourHttpClient);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
|
||||
|
||||
ourHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransaction() throws Exception {
|
||||
String retVal = ourCtx.newXmlParser().encodeBundleToString(new Bundle());
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse);
|
||||
when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_ATOM_XML + "; charset=UTF-8"));
|
||||
when(ourHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8")));
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("value");
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://foo");
|
||||
client.transaction().withResources(Arrays.asList((IBaseResource) p1)).execute();
|
||||
|
||||
HttpUriRequest value = capt.getValue();
|
||||
|
||||
assertTrue("Expected request of type POST on long params list", value instanceof HttpPost);
|
||||
HttpPost post = (HttpPost) value;
|
||||
String body = IOUtils.toString(post.getEntity().getContent());
|
||||
IOUtils.closeQuietly(post.getEntity().getContent());
|
||||
ourLog.info(body);
|
||||
|
||||
assertThat(body, Matchers.containsString("<type value=\"" + BundleTypeEnum.TRANSACTION.getCode()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.instance.model.Conformance;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
||||
public class ClientServerValidationTestDstu2 {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ClientServerValidationTestDstu2.class);
|
||||
private FhirContext myCtx;
|
||||
private HttpClient myHttpClient;
|
||||
private HttpResponse myHttpResponse;
|
||||
private boolean myFirstResponse;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
|
||||
myCtx = FhirContext.forDstu2Hl7Org();
|
||||
myCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||
myFirstResponse = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerReturnsAppropriateVersionForDstu2_040() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.5.0");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myFirstResponse) {
|
||||
myFirstResponse=false;
|
||||
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
||||
}
|
||||
}});
|
||||
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
|
||||
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||
|
||||
// don't load the conformance until the first time the client is actually used
|
||||
assertTrue(myFirstResponse);
|
||||
client.read(new UriDt("http://foo/Patient/123"));
|
||||
assertFalse(myFirstResponse);
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
|
||||
// Conformance only loaded once, then 3 reads
|
||||
verify(myHttpClient, times(4)).execute(Matchers.any(HttpUriRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerReturnsAppropriateVersionForDstu2_050() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.5.0");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myFirstResponse) {
|
||||
myFirstResponse=false;
|
||||
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
||||
}
|
||||
}});
|
||||
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
|
||||
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||
|
||||
// don't load the conformance until the first time the client is actually used
|
||||
assertTrue(myFirstResponse);
|
||||
client.read(new UriDt("http://foo/Patient/123"));
|
||||
assertFalse(myFirstResponse);
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
|
||||
// Conformance only loaded once, then 3 reads
|
||||
verify(myHttpClient, times(4)).execute(Matchers.any(HttpUriRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerReturnsWrongVersionForDstu2() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.80");
|
||||
String msg = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
|
||||
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
|
||||
try {
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
fail();
|
||||
} catch (FhirClientConnectionException e) {
|
||||
String out = e.toString();
|
||||
String want = "The server at base URL \"http://foo/metadata\" returned a conformance statement indicating that it supports FHIR version \"0.80\" which corresponds to DSTU1, but this client is configured to use DSTU2_HL7ORG (via the FhirContext)";
|
||||
ourLog.info(out);
|
||||
ourLog.info(want);
|
||||
assertThat(out, containsString(want));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotModifiedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class ETagClientTest {
|
||||
|
||||
private static FhirContext ourCtx;
|
||||
private HttpClient myHttpClient;
|
||||
|
||||
private HttpResponse myHttpResponse;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
|
||||
|
||||
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
||||
private String getResourceResult() {
|
||||
//@formatter:off
|
||||
String msg =
|
||||
"<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
+ "<id value=\"123\"/>"
|
||||
+ "<meta>"
|
||||
+ "<versionId value=\"4444\"/>"
|
||||
+ "</meta>"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
|
||||
+ "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
|
||||
+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
|
||||
+ "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>"
|
||||
+ "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>"
|
||||
+ "<gender value=\"male\"/>"
|
||||
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
|
||||
+ "</Patient>";
|
||||
//@formatter:on
|
||||
return msg;
|
||||
}
|
||||
|
||||
private Patient getResource() {
|
||||
return ourCtx.newXmlParser().parseResource(Patient.class, getResourceResult());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithContentLocationInResponse() throws Exception {
|
||||
|
||||
String msg = getResourceResult();
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
//@formatter:off
|
||||
Header[] headers = new Header[] {
|
||||
new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"),
|
||||
new BasicHeader(Constants.HEADER_ETAG, "\"9999\"")
|
||||
};
|
||||
//@formatter:on
|
||||
when(myHttpResponse.getAllHeaders()).thenReturn(headers);
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient response = client.read(Patient.class, new IdDt("Patient/1234"));
|
||||
|
||||
assertEquals("http://foo.com/Patient/123/_history/2333", response.getId().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithIfNoneMatch() throws Exception {
|
||||
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), Constants.STATUS_HTTP_304_NOT_MODIFIED, "Not modified"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int count = 0;
|
||||
|
||||
//@formatter:off
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("")));
|
||||
try {
|
||||
client
|
||||
.read()
|
||||
.resource(Patient.class)
|
||||
.withId(new IdDt("Patient/1234"))
|
||||
.execute();
|
||||
fail();
|
||||
} catch (NotModifiedException e) {
|
||||
// good!
|
||||
}
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count).getURI().toString());
|
||||
count++;
|
||||
|
||||
//@formatter:off
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("")));
|
||||
Patient expected = new Patient();
|
||||
Patient response = client
|
||||
.read()
|
||||
.resource(Patient.class)
|
||||
.withId(new IdDt("Patient/1234"))
|
||||
.ifVersionMatches("9876").returnResource(expected)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertSame(expected, response);
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count).getURI().toString());
|
||||
assertEquals("\"9876\"", capt.getAllValues().get(count).getHeaders(Constants.HEADER_IF_NONE_MATCH_LC)[0].getValue());
|
||||
count++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithIfMatch() throws Exception {
|
||||
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), Constants.STATUS_HTTP_200_OK, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int count = 0;
|
||||
|
||||
//@formatter:off
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("")));
|
||||
client
|
||||
.update()
|
||||
.resource(getResource())
|
||||
.withId(new IdDt("Patient/1234"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count).getURI().toString());
|
||||
assertEquals(0, capt.getAllValues().get(count).getHeaders(Constants.HEADER_IF_MATCH_LC).length);
|
||||
count++;
|
||||
|
||||
//@formatter:off
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("")));
|
||||
client
|
||||
.update()
|
||||
.resource(getResource())
|
||||
.withId(new IdDt("Patient/1234/_history/9876"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count).getURI().toString());
|
||||
assertEquals("\"9876\"", capt.getAllValues().get(count).getHeaders(Constants.HEADER_IF_MATCH_LC)[0].getValue());
|
||||
count++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithIfMatchWithPreconditionFailed() throws Exception {
|
||||
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), Constants.STATUS_HTTP_412_PRECONDITION_FAILED, "Precondition Failed"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int count = 0;
|
||||
|
||||
//@formatter:off
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("")));
|
||||
try {
|
||||
client
|
||||
.update()
|
||||
.resource(getResource())
|
||||
.withId(new IdDt("Patient/1234/_history/9876"))
|
||||
.execute();
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
// good
|
||||
}
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count).getURI().toString());
|
||||
assertEquals("\"9876\"", capt.getAllValues().get(count).getHeaders(Constants.HEADER_IF_MATCH_LC)[0].getValue());
|
||||
count++;
|
||||
|
||||
//@formatter:off
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("")));
|
||||
try {
|
||||
Patient resource = getResource();
|
||||
resource.setId(new IdDt("Patient/1234/_history/9876"));
|
||||
client
|
||||
.update()
|
||||
.resource(resource)
|
||||
.execute();
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
// good
|
||||
}
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count).getURI().toString());
|
||||
assertEquals("\"9876\"", capt.getAllValues().get(count).getHeaders(Constants.HEADER_IF_MATCH_LC)[0].getValue());
|
||||
count++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithETag() throws Exception {
|
||||
|
||||
String msg = getResourceResult();
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"),
|
||||
new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") };
|
||||
when(myHttpResponse.getAllHeaders()).thenReturn(headers);
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int count = 0;
|
||||
|
||||
Patient response = client.read().resource(Patient.class).withId(new IdDt("Patient/1234")).execute();
|
||||
assertThat(response.getName().get(0).getFamily().get(0).getValue(), StringContains.containsString("Cardinal"));
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count++).getURI().toString());
|
||||
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
response = (Patient) client.read().resource("Patient").withId("1234").execute();
|
||||
assertThat(response.getName().get(0).getFamily().get(0).getValue(), StringContains.containsString("Cardinal"));
|
||||
assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count++).getURI().toString());
|
||||
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
response = client.read().resource(Patient.class).withIdAndVersion("1234", "22").execute();
|
||||
assertThat(response.getName().get(0).getFamily().get(0).getValue(), StringContains.containsString("Cardinal"));
|
||||
assertEquals("http://example.com/fhir/Patient/1234/_history/22", capt.getAllValues().get(count++).getURI().toString());
|
||||
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
response = client.read().resource(Patient.class).withUrl("http://foo/Patient/22").execute();
|
||||
assertThat(response.getName().get(0).getFamily().get(0).getValue(), StringContains.containsString("Cardinal"));
|
||||
assertEquals("http://foo/Patient/22", capt.getAllValues().get(count++).getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = new FhirContext();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,813 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
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.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.IdType;
|
||||
import org.hl7.fhir.instance.model.Parameters;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.gclient.StringClientParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
|
||||
public class GenericClientDstu2Hl7OrgTest {
|
||||
private static FhirContext ourCtx;
|
||||
private HttpClient myHttpClient;
|
||||
private HttpResponse myHttpResponse;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = FhirContext.forDstu2Hl7Org();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
|
||||
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchWithReverseInclude() throws Exception {
|
||||
|
||||
String msg = getPatientFeedWithOneResult();
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
//@formatter:off
|
||||
org.hl7.fhir.instance.model.Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.encodedJson()
|
||||
.revInclude(new Include("Provenance:target"))
|
||||
.returnBundle(org.hl7.fhir.instance.model.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals(
|
||||
"http://example.com/fhir/Patient?_revinclude=Provenance%3Atarget&_format=json",
|
||||
capt.getValue().getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String getPatientFeedWithOneResult() {
|
||||
//@formatter:off
|
||||
String msg = "<Bundle xmlns=\"http://hl7.org/fhir\">\n" +
|
||||
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
|
||||
"<entry>\n" +
|
||||
"<resource>"
|
||||
+ "<Patient>"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
|
||||
+ "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
|
||||
+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
|
||||
+ "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>"
|
||||
+ "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>"
|
||||
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
|
||||
+ "</Patient>"
|
||||
+ "</resource>\n"
|
||||
+ " </entry>\n"
|
||||
+ "</Bundle>";
|
||||
//@formatter:on
|
||||
return msg;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHistory() throws Exception {
|
||||
|
||||
final String msg = getPatientFeedWithOneResult();
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(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;
|
||||
org.hl7.fhir.instance.model.Bundle response;
|
||||
|
||||
//@formatter:off
|
||||
response = client
|
||||
.history()
|
||||
.onServer()
|
||||
.andReturnBundle(org.hl7.fhir.instance.model.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/_history", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals(1, response.getEntry().size());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
response = client
|
||||
.history()
|
||||
.onType(Patient.class)
|
||||
.andReturnBundle(org.hl7.fhir.instance.model.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/_history", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals(1, response.getEntry().size());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
response = client
|
||||
.history()
|
||||
.onInstance(new IdType("Patient", "123"))
|
||||
.andReturnBundle(org.hl7.fhir.instance.model.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/_history", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals(1, response.getEntry().size());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByString() throws Exception {
|
||||
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()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
//@formatter:off
|
||||
org.hl7.fhir.instance.model.Bundle response = client.search()
|
||||
.forResource("Patient")
|
||||
.where(new StringClientParam("name").matches().value("james"))
|
||||
.returnBundle(org.hl7.fhir.instance.model.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient?name=james", capt.getValue().getURI().toString());
|
||||
assertEquals(Patient.class, response.getEntry().get(0).getResource().getClass());
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchRequiresBundleType() {
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
try {
|
||||
//@formatter:off
|
||||
Bundle response = client.search()
|
||||
.forResource("Patient")
|
||||
.where(new StringClientParam("name").matches().value("james"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithListOfParameterResponse() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setValue(new StringType("STRINGVALIN1"));
|
||||
inParams.addParameter().setValue(new StringType("STRINGVALIN2"));
|
||||
String reqString = p.encodeResourceToString(inParams);
|
||||
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT1"));
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT2"));
|
||||
final String respString = p.encodeResourceToString(outParams);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
Parameters resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams).execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(extractBody(capt, idx), reqString);
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onType(Patient.class)
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams).execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(extractBody(capt, idx), reqString);
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onInstance(new IdType("Patient", "123"))
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams).execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(extractBody(capt, idx), reqString);
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
resp = client.operation().onInstance(new IdType("http://foo.com/bar/baz/Patient/123/_history/22")).named("$SOMEOPERATION").withParameters(inParams).execute();
|
||||
// @formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithNoInParameters() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Parameters inParams = new Parameters();
|
||||
final String reqString = p.encodeResourceToString(inParams);
|
||||
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT1"));
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT2"));
|
||||
final String respString = p.encodeResourceToString(outParams);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
Parameters resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class).execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(extractBody(capt, idx), reqString);
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onType(Patient.class)
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class).execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(extractBody(capt, idx), reqString);
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onInstance(new IdType("Patient", "123"))
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class).execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(extractBody(capt, idx), reqString);
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
// @formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onInstance(new IdType("http://foo.com/bar/baz/Patient/123/_history/22"))
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class)
|
||||
.execute();
|
||||
// @formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationAsGetWithNoInParameters() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT1"));
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT2"));
|
||||
final String respString = p.encodeResourceToString(outParams);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
Parameters resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals("GET", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onType(Patient.class)
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals("GET", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onInstance(new IdType("Patient", "123"))
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals("GET", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
// @formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onInstance(new IdType("http://foo.com/bar/baz/Patient/123/_history/22"))
|
||||
.named("$SOMEOPERATION")
|
||||
.withNoParameters(Parameters.class)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
// @formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationAsGetWithInParameters() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("param1").setValue(new StringType("STRINGVALIN1"));
|
||||
inParams.addParameter().setName("param1").setValue(new StringType("STRINGVALIN1b"));
|
||||
inParams.addParameter().setName("param2").setValue(new StringType("STRINGVALIN2"));
|
||||
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT1"));
|
||||
outParams.addParameter().setValue(new StringType("STRINGVALOUT2"));
|
||||
final String respString = p.encodeResourceToString(outParams);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
Parameters resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION?param1=STRINGVALIN1¶m1=STRINGVALIN1b¶m2=STRINGVALIN2", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals("GET", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onType(Patient.class)
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/$SOMEOPERATION?param1=STRINGVALIN1¶m1=STRINGVALIN1b¶m2=STRINGVALIN2", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals("GET", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onInstance(new IdType("Patient", "123"))
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION?param1=STRINGVALIN1¶m1=STRINGVALIN1b¶m2=STRINGVALIN2", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals("GET", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
// @formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onInstance(new IdType("http://foo.com/bar/baz/Patient/123/_history/22"))
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams)
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
// @formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION?param1=STRINGVALIN1¶m1=STRINGVALIN1b¶m2=STRINGVALIN2", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithBundleResponse() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setValue(new StringType("STRINGVALIN1"));
|
||||
inParams.addParameter().setValue(new StringType("STRINGVALIN2"));
|
||||
String reqString = p.encodeResourceToString(inParams);
|
||||
|
||||
org.hl7.fhir.instance.model.Bundle outParams = new org.hl7.fhir.instance.model.Bundle();
|
||||
outParams.setTotal(123);
|
||||
final String respString = p.encodeResourceToString(outParams);
|
||||
|
||||
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_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
Parameters resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameters(inParams).execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals(extractBody(capt, idx), reqString);
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals(1, resp.getParameter().size());
|
||||
assertEquals(org.hl7.fhir.instance.model.Bundle.class, resp.getParameter().get(0).getResource().getClass());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionWithListOfResources() throws Exception {
|
||||
|
||||
org.hl7.fhir.instance.model.Bundle resp = new org.hl7.fhir.instance.model.Bundle();
|
||||
resp.addEntry().getTransactionResponse().setLocation("Patient/1/_history/1");
|
||||
resp.addEntry().getTransactionResponse().setLocation("Patient/2/_history/2");
|
||||
String respString = ourCtx.newJsonParser().encodeResourceToString(resp);
|
||||
|
||||
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()).thenReturn(new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
List<IBaseResource> input = new ArrayList<IBaseResource>();
|
||||
|
||||
Patient p1 = new Patient(); // No ID
|
||||
p1.addName().addFamily("PATIENT1");
|
||||
input.add(p1);
|
||||
|
||||
Patient p2 = new Patient(); // Yes ID
|
||||
p2.addName().addFamily("PATIENT2");
|
||||
p2.setId("Patient/2");
|
||||
input.add(p2);
|
||||
|
||||
//@formatter:off
|
||||
List<IBaseResource> response = client.transaction()
|
||||
.withResources(input)
|
||||
.encodedJson()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir?_format=json", capt.getValue().getURI().toString());
|
||||
assertEquals(2, response.size());
|
||||
|
||||
String requestString = IOUtils.toString(((HttpEntityEnclosingRequest) capt.getValue()).getEntity().getContent());
|
||||
org.hl7.fhir.instance.model.Bundle requestBundle = ourCtx.newJsonParser().parseResource(org.hl7.fhir.instance.model.Bundle.class, requestString);
|
||||
assertEquals(2, requestBundle.getEntry().size());
|
||||
assertEquals("POST", requestBundle.getEntry().get(0).getTransaction().getMethod().name());
|
||||
assertEquals("PUT", requestBundle.getEntry().get(1).getTransaction().getMethod().name());
|
||||
assertEquals("Patient/2", requestBundle.getEntry().get(1).getTransaction().getUrl());
|
||||
|
||||
p1 = (Patient) response.get(0);
|
||||
assertEquals(new IdType("Patient/1/_history/1"), p1.getId().toUnqualified());
|
||||
// assertEquals("PATIENT1", p1.getName().get(0).getFamily().get(0).getValue());
|
||||
|
||||
p2 = (Patient) response.get(1);
|
||||
assertEquals(new IdType("Patient/2/_history/2"), p2.getId().toUnqualified());
|
||||
// assertEquals("PATIENT2", p2.getName().get(0).getFamily().get(0).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionWithTransactionResource() throws Exception {
|
||||
|
||||
org.hl7.fhir.instance.model.Bundle resp = new org.hl7.fhir.instance.model.Bundle();
|
||||
resp.addEntry().getTransactionResponse().setLocation("Patient/1/_history/1");
|
||||
resp.addEntry().getTransactionResponse().setLocation("Patient/2/_history/2");
|
||||
String respString = ourCtx.newJsonParser().encodeResourceToString(resp);
|
||||
|
||||
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()).thenReturn(new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")));
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
org.hl7.fhir.instance.model.Bundle input = new org.hl7.fhir.instance.model.Bundle();
|
||||
|
||||
Patient p1 = new Patient(); // No ID
|
||||
p1.addName().addFamily("PATIENT1");
|
||||
input.addEntry().setResource(p1);
|
||||
|
||||
Patient p2 = new Patient(); // Yes ID
|
||||
p2.addName().addFamily("PATIENT2");
|
||||
p2.setId("Patient/2");
|
||||
input.addEntry().setResource(p2);
|
||||
|
||||
//@formatter:off
|
||||
org.hl7.fhir.instance.model.Bundle response = client.transaction()
|
||||
.withBundle(input)
|
||||
.encodedJson()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir?_format=json", capt.getValue().getURI().toString());
|
||||
assertEquals(2, response.getEntry().size());
|
||||
|
||||
assertEquals("Patient/1/_history/1", response.getEntry().get(0).getTransactionResponse().getLocation());
|
||||
assertEquals("Patient/2/_history/2", response.getEntry().get(1).getTransactionResponse().getLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteConditional() throws Exception {
|
||||
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), Constants.STATUS_HTTP_204_NO_CONTENT, ""));
|
||||
// when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type",
|
||||
// Constants.CT_TEXT + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
client.delete().resourceById(new IdType("Patient/123")).execute();
|
||||
assertEquals("DELETE", capt.getAllValues().get(idx).getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
client.delete().resourceConditionalByUrl("Patient?name=foo").execute();
|
||||
assertEquals("DELETE", capt.getAllValues().get(idx).getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
client.delete().resourceConditionalByType("Patient").where(new StringClientParam("name").matches().value("foo")).execute();
|
||||
assertEquals("DELETE", capt.getAllValues().get(idx).getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConditional() throws Exception {
|
||||
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), Constants.STATUS_HTTP_204_NO_CONTENT, ""));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
client.create().resource(p).conditionalByUrl("Patient?name=foo").execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_IF_NONE_EXIST).getValue());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
client.create().resource(p).conditional().where(new StringClientParam("name").matches().value("foo")).execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_IF_NONE_EXIST).getValue());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateConditional() throws Exception {
|
||||
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), Constants.STATUS_HTTP_204_NO_CONTENT, ""));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
client.update().resource(p).conditionalByUrl("Patient?name=foo").execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
client.update().resource(ourCtx.newXmlParser().encodeResourceToString(p)).conditionalByUrl("Patient?name=foo").execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
client.update().resource(p).conditional().where(new StringClientParam("name").matches().value("foo")).and(new StringClientParam("address").matches().value("AAA|BBB")).execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo&address=AAA%5C%7CBBB", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
client.update().resource(ourCtx.newXmlParser().encodeResourceToString(p)).conditional().where(new StringClientParam("name").matches().value("foo")).and(new StringClientParam("address").matches().value("AAA|BBB")).execute();
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient?name=foo&address=AAA%5C%7CBBB", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
private String extractBody(ArgumentCaptor<HttpUriRequest> capt, int count) throws IOException {
|
||||
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(count)).getEntity().getContent(), "UTF-8");
|
||||
return body;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,307 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.instance.model.Parameters;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
||||
public class OperationClientTest {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(OperationClientTest.class);
|
||||
private FhirContext ourCtx;
|
||||
private HttpClient ourHttpClient;
|
||||
|
||||
private HttpResponse ourHttpResponse;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ourCtx = FhirContext.forDstu2Hl7Org();
|
||||
|
||||
ourHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ourCtx.getRestfulClientFactory().setHttpClient(ourHttpClient);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
|
||||
|
||||
ourHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpInstance() throws Exception {
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setName("FOO");
|
||||
final String retVal = ourCtx.newXmlParser().encodeResourceToString(outParams);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse);
|
||||
when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IOpClient client = ourCtx.newRestfulClient(IOpClient.class, "http://foo");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Parameters response = client.opInstance(new IdDt("222"), new StringType("PARAM1str"), new Patient().setActive(true));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
HttpPost value = (HttpPost) capt.getAllValues().get(idx);
|
||||
String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/Patient/222/$OP_INSTANCE", value.getURI().toASCIIString());
|
||||
assertEquals(2, request.getParameter().size());
|
||||
assertEquals("PARAM1", request.getParameter().get(0).getName());
|
||||
assertEquals("PARAM1str", ((StringType) request.getParameter().get(0).getValue()).getValue());
|
||||
assertEquals("PARAM2", request.getParameter().get(1).getName());
|
||||
assertEquals(Boolean.TRUE, ((Patient) request.getParameter().get(1).getResource()).getActive());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpServer() throws Exception {
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setName("FOO");
|
||||
final String retVal = ourCtx.newXmlParser().encodeResourceToString(outParams);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse);
|
||||
when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IOpClient client = ourCtx.newRestfulClient(IOpClient.class, "http://foo");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Parameters response = client.opServer(new StringType("PARAM1str"), new Patient().setActive(true));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
HttpPost value = (HttpPost) capt.getAllValues().get(idx);
|
||||
String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/$OP_SERVER", value.getURI().toASCIIString());
|
||||
assertEquals(2, request.getParameter().size());
|
||||
assertEquals("PARAM1", request.getParameter().get(0).getName());
|
||||
assertEquals("PARAM1str", ((StringType) request.getParameter().get(0).getValue()).getValue());
|
||||
assertEquals("PARAM2", request.getParameter().get(1).getName());
|
||||
assertEquals(Boolean.TRUE, ((Patient) request.getParameter().get(1).getResource()).getActive());
|
||||
idx++;
|
||||
|
||||
response = client.opServer(null, new Patient().setActive(true));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
value = (HttpPost) capt.getAllValues().get(idx);
|
||||
requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals(1, request.getParameter().size());
|
||||
assertEquals("PARAM2", request.getParameter().get(0).getName());
|
||||
assertEquals(Boolean.TRUE, ((Patient) request.getParameter().get(0).getResource()).getActive());
|
||||
idx++;
|
||||
|
||||
response = client.opServer(null, null);
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
value = (HttpPost) capt.getAllValues().get(idx);
|
||||
requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals(0, request.getParameter().size());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpWithListParam() throws Exception {
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setName("FOO");
|
||||
final String retVal = ourCtx.newXmlParser().encodeResourceToString(outParams);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse);
|
||||
when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IOpClient client = ourCtx.newRestfulClient(IOpClient.class, "http://foo");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Parameters response = client.opServerListParam(new Patient().setActive(true), Arrays.asList(new StringType("PARAM3str1"), new StringType("PARAM3str2")));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
HttpPost value = (HttpPost) capt.getAllValues().get(idx);
|
||||
String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/$OP_SERVER_LIST_PARAM", value.getURI().toASCIIString());
|
||||
assertEquals(3, request.getParameter().size());
|
||||
assertEquals("PARAM2", request.getParameter().get(0).getName());
|
||||
assertEquals(Boolean.TRUE, ((Patient) request.getParameter().get(0).getResource()).getActive());
|
||||
assertEquals("PARAM3", request.getParameter().get(1).getName());
|
||||
assertEquals("PARAM3str1", ((StringType) request.getParameter().get(1).getValue()).getValue());
|
||||
assertEquals("PARAM3", request.getParameter().get(2).getName());
|
||||
assertEquals("PARAM3str2", ((StringType) request.getParameter().get(2).getValue()).getValue());
|
||||
idx++;
|
||||
|
||||
response = client.opServerListParam(null, Arrays.asList(new StringType("PARAM3str1"), new StringType("PARAM3str2")));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
value = (HttpPost) capt.getAllValues().get(idx);
|
||||
requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/$OP_SERVER_LIST_PARAM", value.getURI().toASCIIString());
|
||||
assertEquals(2, request.getParameter().size());
|
||||
assertEquals("PARAM3", request.getParameter().get(0).getName());
|
||||
assertEquals("PARAM3str1", ((StringType) request.getParameter().get(0).getValue()).getValue());
|
||||
assertEquals("PARAM3", request.getParameter().get(1).getName());
|
||||
assertEquals("PARAM3str2", ((StringType) request.getParameter().get(1).getValue()).getValue());
|
||||
idx++;
|
||||
|
||||
response = client.opServerListParam(null, new ArrayList<StringType>());
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
value = (HttpPost) capt.getAllValues().get(idx);
|
||||
requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/$OP_SERVER_LIST_PARAM", value.getURI().toASCIIString());
|
||||
assertEquals(0, request.getParameter().size());
|
||||
idx++;
|
||||
|
||||
response = client.opServerListParam(null, null);
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
value = (HttpPost) capt.getAllValues().get(idx);
|
||||
requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/$OP_SERVER_LIST_PARAM", value.getURI().toASCIIString());
|
||||
assertEquals(0, request.getParameter().size());
|
||||
idx++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpType() throws Exception {
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setName("FOO");
|
||||
final String retVal = ourCtx.newXmlParser().encodeResourceToString(outParams);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse);
|
||||
when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IOpClient client = ourCtx.newRestfulClient(IOpClient.class, "http://foo");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Parameters response = client.opType(new StringType("PARAM1str"), new Patient().setActive(true));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
HttpPost value = (HttpPost) capt.getAllValues().get(idx);
|
||||
String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent());
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/Patient/$OP_TYPE", value.getURI().toASCIIString());
|
||||
assertEquals(2, request.getParameter().size());
|
||||
assertEquals("PARAM1", request.getParameter().get(0).getName());
|
||||
assertEquals("PARAM1str", ((StringType) request.getParameter().get(0).getValue()).getValue());
|
||||
assertEquals("PARAM2", request.getParameter().get(1).getName());
|
||||
assertEquals(Boolean.TRUE, ((Patient) request.getParameter().get(1).getResource()).getActive());
|
||||
idx++;
|
||||
}
|
||||
|
||||
public interface IOpClient extends IBasicClient {
|
||||
//@formatter:off
|
||||
@Operation(name="$OP_INSTANCE", type=Patient.class)
|
||||
public Parameters opInstance(
|
||||
@IdParam IdDt theId,
|
||||
@OperationParam(name="PARAM1") StringType theParam1,
|
||||
@OperationParam(name="PARAM2") Patient theParam2
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name="$OP_SERVER")
|
||||
public Parameters opServer(
|
||||
@OperationParam(name="PARAM1") StringType theParam1,
|
||||
@OperationParam(name="PARAM2") Patient theParam2
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name="$OP_SERVER_LIST_PARAM")
|
||||
public Parameters opServerListParam(
|
||||
@OperationParam(name="PARAM2") Patient theParam2,
|
||||
@OperationParam(name="PARAM3") List<StringType> theParam3
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name="$OP_TYPE", type=Patient.class)
|
||||
public Parameters opType(
|
||||
@OperationParam(name="PARAM1") StringType theParam1,
|
||||
@OperationParam(name="PARAM2") Patient theParam2
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
}
|
||||
}
|
|
@ -1,127 +1 @@
|
|||
/target/
|
||||
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
|
||||
|
||||
### Vim ###
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
||||
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
.gradle
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
/build/
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>hapi-fhir-testpage-overlay</name>
|
||||
<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>hapi-fhir-jpaserver-base</project>
|
||||
<project>hapi-fhir-jpaserver-test</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
|
@ -13,12 +11,12 @@
|
|||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
|
@ -34,11 +32,11 @@
|
|||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
|
|
@ -78,12 +78,13 @@ SPAN.headerValue {
|
|||
}
|
||||
|
||||
SPAN.includeCheckContainer {
|
||||
margin-top: 6px;
|
||||
margin-bottom: 6px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
margin-right: 0px;
|
||||
margin-left: 15px;
|
||||
margin-left: 2px;
|
||||
white-space: nowrap;
|
||||
line-height: 35px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
SPAN.includeCheckCheck {
|
||||
|
|
|
@ -106,7 +106,6 @@ public class DatatypeGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP
|
|||
retVal.add(("/dt/" + version + "/attachment.xml"));
|
||||
retVal.add(("/dt/" + version + "/contactpoint.xml"));
|
||||
retVal.add(("/dt/" + version + "/elementdefinition.xml"));
|
||||
retVal.add(("/dt/" + version + "/reference.xml"));
|
||||
retVal.add(("/dt/" + version + "/timing.xml"));
|
||||
retVal.add(("/dt/" + version + "/signature.xml"));
|
||||
}
|
||||
|
|
|
@ -130,6 +130,12 @@
|
|||
JPA server failed to index resources containing ContactPointDt elements with
|
||||
populated values (e.g. Patient.telecom). Thanks to Mohammad Jafari for reporting!
|
||||
</action>
|
||||
<action type="add">
|
||||
Add a new configuration method on the parsers,
|
||||
<![CDATA[<code>setStripVersionsFromReferences(boolean)</code>]]> which
|
||||
configures the parser to preserve versions in resource reference links when
|
||||
encoding. By default, these are removed.
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.9" date="2015-Mar-14">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue