Credit for #120
This commit is contained in:
parent
18f1c579ab
commit
1a4a23bdc5
|
@ -0,0 +1,58 @@
|
|||
package example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.provider.dstu2.Dstu2BundleFactory;
|
||||
|
||||
public class IncludesExamples {
|
||||
|
||||
public static void main(String[] args) {
|
||||
testSearchForPatients();
|
||||
}
|
||||
|
||||
private static void testSearchForPatients() {
|
||||
List<IResource> resources = new IncludesExamples().searchForPatients();
|
||||
|
||||
// Create a bundle with both
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
Dstu2BundleFactory bf = new Dstu2BundleFactory(ctx);
|
||||
bf.initializeBundleFromResourceList(null, resources, "http://example.com/base", "http://example.com/base/Patient", 1, BundleTypeEnum.SEARCHSET);
|
||||
IBaseResource b = bf.getResourceBundle();
|
||||
|
||||
// Encode the bundle
|
||||
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
|
||||
System.out.println(encoded);
|
||||
}
|
||||
|
||||
// START SNIPPET: addIncludes
|
||||
@Search
|
||||
private List<IResource> searchForPatients() {
|
||||
// Create an organization
|
||||
Organization org = new Organization();
|
||||
org.setId("Organization/65546");
|
||||
org.setName("Test Organization");
|
||||
|
||||
// Create a patient
|
||||
Patient patient = new Patient();
|
||||
patient.setId("Patient/1333");
|
||||
patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
|
||||
patient.getManagingOrganization().setResource(org);
|
||||
|
||||
// Here we return only the patient object, which has links to other resources
|
||||
List<IResource> retVal = new ArrayList<IResource>();
|
||||
retVal.add(patient);
|
||||
return retVal;
|
||||
}
|
||||
// END SNIPPET: addIncludes
|
||||
|
||||
}
|
|
@ -20,18 +20,15 @@ package ca.uhn.fhir.context;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -68,7 +65,6 @@ import ca.uhn.fhir.model.api.IBoundCodeableConcept;
|
|||
import ca.uhn.fhir.model.api.ICodeEnum;
|
||||
import ca.uhn.fhir.model.api.IDatatype;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.IResourceBlock;
|
||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||
|
@ -236,34 +232,23 @@ class ModelScanner {
|
|||
// Below disabled for now due to performance issues
|
||||
|
||||
/*
|
||||
if (retVal == null) {
|
||||
String sourceClassName = theAnnotationType.getName();
|
||||
String candidateAltClassName = sourceClassName.replace("ca.uhn.fhir.model.api.annotation", "org.hl7.fhir.instance.model.annotations");
|
||||
|
||||
if (!sourceClassName.equals(candidateAltClassName)) {
|
||||
try {
|
||||
final Class<? extends Annotation> altAnnotationClass = (Class<? extends Annotation>) Class.forName(candidateAltClassName);
|
||||
final Annotation altAnnotation = theTarget.getAnnotation(altAnnotationClass);
|
||||
if (altAnnotation == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ourLog.debug("Forwarding annotation request for [{}] to class [{}]", sourceClassName, candidateAltClassName);
|
||||
|
||||
InvocationHandler h = new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
|
||||
Method altMethod = altAnnotationClass.getMethod(theMethod.getName(), theMethod.getParameterTypes());
|
||||
return altMethod.invoke(altAnnotation, theArgs);
|
||||
}
|
||||
};
|
||||
retVal = (T) Proxy.newProxyInstance(theAnnotationType.getClassLoader(), new Class<?>[] { theAnnotationType }, h);
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
* if (retVal == null) { String sourceClassName = theAnnotationType.getName(); String candidateAltClassName =
|
||||
* sourceClassName.replace("ca.uhn.fhir.model.api.annotation", "org.hl7.fhir.instance.model.annotations");
|
||||
*
|
||||
* if (!sourceClassName.equals(candidateAltClassName)) { try { final Class<? extends Annotation>
|
||||
* altAnnotationClass = (Class<? extends Annotation>) Class.forName(candidateAltClassName); final Annotation
|
||||
* altAnnotation = theTarget.getAnnotation(altAnnotationClass); if (altAnnotation == null) { return null; }
|
||||
*
|
||||
* ourLog.debug("Forwarding annotation request for [{}] to class [{}]", sourceClassName, candidateAltClassName);
|
||||
*
|
||||
* InvocationHandler h = new InvocationHandler() {
|
||||
*
|
||||
* @Override public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable { Method
|
||||
* altMethod = altAnnotationClass.getMethod(theMethod.getName(), theMethod.getParameterTypes()); return
|
||||
* altMethod.invoke(altAnnotation, theArgs); } }; retVal = (T)
|
||||
* Proxy.newProxyInstance(theAnnotationType.getClassLoader(), new Class<?>[] { theAnnotationType }, h);
|
||||
*
|
||||
* } catch (ClassNotFoundException e) { return null; } } }
|
||||
*/
|
||||
|
||||
return retVal;
|
||||
|
@ -534,7 +519,13 @@ class ModelScanner {
|
|||
* Child is an extension
|
||||
*/
|
||||
Class<? extends IBase> et = (Class<? extends IBase>) nextElementType;
|
||||
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et);
|
||||
|
||||
IValueSetEnumBinder<Enum<?>> binder = null;
|
||||
if (BoundCodeDt.class.isAssignableFrom(nextElementType) || IBoundCodeableConcept.class.isAssignableFrom(nextElementType)) {
|
||||
binder = getBoundCodeBinder(next);
|
||||
}
|
||||
|
||||
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et, binder);
|
||||
orderMap.put(order, def);
|
||||
if (IElement.class.isAssignableFrom(nextElementType)) {
|
||||
addScanAlso((Class<? extends IElement>) nextElementType);
|
||||
|
@ -570,7 +561,8 @@ class ModelScanner {
|
|||
RuntimeChildAny def = new RuntimeChildAny(next, elementName, childAnnotation, descriptionAnnotation);
|
||||
orderMap.put(order, def);
|
||||
|
||||
} else if (IDatatype.class.isAssignableFrom(nextElementType) || IPrimitiveType.class.isAssignableFrom(nextElementType) || ICompositeType.class.isAssignableFrom(nextElementType) || IBaseDatatype.class.isAssignableFrom(nextElementType) || IBaseExtension.class.isAssignableFrom(nextElementType)) {
|
||||
} else if (IDatatype.class.isAssignableFrom(nextElementType) || IPrimitiveType.class.isAssignableFrom(nextElementType) || ICompositeType.class.isAssignableFrom(nextElementType) || IBaseDatatype.class.isAssignableFrom(nextElementType)
|
||||
|| IBaseExtension.class.isAssignableFrom(nextElementType)) {
|
||||
Class<? extends IBase> nextDatatype = (Class<? extends IBase>) nextElementType;
|
||||
|
||||
addScanAlso(nextDatatype);
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hl7.fhir.instance.model.IBase;
|
|||
import org.hl7.fhir.instance.model.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
|
@ -47,17 +48,29 @@ public class RuntimeChildDeclaredExtensionDefinition extends BaseRuntimeDeclared
|
|||
private String myExtensionUrl;
|
||||
private boolean myModifier;
|
||||
private Map<String, RuntimeChildDeclaredExtensionDefinition> myUrlToChildExtension;
|
||||
private Object myInstanceConstructorArguments;
|
||||
|
||||
/**
|
||||
* @param theDefinedLocally See {@link Extension#definedLocally()}
|
||||
* @param theBoundTypeBinder
|
||||
* If the child is of a type that requires a constructor argument to instantiate, this is the argument to
|
||||
* use
|
||||
* @param theDefinedLocally
|
||||
* See {@link Extension#definedLocally()}
|
||||
*/
|
||||
RuntimeChildDeclaredExtensionDefinition(Field theField, Child theChild, Description theDescriptionAnnotation, Extension theExtension, String theElementName, String theExtensionUrl, Class<? extends IBase> theChildType) throws ConfigurationException {
|
||||
RuntimeChildDeclaredExtensionDefinition(Field theField, Child theChild, Description theDescriptionAnnotation, Extension theExtension, String theElementName, String theExtensionUrl, Class<? extends IBase> theChildType, IValueSetEnumBinder<Enum<?>> theBoundTypeBinder)
|
||||
throws ConfigurationException {
|
||||
super(theField, theChild, theDescriptionAnnotation, theElementName);
|
||||
assert isNotBlank(theExtensionUrl);
|
||||
myExtensionUrl = theExtensionUrl;
|
||||
myChildType = theChildType;
|
||||
myDefinedLocally = theExtension.definedLocally();
|
||||
myModifier = theExtension.isModifier();
|
||||
myInstanceConstructorArguments = theBoundTypeBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInstanceConstructorArguments() {
|
||||
return myInstanceConstructorArguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.lang.reflect.Field;
|
|||
|
||||
import org.hl7.fhir.instance.model.IBase;
|
||||
|
||||
import ca.uhn.fhir.model.api.IDatatype;
|
||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
|
|
|
@ -1395,7 +1395,7 @@ class ParserState<T> {
|
|||
switch (target.getChildType()) {
|
||||
case COMPOSITE_DATATYPE: {
|
||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance();
|
||||
ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(myPreResourceState, compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
|
@ -1403,7 +1403,7 @@ class ParserState<T> {
|
|||
}
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
|
||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
|
||||
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
|
||||
push(newState);
|
||||
|
@ -1458,12 +1458,12 @@ class ParserState<T> {
|
|||
return newState;
|
||||
}
|
||||
|
||||
private class ElementCompositeState<T2 extends IBase> extends BaseState {
|
||||
private class ElementCompositeState extends BaseState {
|
||||
|
||||
private BaseRuntimeElementCompositeDefinition<?> myDefinition;
|
||||
private T2 myInstance;
|
||||
private IBase myInstance;
|
||||
|
||||
public ElementCompositeState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, T2 theInstance) {
|
||||
public ElementCompositeState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IBase theInstance) {
|
||||
super(thePreResourceState);
|
||||
myDefinition = theDef;
|
||||
myInstance = theInstance;
|
||||
|
@ -1516,7 +1516,7 @@ class ParserState<T> {
|
|||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(child.getInstanceConstructorArguments());
|
||||
child.getMutator().addValue(myInstance, newChildInstance);
|
||||
ParserState<T>.ElementCompositeState<ICompositeType> newState = new ElementCompositeState<ICompositeType>(getPreResourceState(), compositeTarget, newChildInstance);
|
||||
ParserState<T>.ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
|
@ -1540,7 +1540,7 @@ class ParserState<T> {
|
|||
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
|
||||
IBase newBlockInstance = blockTarget.newInstance();
|
||||
child.getMutator().addValue(myInstance, newBlockInstance);
|
||||
ElementCompositeState<IBase> newState = new ElementCompositeState<IBase>(getPreResourceState(), blockTarget, newBlockInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), blockTarget, newBlockInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
|
@ -1592,7 +1592,7 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected T2 getCurrentElement() {
|
||||
protected IBase getCurrentElement() {
|
||||
return myInstance;
|
||||
}
|
||||
|
||||
|
@ -1627,7 +1627,7 @@ class ParserState<T> {
|
|||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||
ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance();
|
||||
myExtension.setValue(newChildInstance);
|
||||
ElementCompositeState<IBase> newState = new ElementCompositeState<IBase>(getPreResourceState(), compositeTarget, newChildInstance);
|
||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
|
||||
push(newState);
|
||||
return;
|
||||
}
|
||||
|
@ -1664,7 +1664,7 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
|
||||
private class SecurityLabelElementStateHapi extends ElementCompositeState<BaseCodingDt> {
|
||||
private class SecurityLabelElementStateHapi extends ElementCompositeState {
|
||||
|
||||
public SecurityLabelElementStateHapi(ParserState<T>.PreResourceState thePreResourceState,BaseRuntimeElementCompositeDefinition<?> theDef, BaseCodingDt codingDt) {
|
||||
super(thePreResourceState, theDef, codingDt);
|
||||
|
@ -2224,18 +2224,21 @@ class ParserState<T> {
|
|||
DISPLAY, INITIAL, REFERENCE
|
||||
}
|
||||
|
||||
private class ResourceStateHapi extends ElementCompositeState<IResource> {
|
||||
private class ResourceStateHapi extends ElementCompositeState {
|
||||
|
||||
private IResource myInstance;
|
||||
|
||||
public ResourceStateHapi(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IResource theInstance) {
|
||||
super(thePreResourceState, theDef, theInstance);
|
||||
myInstance = theInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enteringNewElement(String theNamespace, String theChildName) throws DataFormatException {
|
||||
if ("id".equals(theChildName)) {
|
||||
push(new PrimitiveState(getPreResourceState(), getCurrentElement().getId()));
|
||||
push(new PrimitiveState(getPreResourceState(), myInstance.getId()));
|
||||
} else if ("meta".equals(theChildName)) {
|
||||
push(new MetaElementState(getPreResourceState(), getCurrentElement().getResourceMetadata()));
|
||||
push(new MetaElementState(getPreResourceState(), myInstance.getResourceMetadata()));
|
||||
} else {
|
||||
super.enteringNewElement(theNamespace, theChildName);
|
||||
}
|
||||
|
@ -2243,7 +2246,7 @@ class ParserState<T> {
|
|||
|
||||
}
|
||||
|
||||
private class ResourceStateHl7Org extends ElementCompositeState<IBaseResource> {
|
||||
private class ResourceStateHl7Org extends ElementCompositeState {
|
||||
|
||||
public ResourceStateHl7Org(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IBaseResource theInstance) {
|
||||
super(thePreResourceState, theDef, theInstance);
|
||||
|
|
|
@ -77,6 +77,7 @@ public class RestfulServer extends HttpServlet {
|
|||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private AddProfileTagEnum myAddProfileTag;
|
||||
private BundleInclusionRule myBundleInclusionRule = BundleInclusionRule.BASED_ON_INCLUDES;
|
||||
private EncodingEnum myDefaultResponseEncoding = EncodingEnum.XML;
|
||||
private ETagSupportEnum myETagSupport = DEFAULT_ETAG_SUPPORT;
|
||||
private FhirContext myFhirContext;
|
||||
|
@ -87,12 +88,13 @@ public class RestfulServer extends HttpServlet {
|
|||
private Map<String, ResourceBinding> myResourceNameToProvider = new HashMap<String, ResourceBinding>();
|
||||
private Collection<IResourceProvider> myResourceProviders;
|
||||
private IServerAddressStrategy myServerAddressStrategy = new IncomingRequestAddressStrategy();
|
||||
private ResourceBinding myServerBinding = new ResourceBinding();
|
||||
private BaseMethodBinding<?> myServerConformanceMethod;
|
||||
private Object myServerConformanceProvider;
|
||||
private String myServerName = "HAPI FHIR Server";
|
||||
|
||||
/** This is configurable but by default we just use HAPI version */
|
||||
private String myServerVersion = VersionUtil.getVersion();
|
||||
private BundleInclusionRule myBundleInclusionRule = BundleInclusionRule.BASED_ON_INCLUDES;
|
||||
|
||||
private boolean myStarted;
|
||||
|
||||
|
@ -257,8 +259,6 @@ public class RestfulServer extends HttpServlet {
|
|||
|
||||
}
|
||||
|
||||
private ResourceBinding myServerBinding = new ResourceBinding();
|
||||
|
||||
private void findSystemMethods(Object theSystemProvider, Class<?> clazz) {
|
||||
Class<?> supertype = clazz.getSuperclass();
|
||||
if (!Object.class.equals(supertype)) {
|
||||
|
@ -293,6 +293,10 @@ public class RestfulServer extends HttpServlet {
|
|||
return myAddProfileTag;
|
||||
}
|
||||
|
||||
public BundleInclusionRule getBundleInclusionRule() {
|
||||
return myBundleInclusionRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default encoding to return (XML/JSON) if an incoming request does not specify a preference (either
|
||||
* with the <code>_format</code> URL parameter, or with an <code>Accept</code> header in the request. The default is
|
||||
|
@ -900,6 +904,15 @@ public class RestfulServer extends HttpServlet {
|
|||
myAddProfileTag = theAddProfileTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set how bundle factory should decide whether referenced resources should be included in bundles
|
||||
*
|
||||
* @param theBundleInclusionRule - inclusion rule (@see BundleInclusionRule for behaviors)
|
||||
*/
|
||||
public void setBundleInclusionRule(BundleInclusionRule theBundleInclusionRule) {
|
||||
myBundleInclusionRule = theBundleInclusionRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default encoding to return (XML/JSON) if an incoming request does not specify a preference (either with
|
||||
* the <code>_format</code> URL parameter, or with an <code>Accept</code> header in the request. The default is
|
||||
|
@ -1084,17 +1097,4 @@ public class RestfulServer extends HttpServlet {
|
|||
return valueOf(NarrativeModeEnum.class, theCode.toUpperCase());
|
||||
}
|
||||
}
|
||||
|
||||
public BundleInclusionRule getBundleInclusionRule() {
|
||||
return myBundleInclusionRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* set how bundle factory should decide whether referenced resources should be included in bundles
|
||||
*
|
||||
* @param theBundleInclusionRule - inclusion rule (@see BundleInclusionRule for behaviors)
|
||||
*/
|
||||
public void setBundleInclusionRule(BundleInclusionRule theBundleInclusionRule) {
|
||||
myBundleInclusionRule = theBundleInclusionRule;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package ca.uhn.fhir.parser;
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -138,4 +138,22 @@ public class BaseParserTest {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #120
|
||||
*/
|
||||
@Test
|
||||
public void testParseExtensionWithBoundCodeType() {
|
||||
//@formatter:off
|
||||
String resText =
|
||||
"<DiagnosticReport xmlns=\"http://hl7.org/fhir\">" +
|
||||
" <extension url=\"http://agfa.com/extensions#workflowAction\">" +
|
||||
" <valueCode value=\"sign-off\"/>" +
|
||||
" </extension>" +
|
||||
"</DiagnosticReport>";
|
||||
//@formatter:on
|
||||
|
||||
MyDiagnosticReportWithBoundCodeExtension res = ourCtx.newXmlParser().parseResource(MyDiagnosticReportWithBoundCodeExtension.class, resText);
|
||||
assertEquals(WorkflowActionEnum.SIGNOFF, res.getWorkflowAction().getValueAsEnum());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
/**
|
||||
* See #120
|
||||
*/
|
||||
@ResourceDef(name = "DiagnosticReport")
|
||||
public class MyDiagnosticReportWithBoundCodeExtension extends DiagnosticReport {
|
||||
|
||||
public static final String SP_IMAGING_STUDY = "ImagingStudy";
|
||||
|
||||
/**
|
||||
* Each extension is defined in a field. Any valid HAPI Data Type can be used for the field type. Note that the
|
||||
* [name=""] attribute in the @Child annotation needs to match the name for the bean accessor and mutator methods.
|
||||
*/
|
||||
// @Child(name = "taskId", order = 16)
|
||||
// @Extension(url = "http://agfa.com/extensions#taskId", definedLocally = true, isModifier = false)
|
||||
// @Description(shortDefinition = "The task id")
|
||||
private IntegerDt taskId;
|
||||
|
||||
@Child(name = "workflowAction", type = CodeDt.class, order = 17)
|
||||
@Extension(url = "http://agfa.com/extensions#workflowAction", definedLocally = true, isModifier = false)
|
||||
@Description(shortDefinition = "sign-off |sign-off-later |correctionist +", formalDefinition = "The work-flow action")
|
||||
private BoundCodeDt<WorkflowActionEnum> workflowAction;
|
||||
|
||||
// @Child(name = "workflowComments", order = 18)
|
||||
// @Extension(url = "http://agfa.com/extensions#workflowComments", definedLocally = true, isModifier = false)
|
||||
// @Description(shortDefinition = "The work-flow comments")
|
||||
private StringDt workflowComments;
|
||||
|
||||
/**
|
||||
* It is important to override the isEmpty() method, adding a check for any newly added fields.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(taskId, workflowAction, workflowComments);
|
||||
}
|
||||
|
||||
/********
|
||||
* Accessors and mutators follow
|
||||
*
|
||||
* IMPORTANT: Each extension is required to have an getter/accessor and a stter/mutator. You are highly recommended
|
||||
* to create getters which create instances if they do not already exist, since this is how the rest of the HAPI
|
||||
* FHIR API works.
|
||||
********/
|
||||
|
||||
/** Getter for mandatory */
|
||||
|
||||
public IntegerDt getTaskId() {
|
||||
if (taskId == null) {
|
||||
taskId = new IntegerDt();
|
||||
}
|
||||
return taskId;
|
||||
}
|
||||
|
||||
public MyDiagnosticReportWithBoundCodeExtension setTaskId(int taskId) {
|
||||
this.taskId = new IntegerDt(taskId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MyDiagnosticReportWithBoundCodeExtension setTaskId(IntegerDt taskId) {
|
||||
this.taskId = taskId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BoundCodeDt<WorkflowActionEnum> getWorkflowAction() {
|
||||
if (workflowAction == null) {
|
||||
workflowAction = new BoundCodeDt<WorkflowActionEnum>(WorkflowActionEnum.VALUESET_BINDER);
|
||||
}
|
||||
|
||||
return workflowAction;
|
||||
}
|
||||
|
||||
public MyDiagnosticReportWithBoundCodeExtension setWorkflowAction(BoundCodeDt<WorkflowActionEnum> workflowAction) {
|
||||
this.workflowAction = workflowAction;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public MyDiagnosticReportWithBoundCodeExtension setWorkflowAction(WorkflowActionEnum workflowAction) {
|
||||
getWorkflowAction().setValueAsEnum(workflowAction);
|
||||
return this;
|
||||
}
|
||||
|
||||
public StringDt getWorkflowComments() {
|
||||
if (workflowComments == null) {
|
||||
workflowComments = new StringDt();
|
||||
}
|
||||
return workflowComments;
|
||||
}
|
||||
|
||||
public MyDiagnosticReportWithBoundCodeExtension setWorkflowComments(StringDt workflowComments) {
|
||||
this.workflowComments = workflowComments;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MyDiagnosticReportWithBoundCodeExtension setWorkflowComments(String workflowComments) {
|
||||
this.workflowComments = new StringDt(workflowComments);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||
|
||||
/**
|
||||
* See #120
|
||||
*/
|
||||
public enum WorkflowActionEnum {
|
||||
|
||||
/**
|
||||
* Code Value: <b>sign-off</b>
|
||||
*
|
||||
* Sign off workflow action.
|
||||
*/
|
||||
SIGNOFF("sign-off","#workflow-action"),
|
||||
|
||||
/**
|
||||
* Code Value: <b>sign-off-later</b>
|
||||
*
|
||||
* Sign off later workflow action.
|
||||
*/
|
||||
SIGNOFFLATER("sign-off-later","#workflow-action"),
|
||||
|
||||
/**
|
||||
* Code Value: <b>correctionist</b>
|
||||
*
|
||||
* Correctionist workflow action.
|
||||
*/
|
||||
CORRECTIONIST("correctionist","#workflow-action");
|
||||
|
||||
/**
|
||||
* Identifier for this Value Set:
|
||||
* local/workflow-action
|
||||
*/
|
||||
public static final String VALUESET_IDENTIFIER = "#workflow-action";
|
||||
|
||||
/**
|
||||
* Name for this Value Set:
|
||||
* WorkflowAction
|
||||
*/
|
||||
public static final String VALUESET_NAME = "WorkflowAction";
|
||||
|
||||
private static Map<String, WorkflowActionEnum> CODE_TO_ENUM = new HashMap<String, WorkflowActionEnum>();
|
||||
private static Map<String, Map<String, WorkflowActionEnum>> SYSTEM_TO_CODE_TO_ENUM = new HashMap<String, Map<String, WorkflowActionEnum>>();
|
||||
|
||||
private final String myCode;
|
||||
private final String mySystem;
|
||||
|
||||
static {
|
||||
for (WorkflowActionEnum next : WorkflowActionEnum.values()) {
|
||||
CODE_TO_ENUM.put(next.getCode(), next);
|
||||
|
||||
if (!SYSTEM_TO_CODE_TO_ENUM.containsKey(next.getSystem())) {
|
||||
SYSTEM_TO_CODE_TO_ENUM.put(next.getSystem(), new HashMap<String, WorkflowActionEnum>());
|
||||
}
|
||||
SYSTEM_TO_CODE_TO_ENUM.get(next.getSystem()).put(next.getCode(), next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code associated with this enumerated value
|
||||
*/
|
||||
public String getCode() {
|
||||
return myCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code system associated with this enumerated value
|
||||
*/
|
||||
public String getSystem() {
|
||||
return mySystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the enumerated value associated with this code
|
||||
*/
|
||||
public WorkflowActionEnum forCode(String theCode) {
|
||||
WorkflowActionEnum retVal = CODE_TO_ENUM.get(theCode);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts codes to their respective enumerated values
|
||||
*/
|
||||
public static final IValueSetEnumBinder<WorkflowActionEnum> VALUESET_BINDER = new IValueSetEnumBinder<WorkflowActionEnum>() {
|
||||
@Override
|
||||
public String toCodeString(WorkflowActionEnum theEnum) {
|
||||
return theEnum.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSystemString(WorkflowActionEnum theEnum) {
|
||||
return theEnum.getSystem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkflowActionEnum fromCodeString(String theCodeString) {
|
||||
return CODE_TO_ENUM.get(theCodeString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorkflowActionEnum fromCodeString(String theCodeString, String theSystemString) {
|
||||
Map<String, WorkflowActionEnum> map = SYSTEM_TO_CODE_TO_ENUM.get(theSystemString);
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
return map.get(theCodeString);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
WorkflowActionEnum(String theCode, String theSystem){
|
||||
myCode = theCode;
|
||||
mySystem = theSystem;
|
||||
}
|
||||
|
||||
}
|
|
@ -8,8 +8,8 @@
|
|||
<body>
|
||||
<release version="0.9" date="TBA">
|
||||
<action type="add">
|
||||
Support for DSTU2 features introduced: New Bundle encoding style, as well as new
|
||||
extension encoding in JSON.
|
||||
Support for DSTU2 features introduced: New resource definitions, Bundle resource,
|
||||
encoding changes (ID in resource bodt, meta tag)
|
||||
</action>
|
||||
<action type="fix" issue="65">
|
||||
Fix an issue encoding extensions on primitive types in JSON. Previously the "_value" object
|
||||
|
@ -143,6 +143,16 @@
|
|||
DateClientParam.before() incorrectly placed "<=" instead of
|
||||
"<" in the request URL. Thanks to Ryan for reporting!
|
||||
</action>
|
||||
<action type="add" issue="77" dev="wdebeau1">
|
||||
Server now only automatically adds _include resources which are provided
|
||||
as references if the client request actually requested that specific include.
|
||||
See RestfulServer
|
||||
</action>
|
||||
<action type="fix" issue="120">
|
||||
User defined resource types which contain extensions that use a bound code type
|
||||
(e.g. an BoundCodeDt with a custom Enum) failed to parse correctly. Thanks
|
||||
to baopingle for reporting and providing a test case!
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.8" date="2014-Dec-17">
|
||||
<action type="add">
|
||||
|
|
|
@ -1,656 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<document xmlns="http://maven.apache.org/changes/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 ./changes.xsd">
|
||||
<properties>
|
||||
<author>James Agnew</author>
|
||||
<title>HAPI FHIR Changelog</title>
|
||||
</properties>
|
||||
<body>
|
||||
<release version="0.9" date="TBA">
|
||||
<action type="add">
|
||||
Support for DSTU2 features introduced: New Bundle encoding style, as well as new
|
||||
extension encoding in JSON.
|
||||
</action>
|
||||
<action type="add">
|
||||
Library now checks if custom resource types can be instantiated on startup
|
||||
(e.g. because they don't have a no-argument constructor) in order to
|
||||
avoid failing later
|
||||
</action>
|
||||
<<<<<<< HEAD
|
||||
<action type="add">
|
||||
Bump a few dependency JARs to the latest versions in Maven POM:
|
||||
<![CDATA[
|
||||
<ul>
|
||||
<li>SLF4j (in base module) - Bumped to 1.7.9</li>
|
||||
<li>Apache HTTPClient (in base module) - Bumped to 4.3.6</li>
|
||||
<li>Hibernate (in JPA module) - Bumped to 4.3.7</li>
|
||||
</ul>
|
||||
]]>
|
||||
=======
|
||||
<action type="fix" issue="67">
|
||||
IdDt failed to recognize local identifiers containing fragments that look like
|
||||
real identifiers as being local identifiers even though they started with '#'.
|
||||
For example, a local resource reference of "#aa/_history/aa" would be incorrectly
|
||||
parsed as a non-local reference.
|
||||
Thanks to Mohammad Jafari for reporting!
|
||||
>>>>>>> 31d61100db41590b9760daf9e0942ad553ff69e2
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.8" date="2014-Dec-17">
|
||||
<action type="add">
|
||||
<![CDATA[<b>API CHANGE:</b>]]> The "FHIR structures" for DSTU1 (the classes which model the
|
||||
resources and composite datatypes) have been moved out of the core JAR into their
|
||||
own JAR, in order to allow support for DEV resources, and DSTU2 resources when thast
|
||||
version is finalized. See
|
||||
<![CDATA[<a href="./doc_upgrading.html">upgrading</a>]]>
|
||||
for more information.
|
||||
</action>
|
||||
<action type="fix">
|
||||
<![CDATA[
|
||||
<b>Deprocated API Removal</b>: The following classes (which were deprocated previously)
|
||||
have now been removed:
|
||||
<ul>
|
||||
<li><b>ISecurityManager</b>: If you are using this class, the same functionality
|
||||
is available through the more general purpose
|
||||
<a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_server_interceptor.html">server interceptor</a>
|
||||
capabilities.
|
||||
<li><b>CodingListParam</b>: This class was made redundant by the
|
||||
<a href="http://jamesagnew.github.io/hapi-fhir/apidocs/ca/uhn/fhir/rest/param/TokenOrListParam.html">TokenOrListParam</a>
|
||||
class, which can be used in its place.
|
||||
</ul>
|
||||
]]>
|
||||
</action>
|
||||
<action type="add">
|
||||
<![CDATA[
|
||||
<b>API Change</b>: The IResource#getResourceMetadata() method has been changed
|
||||
from returning
|
||||
<code>Map<ResourceMetadataKeyEnum<?>, Object><code>
|
||||
to returning a new type called
|
||||
<code>ResourceMetadataMap</code>. This new type implements
|
||||
<code>Map<ResourceMetadataKeyEnum<?>, Object><code>
|
||||
itself, so this change should not break existing code, but may
|
||||
require a clean build in order to run correctly.
|
||||
]]>
|
||||
</action>
|
||||
<action type="add" issue="38" dev="wdebeau1">
|
||||
Profile generation on the server was not working due to IdDt being
|
||||
incorrectly used. Thanks to Bill de Beaubien for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="42" dev="wdebeau1">
|
||||
Profiles did not generate correctly if a resource definition class had a
|
||||
defined extension which was of a composite type. Thanks to Bill de Beaubien for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="44" dev="petromykhailysyn">
|
||||
Remove unnecessary IOException from narrative generator API. Thanks to
|
||||
Petro Mykhailysyn for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="48" dev="wdebeau1">
|
||||
Introduced a new
|
||||
<![CDATA[<code>@ProvidesResources</code>]]> annotation which can be added to
|
||||
resource provider and servers to allow them to declare additional resource
|
||||
classes they are able to serve. This is useful if you have a server which can
|
||||
serve up multiple classes for the same resource type (e.g. a server that sometimes
|
||||
returns a default Patient, but sometimes uses a custom subclass).
|
||||
Thanks to Bill de Beaubien for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="49" dev="wdebeau1">
|
||||
Introduced a new
|
||||
<![CDATA[<code>@Destroy</code>]]> annotation which can be added to
|
||||
a resource provider method. This method will be called by the server when it
|
||||
is being closed/destroyed (e.g. when the application is being undeployed, the
|
||||
container is being shut down, etc.)
|
||||
Thanks to Bill de Beaubien for the pull request!
|
||||
</action>
|
||||
<action type="add">
|
||||
Add a new method <![CDATA[handleException]]> to the server interceptor
|
||||
framework which allows interceptors to be notified of any exceptions and
|
||||
runtime errors within server methods. Interceptors may optionally also
|
||||
override the default error handling behaviour of the RestfulServer.
|
||||
</action>
|
||||
<action dev="wdebeau1" type="add">
|
||||
Add constants to BaseResource for the "_id" search parameter which all resources
|
||||
should support.
|
||||
</action>
|
||||
<action type="fix">
|
||||
DateRangeParam parameters on the server now return correct
|
||||
<![CDATA[<code>getLowerBoundAsInstant()</code>]]>
|
||||
and
|
||||
<![CDATA[<code>getUpperBoundAsInstant()</code>]]>
|
||||
values if a single unqualified value is passed in. For example, if
|
||||
a query containing
|
||||
<![CDATA[<code>&birthdate=2012-10-01</code>]]>
|
||||
is received, previously these two methods would both return the same
|
||||
value, but with this fix
|
||||
<![CDATA[<code>getUpperBoundAsInstant()</code>]]>
|
||||
now returns the instant at 23:59:59.9999.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Resource fields with a type of "*" (or Any) sometimes failed to parse if a
|
||||
value type of "code" was used. Thanks to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="add" dev="lmds">
|
||||
Remove dependency on JAXB libraries, which were used to parse and encode
|
||||
dates and times (even in the JSON parser). JAXB is built in to most JDKs
|
||||
but the version bundled with IBM's JDK is flaky and resulted in a number
|
||||
of problems when deploying to Websphere.
|
||||
</action>
|
||||
<action type="fix" issue="50" dev="jjathman">
|
||||
Primitive datatypes now preserve their original string value when parsing resources,
|
||||
as well as containing the "parsed value". For instance, a DecimalDt field value of
|
||||
<![CDATA[<code>1.0000</code>]]> will be parsed into the corresponding
|
||||
decimal value, but will also retain the original value with the corresponding
|
||||
level of precision. This allows vadliator rules to be applied to
|
||||
original values as received "over the wire", such as well formatted but
|
||||
invalid dates, e.g. "2001-15-01". Thanks to Joe Athman for reporting and
|
||||
helping to come up with a fix!
|
||||
</action>
|
||||
<action type="add">
|
||||
When using Generic Client, if performing a
|
||||
<![CDATA[create]]> or <![CDATA[update]]> operation using a String as the resource body,
|
||||
the client will auto-detect the FHIR encoding style and send an appropriate
|
||||
<![CDATA[Content-Type]]> header.
|
||||
</action>
|
||||
<action type="fix" issue="52">
|
||||
JPA module (and public HAPI-FHIR test server) were unable to process resource types
|
||||
where at least one search parameter has no path specified. These now correctly save
|
||||
(although the server does not yet process these params, and it should). Thanks to
|
||||
GitHub user shvoidlee for reporting and help with analysis!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Generic/Fluent Client "create" and "update" method requests were not setting a content type header
|
||||
</action>
|
||||
<action type="add" issue="53" dev="petromykhailysyn">
|
||||
DateDt left precision value as <![CDATA[null]]> in the constructor
|
||||
<![CDATA[DateDt(Date)]]>.
|
||||
</action>
|
||||
<action type="fix">
|
||||
RESTful server now doesn't overwrite resource IDs if they are absolute. In other words, if
|
||||
a server's Resource Provider returns a resource with ID "Patient/123" it will be translated to
|
||||
"[base url]/Patient/123" but if the RP returns ID "http://foo/Patient/123" the ID will be
|
||||
returned exactly as is. Thanks to Bill de Beaubien for the suggestion!
|
||||
</action>
|
||||
<action type="fix" issue="55">
|
||||
JPA module Transaction operation was not correctly replacing logical IDs
|
||||
beginning with "cid:" with server assigned IDs, as required by the
|
||||
specification.
|
||||
</action>
|
||||
<action type="fix" dev="tahurac">
|
||||
<![CDATA[FhirTerser]]> did not visit or find children in contained resources when
|
||||
searching a resource. This caused server implementations to not always return contained
|
||||
resources when they are included with a resource being returned.
|
||||
</action>
|
||||
<action type="add" dev="lmds">
|
||||
Add a method <![CDATA[String IResource#getResourceName()]]> which returns the name of the
|
||||
resource in question (e.g. "Patient", or "Observation"). This is intended as a
|
||||
convenience to users.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Do not strip version from resource references in resources returned
|
||||
from server search methods. Thanks to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix" dev="jjathman" issue="54">
|
||||
Correct an issue with the validator where changes to the underlying
|
||||
OperationOutcome produced by a validation cycle cause the validation
|
||||
results to be incorrect.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Client interceptors registered to an interface based client instance
|
||||
were applied to other client instances for the same client interface as well. (Issue
|
||||
did not affect generic/fluent clients)
|
||||
</action>
|
||||
<action type="fix" issue="57">
|
||||
DateDt, DateTimeDt and types InstantDt types now do not throw an exception
|
||||
if they are used to parse a value with the wrong level of precision for
|
||||
the given type but do throw an exception if the wrong level of precision
|
||||
is passed into their constructors.<![CDATA[<br/><br/>]]>
|
||||
This means that HAPI FHIR can now successfully parse resources from external
|
||||
sources that have the wrong level of precision, but will generate a validation
|
||||
error if the resource is validated. Thanks to Alexander Kley for the suggestion!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Encoding a Binary resource without a content type set should not result in a NullPointerException. Thanks
|
||||
to Alexander Kley for reporting!
|
||||
</action>
|
||||
<action type="add">
|
||||
Server gives a more helpful error message if multiple IResourceProvider implementations
|
||||
are provided for the same resource type. Thanks to wanghaisheng for the idea!
|
||||
</action>
|
||||
<action type="add" issue="61">
|
||||
Bring DSTU1 resource definitions up to version 0.0.82-2929<![CDATA[<br/>]]>
|
||||
Bring DEV resource definitions up to 0.4.0-3775<![CDATA[<br/>]]>
|
||||
Thanks to crinacimpian for reporting!
|
||||
</action>
|
||||
<action type="add" issue="62">
|
||||
JPA server did not correctly process _include requests if included
|
||||
resources were present with a non-numeric identifier. Thanks to
|
||||
Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix" issue="60">
|
||||
Client requests which include a resource/bundle body (e.g. create,
|
||||
update, transaction) were not including a charset in the content type
|
||||
header, leading to servers incorrectly assuming ISO-8859/1. Thanks to
|
||||
shvoidlee for reporting!
|
||||
</action>
|
||||
<action type="fix" issue="59" dev="wdebeau1">
|
||||
Clean up the way that Profile resources are automatically exported
|
||||
by the server for custom resource profile classes. See the
|
||||
<![CDATA[<a href="http://jamesagnew.github.io/hapi-fhir/apidocs/ca/uhn/fhir/model/api/annotation/ResourceDef.html">@ResourceDef</a>]]>
|
||||
JavaDoc for information on how this works.
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.7" date="2014-Oct-23">
|
||||
<action type="add" issue="30">
|
||||
<![CDATA[<b>API CHANGE:</b>]]> The TagList class previously implemented ArrayList semantics,
|
||||
but this has been replaced with LinkedHashMap semantics. This means that the list of
|
||||
tags will no longer accept duplicate tags, but that tag order will still be
|
||||
preserved. Thanks to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix" issue="33">
|
||||
Server was incorrectly including contained resources being returned as both contained resources, and as
|
||||
top-level resources in the returned bundle for search operations.
|
||||
Thanks to Bill de Beaubien for reporting! This also fixes Issue #20, thanks to
|
||||
lephty for reporting!
|
||||
</action>
|
||||
<action type="add" dev="suranga">
|
||||
Documentation fixes
|
||||
</action>
|
||||
<action type="add" dev="dougmartin">
|
||||
Add a collection of new methods on the generic client which support the
|
||||
<![CDATA[
|
||||
<b><a href="./apidocs/ca/uhn/fhir/rest/client/IGenericClient.html#read(java.lang.Class,%20ca.uhn.fhir.model.primitive.UriDt)">read</a></b>,
|
||||
<b><a href="./apidocs/ca/uhn/fhir/rest/client/IGenericClient.html#vread(java.lang.Class,%20ca.uhn.fhir.model.primitive.UriDt)">read</a></b>,
|
||||
and <b><a href="./apidocs/ca/uhn/fhir/rest/client/IGenericClient.html#search(java.lang.Class,%20ca.uhn.fhir.model.primitive.UriDt)">search</a></b>
|
||||
]]>
|
||||
operations using an absolute URL. This allows developers to perform these operations using
|
||||
URLs they obtained from other sources (or external resource references within resources). In
|
||||
addition, the existing read/vread operations will now access absolute URL references if
|
||||
they are passed in. Thanks to Doug Martin of the Regenstrief Center for Biomedical Informatics
|
||||
for contributing this implementation!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Server implementation was not correctly figuring out its own FHIR Base URL when deployed
|
||||
on Amazon Web Service server. Thanks to Jeffrey Ting and Bill De Beaubien of
|
||||
Systems Made Simple for their help in figuring out this issue!
|
||||
</action>
|
||||
<action type="fix">
|
||||
XML Parser failed to encode fields with both a resource reference child and
|
||||
a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of
|
||||
Systems Made Simple for their help in figuring out this issue!
|
||||
</action>
|
||||
<action type="fix">
|
||||
HAPI now runs successfully on Servlet 2.5 containers (such as Tomcat 6). Thanks to
|
||||
Bernard Gitaadji for reporting and diagnosing the issue!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Summary (in the bundle entry) is now encoded by the XML and JSON parsers if supplied. Thanks to David Hay of
|
||||
Orion Health for reporting this!
|
||||
</action>
|
||||
<action type="fix" issue="24">
|
||||
Conformance profiles which are automatically generated by the server were missing a few mandatory elements,
|
||||
which meant that the profile did not correctly validate. Thanks to Bill de Beaubien of Systems Made Simple
|
||||
for reporting this!
|
||||
</action>
|
||||
<action type="fix">
|
||||
XHTML (in narratives) containing escapable characters (e.g. < or ") will now always have those characters
|
||||
escaped properly in encoded messages.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Resources containing entities which are not valid in basic XML (e.g. &sect;) will have those
|
||||
entities converted to their equivalent unicode characters when resources are encoded, since FHIR does
|
||||
not allow extended entities in resource instances.
|
||||
</action>
|
||||
<action type="add">
|
||||
Add a new client interceptor which adds HTTP Authorization Bearer Tokens (for use with OAUTH2 servers)
|
||||
to client requests.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Add phloc-commons dependency explicitly, which resolves an issue building HAPI from source on
|
||||
some platforms. Thanks to Odysseas Pentakalos for the patch!
|
||||
</action>
|
||||
<action type="add">
|
||||
HAPI now logs a single line indicating the StAX implementation being used upon the
|
||||
first time an XML parser is created.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Update methods on the server did not return a "content-location" header, but
|
||||
only a "location" header. Both are required according to the FHIR specification.
|
||||
Thanks to Bill de Beaubien of Systems Made Simple for reporting this!
|
||||
</action>
|
||||
<action type="fix" issue="26" dev="akley">
|
||||
Parser failed to correctly read contained Binary resources. Thanks to Alexander Kley for
|
||||
the patch!
|
||||
</action>
|
||||
<action type="fix" issue="29" dev="akley">
|
||||
Calling encode multiple times on a resource with contained resources caused the contained
|
||||
resources to be re-added (and the actual message to grow) with each encode pass. Thanks to
|
||||
Alexander Kley for the test case!
|
||||
</action>
|
||||
<action type="fix">
|
||||
JSON-encoded contained resources with the incorrect "_id" element (which should be "id", but some
|
||||
incorrect examples exist on the FHIR specification) now parse correctly. In other words, HAPI
|
||||
previously only accepted the correct "id" element, but now it also accepts the incorrect
|
||||
"_id" element just to be more lenient.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Several unit tests failed on Windows (or any platform with non UTF-8 default encoding). This may
|
||||
have also caused resource validation to fail occasionally on these platforms as well.
|
||||
Thanks to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
toString() method on TokenParam was incorrectly showing the system as the value.
|
||||
Thanks to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="update">
|
||||
Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks
|
||||
to David Hay of Orion Health for reporting!
|
||||
</action>
|
||||
<action type="add" issue="31" dev="preston">
|
||||
Add a
|
||||
<![CDATA[<a href="https://www.vagrantup.com/">Vagrant</a>]]>
|
||||
based environment (basically a fully built, self contained development environment) for
|
||||
trying out the HAPI server modules. Thanks to Preston Lee for the pull request, and for
|
||||
offering to maintain this!
|
||||
</action>
|
||||
<action type="add" issue="32" dev="jjathman">
|
||||
Change validation API so that it uses a return type instead of exceptions to communicate
|
||||
validation failures. Thanks to Joe Athman for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="35" dev="petromykhailysyn">
|
||||
Add a client interceptor which adds an HTTP cookie to each client request. Thanks to
|
||||
Petro Mykhailysyn for the pull request!
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!">
|
||||
<!--
|
||||
<action type="add">
|
||||
Allow generic client ... OAUTH
|
||||
</action>
|
||||
-->
|
||||
<action type="add">
|
||||
Add server interceptor framework, and new interceptor for logging incoming
|
||||
requests.
|
||||
</action>
|
||||
<action type="add">
|
||||
Add server validation framework for validating resources against the FHIR schemas and schematrons
|
||||
</action>
|
||||
<action type="fix">
|
||||
Tester UI created double _format and _pretty param entries in searches. Thanks to Gered King of University
|
||||
Health Network for reporting!
|
||||
</action>
|
||||
<action type="fix" issue="4">
|
||||
Create method was incorrectly returning an HTTP 204 on sucessful completion, but
|
||||
should be returning an HTTP 200 per the FHIR specification. Thanks to wanghaisheng
|
||||
for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
FHIR Tester UI now correctly sends UTF-8 charset in responses so that message payloads containing
|
||||
non US-ASCII characters will correctly display in the browser
|
||||
</action>
|
||||
<action type="fix">
|
||||
JSON parser was incorrectly encoding extensions on composite elements outside the element itself
|
||||
(as is done correctly for non-composite elements) instead of inside of them. Thanks to David Hay of
|
||||
Orion for reporting this!
|
||||
</action>
|
||||
<action type="add">
|
||||
Contained/included resource instances received by a client are now automatically
|
||||
added to any ResourceReferenceDt instancea in other resources which reference them.
|
||||
</action>
|
||||
<action type="add">
|
||||
Add documentation on how to use eBay CORS Filter to support Cross Origin Resource
|
||||
Sharing (CORS) to server. CORS support that was built in to the server itself has
|
||||
been removed, as it did not work correctly (and was reinventing a wheel that others
|
||||
have done a great job inventing). Thanks to Peter Bernhardt of Relay Health for all the assistance
|
||||
in testing this!
|
||||
</action>
|
||||
<action type="fix">
|
||||
IResource interface did not expose the getLanguage/setLanguage methods from BaseResource,
|
||||
so the resource language was difficult to access.
|
||||
</action>
|
||||
<action type="fix">
|
||||
JSON Parser now gives a more friendly error message if it tries to parse JSON with invalid use
|
||||
of single quotes
|
||||
</action>
|
||||
<action type="add">
|
||||
Transaction server method is now allowed to return an OperationOutcome in addition to the
|
||||
incoming resources. The public test server now does this in order to return status information
|
||||
about the transaction processing.
|
||||
</action>
|
||||
<action type="add">
|
||||
Update method in the server can now flag (via a field on the MethodOutcome object being returned)
|
||||
that the result was actually a creation, and Create method can indicate that it was actually an
|
||||
update. This has no effect other than to switch between the HTTP 200 and HTTP 201 status codes on the
|
||||
response, but this may be useful in some circumstances.
|
||||
</action>
|
||||
<action type="fix" dev="tahurac">
|
||||
Annotation client search methods with a specific resource type (e.g. List<Patient> search())
|
||||
won't return any resources that aren't of the correct type that are received in a response
|
||||
bundle (generally these are referenced resources, so they are populated in the reference fields instead).
|
||||
Thanks to Tahura Chaudhry of University Health Network for the unit test!
|
||||
</action>
|
||||
<action type="add">
|
||||
Added narrative generator template for OperationOutcome resource
|
||||
</action>
|
||||
<action type="fix">
|
||||
Date/time types did not correctly parse values in the format "yyyymmdd" (although the FHIR-defined format
|
||||
is "yyyy-mm-dd" anyhow, and this is correctly handled). Thanks to Jeffrey Ting of Systems Made Simple
|
||||
for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Server search method for an unnamed query gets called if the client requests a named query
|
||||
with the same parameter list. Thanks to Neal Acharya of University Health Network for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Category header (for tags) is correctly read in client for "read" operation
|
||||
</action>
|
||||
<action type="add">
|
||||
Transaction method in server can now have parameter type Bundle instead of
|
||||
List<IResource>
|
||||
</action>
|
||||
<action type="add">
|
||||
HAPI parsers now use field access to get/set values instead of method accessors and mutators.
|
||||
This should give a small performance boost.
|
||||
</action>
|
||||
<action type="fix">
|
||||
JSON parser encodes resource references incorrectly, using the name "resource" instead
|
||||
of the name "reference" for the actual reference. Thanks to
|
||||
Ricky Nguyen for reporting and tracking down the issue!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Rename NotImpementedException to NotImplementedException (to correct typo)
|
||||
</action>
|
||||
<action type="fix">
|
||||
Server setUseBrowserFriendlyContentType setting also respected for errors (e.g. OperationOutcome with 4xx/5xx status)
|
||||
</action>
|
||||
<action type="fix">
|
||||
Fix performance issue in date/time datatypes where pattern matchers were not static
|
||||
</action>
|
||||
<action type="fix">
|
||||
Server now gives a more helpful error message if a @Read method has a search parameter (which is invalid, but
|
||||
previously lead to a very unhelpful error message). Thanks to Tahura Chaudhry of UHN for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health
|
||||
for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
QuantityParam correctly encodes approximate (~) prefix to values
|
||||
</action>
|
||||
<action type="fix" issue="14">
|
||||
If a server defines a method with parameter "_id", incoming search requests for that method may
|
||||
get delegated to the wrong method. Thanks to Neal Acharya for reporting!
|
||||
</action>
|
||||
<action type="add">
|
||||
SecurityEvent.Object structural element has been renamed to
|
||||
SecurityEvent.ObjectElement to avoid conflicting names with the
|
||||
java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for
|
||||
reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Text/narrative blocks that were created with a non-empty
|
||||
namespace prefix (e.g. <xhtml:div xmlns:xhtml="...">...</xhtml:div>)
|
||||
failed to encode correctly (prefix was missing in encoded resource)
|
||||
</action>
|
||||
<action type="fix">
|
||||
Resource references previously encoded their children (display and reference)
|
||||
in the wrong order so references with both would fail schema validation.
|
||||
</action>
|
||||
<action type="add">
|
||||
SecurityEvent resource's enums now use friendly enum names instead of the unfriendly
|
||||
numeric code values. Thanks to Laurie MacDougall-Sookraj of UHN for the
|
||||
suggestion!
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.5" date="2014-Jul-30">
|
||||
<action type="add">
|
||||
HAPI has a number of RESTful method parameter types that have similar but not identical
|
||||
purposes and confusing names. A cleanup has been undertaken to clean this up.
|
||||
This means that a number of existing classes
|
||||
have been deprocated in favour of new naming schemes.
|
||||
<![CDATA[<br/><br/>]]>
|
||||
All annotation-based clients and all server search method parameters are now named
|
||||
(type)Param, for example: StringParam, TokenParam, etc.
|
||||
<![CDATA[<br/><br/>]]>
|
||||
All generic/fluent client method parameters are now named
|
||||
(type)ClientParam, for example: StringClientParam, TokenClientParam, etc.
|
||||
<![CDATA[<br/><br/>]]>
|
||||
All renamed classes have been retained and deprocated, so this change should not cause any issues
|
||||
for existing applications but those applications should be refactored to use the
|
||||
new parameters when possible.
|
||||
</action>
|
||||
<action type="add">
|
||||
Allow server methods to return wildcard generic types (e.g. List<? extends IResource>)
|
||||
</action>
|
||||
<action type="add">
|
||||
Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as
|
||||
"&identifier=system|codepart1\|codepart2"
|
||||
</action>
|
||||
<action type="add">
|
||||
Add support for OPTIONS verb (which returns the server conformance statement)
|
||||
</action>
|
||||
<action type="add">
|
||||
Add support for CORS headers in server
|
||||
</action>
|
||||
<action type="add">
|
||||
Bump SLF4j dependency to latest version (1.7.7)
|
||||
</action>
|
||||
<action type="add">
|
||||
Add interceptor framework for clients (annotation based and generic), and add interceptors
|
||||
for configurable logging, capturing requests and responses, and HTTP basic auth.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Transaction client invocations with XML encoding were using the wrong content type ("application/xml+fhir" instead
|
||||
of the correct "application/atom+xml"). Thanks to David Hay of Orion Health for surfacing this one!
|
||||
</action>
|
||||
<action type="add">
|
||||
Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion!
|
||||
</action>
|
||||
<action type="add" issue="1">
|
||||
If a client receives a non 2xx response (e.g. HTTP 500) and the response body is a text/plain message or
|
||||
an OperationOutcome resource, include the message in the exception message so that it will be
|
||||
more conveniently displayed in logs and other places. Thanks to Neal Acharya for the suggestion!
|
||||
</action>
|
||||
<action type="add" issue="2">
|
||||
Read invocations in the client now process the "Content-Location" header and use it to
|
||||
populate the ID of the returned resource. Thanks to Neal Acharya for the suggestion!
|
||||
</action>
|
||||
<action type="fix" issue="3">
|
||||
Fix issue where vread invocations on server incorrectly get routed to instance history method if one is
|
||||
defined. Thanks to Neal Acharya from UHN for surfacing this one!
|
||||
</action>
|
||||
<action type="add">
|
||||
Binary reads on a server not include the Content-Disposition header, to prevent HTML in binary
|
||||
blobs from being used for nefarious purposes. See
|
||||
<![CDATA[<a href="http://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_id=677&tracker_item_id=3298">FHIR Tracker Bug 3298</a>]]>
|
||||
for more information.
|
||||
</action>
|
||||
<action type="add">
|
||||
Support has been added for using an HTTP proxy for outgoing requests.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Fix: Primitive extensions declared against custom resource types
|
||||
are encoded even if they have no value. Thanks to David Hay of Orion for
|
||||
reporting this!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Fix: RESTful server deployed to a location where the URL to access it contained a
|
||||
space (e.g. a WAR file with a space in the name) failed to work correctly.
|
||||
Thanks to David Hay of Orion for reporting this!
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.4" date="2014-Jul-13">
|
||||
<action type="add">
|
||||
<![CDATA[<b>BREAKING CHANGE:</b>]]>: IdDt has been modified so that it
|
||||
contains a partial or complete resource identity. Previously it contained
|
||||
only the simple alphanumeric id of the resource (the part at the end of the "read" URL for
|
||||
that resource) but it can now contain a complete URL or even a partial URL (e.g. "Patient/123")
|
||||
and can optionally contain a version (e.g. "Patient/123/_history/456"). New methods have
|
||||
been added to this datatype which provide just the numeric portion. See the JavaDoc
|
||||
for more information.
|
||||
</action>
|
||||
<action type="add">
|
||||
<![CDATA[<b>API CHANGE:</b>]]>: Most elements in the HAPI FHIR model contain
|
||||
a getId() and setId() method. This method is confusing because it is only actually used
|
||||
for IDREF elements (which are rare) but its name makes it easy to confuse with more
|
||||
important identifiers. For this reason, these methods have been deprocated and replaced with
|
||||
get/setElementSpecificId() methods. The old methods will be removed at some point. Resource
|
||||
types are unchanged and retain their get/setId methods.
|
||||
</action>
|
||||
<action type="add">
|
||||
Allow use of QuantityDt as a service parameter to support the "quantity" type. Previously
|
||||
QuantityDt did not implement IQueryParameterType so it was not valid, and there was no way to
|
||||
support quantity search parameters on the server (e.g. Observation.value-quantity)
|
||||
</action>
|
||||
<action type="add">
|
||||
Introduce StringParameter type which can be used as a RESTful operation search parameter
|
||||
type. StringParameter allows ":exact" matches to be specified in clients, and handled in servers.
|
||||
</action>
|
||||
<action type="add">
|
||||
Parsers (XML/JSON) now support deleted entries in bundles
|
||||
</action>
|
||||
<action type="add">
|
||||
Transaction method now supported in servers
|
||||
</action>
|
||||
<action type="add">
|
||||
Support for Binary resources added (in servers, clients, parsers, etc.)
|
||||
</action>
|
||||
<action type="fix">
|
||||
Support for Query resources fixed (in parser)
|
||||
</action>
|
||||
<action type="fix">
|
||||
Nested contained resources (e.g. encoding a resource with a contained resource that itself contains a resource)
|
||||
now parse and encode correctly, meaning that all contained resources are placed in the "contained" element
|
||||
of the root resource, and the parser looks in the root resource for all container levels when stitching
|
||||
contained resources back together.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Server methods with @Include parameter would sometimes fail when no _include was actually
|
||||
specified in query strings.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Client requests for IdentifierDt types (such as Patient.identifier) did not create the correct
|
||||
query string if the system is null.
|
||||
</action>
|
||||
<action type="add">
|
||||
Add support for paging responses from RESTful servers.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Don't fail on narrative blocks in JSON resources with only an XML declaration but no content (these are
|
||||
produced by the Health Intersections server)
|
||||
</action>
|
||||
<action type="fix">
|
||||
Server now automatically compresses responses if the client indicates support
|
||||
</action>
|
||||
<action type="fix">
|
||||
Server failed to support optional parameters when type is String and :exact qualifier is used
|
||||
</action>
|
||||
<action type="fix">
|
||||
Read method in client correctly populated resource ID in returned object
|
||||
</action>
|
||||
<action type="add">
|
||||
Support added for deleted-entry by/name, by/email, and comment from Tombstones spec
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.3" date="2014-May-12" description="This release corrects lots of bugs and introduces the fluent client mode">
|
||||
</release>
|
||||
</body>
|
||||
</document>
|
|
@ -103,52 +103,30 @@ patient.getManagingOrganization().setReference("Organization/124362");]]></sourc
|
|||
bundles. Both resources are added to a bundle, which will then have
|
||||
two entries:
|
||||
</p>
|
||||
<source><![CDATA[// Create an organization
|
||||
Organization org = new Organization();
|
||||
org.setId("Organization/65546");
|
||||
org.getName().setValue("Contained Test Organization");
|
||||
|
||||
// Create a patient
|
||||
Patient patient = new Patient();
|
||||
patient.setId("Patient/1333");
|
||||
patient.addIdentifier("urn:mrns", "253345");
|
||||
patient.getManagingOrganization().setResource(org);
|
||||
|
||||
// Create a list containing both resources. In a server method, you might just
|
||||
// return this list, but here we will create a bundle to encode.
|
||||
List<IResource> resources = new ArrayList<IResource>();
|
||||
resources.add(org);
|
||||
resources.add(patient);
|
||||
|
||||
// Create a bundle with both
|
||||
Bundle b = Bundle.withResources(resources, ourCtx, "http://example.com/base");
|
||||
|
||||
// Encode the buntdle
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
|
||||
System.out.println(encoded);]]></source>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="addIncludes" />
|
||||
<param name="file" value="examples/src/main/java/example/IncludesExamples.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
This will give the following output:
|
||||
</p>
|
||||
<source><![CDATA[<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<source><![CDATA[<Bundle xmlns="http://hl7.org/fhir">
|
||||
<id value="4e151274-2b19-4930-97f2-8427167a176c"/>
|
||||
<type value="searchset"/>
|
||||
<total value="1"/>
|
||||
<link>
|
||||
<relation value="fhir-base"/>
|
||||
<url value="http://example.com/base"/>
|
||||
</link>
|
||||
<link>
|
||||
<relation value="self"/>
|
||||
<url value="http://example.com/base/Patient"/>
|
||||
</link>
|
||||
<entry>
|
||||
<title>Organization Organization/65546</title>
|
||||
<id>http://example.com/base/Organization/65546</id>
|
||||
<published>2014-10-14T09:22:54-04:00</published>
|
||||
<link rel="self" href="http://example.com/base/Organization/65546"/>
|
||||
<content type="text/xml">
|
||||
<Organization xmlns="http://hl7.org/fhir">
|
||||
<name value="Contained Test Organization"/>
|
||||
</Organization>
|
||||
</content>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Patient Patient/1333</title>
|
||||
<id>http://example.com/base/Patient/1333</id>
|
||||
<published>2014-10-14T09:22:54-04:00</published>
|
||||
<link rel="self" href="http://example.com/base/Patient/1333"/>
|
||||
<content type="text/xml">
|
||||
<resource>
|
||||
<Patient xmlns="http://hl7.org/fhir">
|
||||
<id value="1333"/>
|
||||
<identifier>
|
||||
<system value="urn:mrns"/>
|
||||
<value value="253345"/>
|
||||
|
@ -157,9 +135,21 @@ System.out.println(encoded);]]></source>
|
|||
<reference value="Organization/65546"/>
|
||||
</managingOrganization>
|
||||
</Patient>
|
||||
</content>
|
||||
</resource>
|
||||
</entry>
|
||||
</feed>]]></source>
|
||||
<entry>
|
||||
<resource>
|
||||
<Organization xmlns="http://hl7.org/fhir">
|
||||
<id value="65546"/>
|
||||
<name value="Test Organization"/>
|
||||
</Organization>
|
||||
</resource>
|
||||
<search>
|
||||
<mode value="include"/>
|
||||
</search>
|
||||
</entry>
|
||||
</Bundle>
|
||||
]]></source>
|
||||
|
||||
</subsection>
|
||||
|
||||
|
|
Loading…
Reference in New Issue