Begin multi version work
This commit is contained in:
parent
383d4929c8
commit
c294e1c064
|
@ -50,16 +50,20 @@ import ca.uhn.fhir.util.FhirTerser;
|
||||||
import ca.uhn.fhir.validation.FhirValidator;
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FHIR context is the central starting point for the use of the HAPI FHIR API. It should be created once, and then used as a factory for various other types of objects (parsers, clients, etc.).
|
* The FHIR context is the central starting point for the use of the HAPI FHIR API. It should be created once, and then
|
||||||
|
* used as a factory for various other types of objects (parsers, clients, etc.).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Important usage notes:
|
* Important usage notes:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Thread safety: <b>This class is thread safe</b> and may be shared between multiple processing threads.</li>
|
* <li>Thread safety: <b>This class is thread safe</b> and may be shared between multiple processing threads.</li>
|
||||||
* <li>
|
* <li>
|
||||||
* Performance: <b>This class is expensive</b> to create, as it scans every resource class it needs to parse or encode to build up an internal model of those classes. For that reason, you should try
|
* Performance: <b>This class is expensive</b> to create, as it scans every resource class it needs to parse or encode
|
||||||
* to create one FhirContext instance which remains for the life of your application and reuse that instance. Note that it will not cause problems to create multiple instances (ie. resources
|
* to build up an internal model of those classes. For that reason, you should try to create one FhirContext instance
|
||||||
* originating from one FhirContext may be passed to parsers originating from another) but you will incur a performance penalty if a new FhirContext is created for every message you parse/encode.</li>
|
* which remains for the life of your application and reuse that instance. Note that it will not cause problems to
|
||||||
|
* create multiple instances (ie. resources originating from one FhirContext may be passed to parsers originating from
|
||||||
|
* another) but you will incur a performance penalty if a new FhirContext is created for every message you parse/encode.
|
||||||
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
|
@ -74,7 +78,7 @@ public class FhirContext {
|
||||||
private volatile INarrativeGenerator myNarrativeGenerator;
|
private volatile INarrativeGenerator myNarrativeGenerator;
|
||||||
private volatile IRestfulClientFactory myRestfulClientFactory;
|
private volatile IRestfulClientFactory myRestfulClientFactory;
|
||||||
private volatile RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
|
private volatile RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
|
||||||
private IFhirVersion myVersion;
|
private final IFhirVersion myVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor. In most cases this is the right constructor to use.
|
* Default constructor. In most cases this is the right constructor to use.
|
||||||
|
@ -92,18 +96,31 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public FhirContext(Collection<Class<? extends IResource>> theResourceTypes) {
|
public FhirContext(Collection<Class<? extends IResource>> theResourceTypes) {
|
||||||
scanResourceTypes(theResourceTypes);
|
this(null, theResourceTypes);
|
||||||
|
}
|
||||||
|
|
||||||
if (FhirVersionEnum.DSTU1.isPresentOnClasspath()) {
|
public FhirContext(FhirVersionEnum theVersion) {
|
||||||
|
this(theVersion, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FhirContext(FhirVersionEnum theVersion, Collection<Class<? extends IResource>> theResourceTypes) {
|
||||||
|
if (theVersion != null) {
|
||||||
|
if (!theVersion.isPresentOnClasspath()) {
|
||||||
|
throw new IllegalStateException(getLocalizer().getMessage(FhirContext.class, "noStructuresForSpecifiedVersion"));
|
||||||
|
}
|
||||||
|
myVersion = theVersion.getVersionImplementation();
|
||||||
|
} else if (FhirVersionEnum.DSTU1.isPresentOnClasspath()) {
|
||||||
myVersion = FhirVersionEnum.DSTU1.getVersionImplementation();
|
myVersion = FhirVersionEnum.DSTU1.getVersionImplementation();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Could not find any HAPI-FHIR structure JARs on the classpath. Note that as of HAPI-FHIR v0.8, a separate FHIR strcture JAR must be added to your classpath or project pom.xml");
|
throw new IllegalStateException(getLocalizer().getMessage(FhirContext.class, "noStructures"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scanResourceTypes(theResourceTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed for extending the core library.
|
* 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(Class<? extends IElement> theElementType) {
|
public BaseRuntimeElementDefinition<?> getElementDefinition(Class<? extends IElement> theElementType) {
|
||||||
return myClassToElementDefinition.get(theElementType);
|
return myClassToElementDefinition.get(theElementType);
|
||||||
|
@ -115,7 +132,8 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This feature is not yet in its final state and should be considered an internal part of HAPI for now - use with caution
|
* This feature is not yet in its final state and should be considered an internal part of HAPI for now - use with
|
||||||
|
* caution
|
||||||
*/
|
*/
|
||||||
public HapiLocalizer getLocalizer() {
|
public HapiLocalizer getLocalizer() {
|
||||||
if (myLocalizer == null) {
|
if (myLocalizer == null) {
|
||||||
|
@ -129,7 +147,8 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed for extending the core library.
|
* 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 RuntimeResourceDefinition getResourceDefinition(Class<? extends IResource> theResourceType) {
|
public RuntimeResourceDefinition getResourceDefinition(Class<? extends IResource> theResourceType) {
|
||||||
RuntimeResourceDefinition retVal = (RuntimeResourceDefinition) myClassToElementDefinition.get(theResourceType);
|
RuntimeResourceDefinition retVal = (RuntimeResourceDefinition) myClassToElementDefinition.get(theResourceType);
|
||||||
|
@ -140,21 +159,24 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed for extending the core library.
|
* 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 RuntimeResourceDefinition getResourceDefinition(IResource theResource) {
|
public RuntimeResourceDefinition getResourceDefinition(IResource theResource) {
|
||||||
return getResourceDefinition(theResource.getClass());
|
return getResourceDefinition(theResource.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed for extending the core library.
|
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed
|
||||||
|
* for extending the core library.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public RuntimeResourceDefinition getResourceDefinition(String theResourceName) {
|
public RuntimeResourceDefinition getResourceDefinition(String theResourceName) {
|
||||||
String resourceName = theResourceName;
|
String resourceName = theResourceName;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: this is a bit of a hack, really we should have a translation table based on a property file or something so that we can detect names like diagnosticreport
|
* TODO: this is a bit of a hack, really we should have a translation table based on a property file or
|
||||||
|
* something so that we can detect names like diagnosticreport
|
||||||
*/
|
*/
|
||||||
if (Character.isLowerCase(resourceName.charAt(0))) {
|
if (Character.isLowerCase(resourceName.charAt(0))) {
|
||||||
resourceName = WordUtils.capitalize(resourceName);
|
resourceName = WordUtils.capitalize(resourceName);
|
||||||
|
@ -188,14 +210,16 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed for extending the core library.
|
* 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 RuntimeResourceDefinition getResourceDefinitionById(String theId) {
|
public RuntimeResourceDefinition getResourceDefinitionById(String theId) {
|
||||||
return myIdToResourceDefinition.get(theId);
|
return myIdToResourceDefinition.get(theId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the scanned runtime models. This is an advanced feature which is generally only needed for extending the core library.
|
* Returns the scanned runtime models. This is an advanced feature which is generally only needed for extending the
|
||||||
|
* core library.
|
||||||
*/
|
*/
|
||||||
public Collection<RuntimeResourceDefinition> getResourceDefinitions() {
|
public Collection<RuntimeResourceDefinition> getResourceDefinitions() {
|
||||||
return myIdToResourceDefinition.values();
|
return myIdToResourceDefinition.values();
|
||||||
|
@ -220,10 +244,12 @@ public class FhirContext {
|
||||||
* Create and return a new JSON parser.
|
* Create and return a new JSON parser.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or every message being parsed/encoded.
|
* Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread
|
||||||
|
* or every message being parsed/encoded.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed without incurring any performance penalty
|
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed
|
||||||
|
* without incurring any performance penalty
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public IParser newJsonParser() {
|
public IParser newJsonParser() {
|
||||||
|
@ -231,12 +257,16 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new client instance. This method requires an interface which is defined specifically for your use cases to contain methods for each of the RESTful operations you wish to
|
* Instantiates a new client instance. This method requires an interface which is defined specifically for your use
|
||||||
* implement (e.g. "read ImagingStudy", "search Patient by identifier", etc.). This interface must extend {@link IRestfulClient} (or commonly its sub-interface {@link IBasicClient}). See the <a
|
* cases to contain methods for each of the RESTful operations you wish to implement (e.g. "read ImagingStudy",
|
||||||
* href="http://hl7api.sourceforge.net/hapi-fhir/doc_rest_client.html">RESTful Client</a> documentation for more information on how to define this interface.
|
* "search Patient by identifier", etc.). This interface must extend {@link IRestfulClient} (or commonly its
|
||||||
|
* sub-interface {@link IBasicClient}). See the <a
|
||||||
|
* href="http://hl7api.sourceforge.net/hapi-fhir/doc_rest_client.html">RESTful Client</a> documentation for more
|
||||||
|
* information on how to define this interface.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every operation invocation without incurring any performance penalty
|
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every operation invocation
|
||||||
|
* without incurring any performance penalty
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theClientType
|
* @param theClientType
|
||||||
|
@ -252,11 +282,13 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new generic client. A generic client is able to perform any of the FHIR RESTful operations against a compliant server, but does not have methods defining the specific
|
* Instantiates a new generic client. A generic client is able to perform any of the FHIR RESTful operations against
|
||||||
* functionality required (as is the case with {@link #newRestfulClient(Class, String) non-generic clients}).
|
* a compliant server, but does not have methods defining the specific functionality required (as is the case with
|
||||||
|
* {@link #newRestfulClient(Class, String) non-generic clients}).
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every operation invocation without incurring any performance penalty
|
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every operation invocation
|
||||||
|
* without incurring any performance penalty
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theServerBase
|
* @param theServerBase
|
||||||
|
@ -283,10 +315,12 @@ public class FhirContext {
|
||||||
* Create and return a new XML parser.
|
* Create and return a new XML parser.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread or every message being parsed/encoded.
|
* Thread safety: <b>Parsers are not guaranteed to be thread safe</b>. Create a new parser instance for every thread
|
||||||
|
* or every message being parsed/encoded.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed without incurring any performance penalty
|
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed
|
||||||
|
* without incurring any performance penalty
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public IParser newXmlParser() {
|
public IParser newXmlParser() {
|
||||||
|
@ -328,7 +362,8 @@ public class FhirContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This feature is not yet in its final state and should be considered an internal part of HAPI for now - use with caution
|
* This feature is not yet in its final state and should be considered an internal part of HAPI for now - use with
|
||||||
|
* caution
|
||||||
*/
|
*/
|
||||||
public void setLocalizer(HapiLocalizer theMessages) {
|
public void setLocalizer(HapiLocalizer theMessages) {
|
||||||
myLocalizer = theMessages;
|
myLocalizer = theMessages;
|
||||||
|
@ -356,4 +391,18 @@ public class FhirContext {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new FhirContext with version {@link FhirVersionEnum#DSTU1}
|
||||||
|
*/
|
||||||
|
public static FhirContext forDstu1() {
|
||||||
|
return new FhirContext(FhirVersionEnum.DSTU1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new FhirContext with version {@link FhirVersionEnum#DEV}
|
||||||
|
*/
|
||||||
|
public static FhirContext forDev() {
|
||||||
|
return new FhirContext(FhirVersionEnum.DEV);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,15 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
|
||||||
public enum FhirVersionEnum {
|
public enum FhirVersionEnum {
|
||||||
|
|
||||||
DSTU1("ca.uhn.fhir.model.dstu.FhirDstu1");
|
/*
|
||||||
|
* ***********************
|
||||||
|
* Don't sort this type!!!
|
||||||
|
* ***********************
|
||||||
|
*/
|
||||||
|
|
||||||
|
DSTU1("ca.uhn.fhir.model.dstu.FhirDstu1"),
|
||||||
|
|
||||||
|
DEV("ca.uhn.fhir.model.dev.FhirDev");
|
||||||
|
|
||||||
private final String myVersionClass;
|
private final String myVersionClass;
|
||||||
private volatile Boolean myPresentOnClasspath;
|
private volatile Boolean myPresentOnClasspath;
|
||||||
|
@ -35,6 +43,10 @@ public enum FhirVersionEnum {
|
||||||
myVersionClass = theVersionClass;
|
myVersionClass = theVersionClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNewerThan(FhirVersionEnum theVersion) {
|
||||||
|
return ordinal() > theVersion.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given version is present on the classpath
|
* Returns true if the given version is present on the classpath
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,7 +20,7 @@ package ca.uhn.fhir.context;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -93,20 +93,26 @@ class ModelScanner {
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
|
||||||
ModelScanner(FhirContext theContext, Class<? extends IResource> theResourceTypes) throws ConfigurationException {
|
ModelScanner(FhirContext theContext, Class<? extends IResource> theResourceTypes) throws ConfigurationException {
|
||||||
myContext=theContext;
|
myContext = theContext;
|
||||||
Set<Class<? extends IElement>> singleton = new HashSet<Class<? extends IElement>>();
|
Set<Class<? extends IElement>> singleton = new HashSet<Class<? extends IElement>>();
|
||||||
singleton.add(theResourceTypes);
|
singleton.add(theResourceTypes);
|
||||||
init(null, singleton);
|
init(null, singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelScanner(FhirContext theContext, Collection<Class<? extends IResource>> theResourceTypes) throws ConfigurationException {
|
ModelScanner(FhirContext theContext, Collection<Class<? extends IResource>> theResourceTypes) throws ConfigurationException {
|
||||||
myContext=theContext;
|
myContext = theContext;
|
||||||
init(null, new HashSet<Class<? extends IElement>>(theResourceTypes));
|
init(null, new HashSet<Class<? extends IElement>>(theResourceTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelScanner(FhirContext theContext, Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Collection<Class<? extends IResource>> theResourceTypes) throws ConfigurationException {
|
ModelScanner(FhirContext theContext, Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Collection<Class<? extends IResource>> theResourceTypes) throws ConfigurationException {
|
||||||
myContext=theContext;
|
myContext = theContext;
|
||||||
init(theExistingDefinitions, new HashSet<Class<? extends IElement>>(theResourceTypes));
|
Set<Class<? extends IElement>> toScan;
|
||||||
|
if (theResourceTypes != null) {
|
||||||
|
toScan = new HashSet<Class<? extends IElement>>(theResourceTypes);
|
||||||
|
} else {
|
||||||
|
toScan = new HashSet<Class<? extends IElement>>();
|
||||||
|
}
|
||||||
|
init(theExistingDefinitions, toScan);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> getClassToElementDefinitions() {
|
public Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> getClassToElementDefinitions() {
|
||||||
|
@ -175,13 +181,7 @@ class ModelScanner {
|
||||||
int startSize = myClassToElementDefinitions.size();
|
int startSize = myClassToElementDefinitions.size();
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
InputStream str = ModelScanner.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/fhirversion.properties");
|
InputStream str = myContext.getVersion().getFhirVersionPropertiesFile();
|
||||||
if (str == null) {
|
|
||||||
str = ModelScanner.class.getResourceAsStream("ca/uhn/fhir/model/dstu/fhirversion.properties");
|
|
||||||
}
|
|
||||||
if (str == null) {
|
|
||||||
throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/dstu/model.properties");
|
|
||||||
}
|
|
||||||
Properties prop = new Properties();
|
Properties prop = new Properties();
|
||||||
try {
|
try {
|
||||||
prop.load(str);
|
prop.load(str);
|
||||||
|
@ -386,13 +386,13 @@ class ModelScanner {
|
||||||
for (Field next : theClass.getDeclaredFields()) {
|
for (Field next : theClass.getDeclaredFields()) {
|
||||||
|
|
||||||
if (Modifier.isFinal(next.getModifiers())) {
|
if (Modifier.isFinal(next.getModifiers())) {
|
||||||
ourLog.trace("Ignoring constant {} on target type {}", next.getName(), theClass);
|
ourLog.trace("Ignoring constant {} on target type {}", next.getName(), theClass);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Child childAnnotation = next.getAnnotation(Child.class);
|
Child childAnnotation = next.getAnnotation(Child.class);
|
||||||
if (childAnnotation == null) {
|
if (childAnnotation == null) {
|
||||||
ourLog.trace("Ignoring non @Child field {} on target type {}",next.getName() , theClass);
|
ourLog.trace("Ignoring non @Child field {} on target type {}", next.getName(), theClass);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,8 +422,8 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (order == Child.REPLACE_PARENT) {
|
if (order == Child.REPLACE_PARENT) {
|
||||||
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT + ") but no parent element with extension URL " + extensionAttr.url()
|
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT + ") but no parent element with extension URL " + extensionAttr.url() + " could be found on type "
|
||||||
+ " could be found on type " + next.getDeclaringClass().getSimpleName());
|
+ next.getDeclaringClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -454,7 +454,7 @@ class ModelScanner {
|
||||||
int min = childAnnotation.min();
|
int min = childAnnotation.min();
|
||||||
int max = childAnnotation.max();
|
int max = childAnnotation.max();
|
||||||
/*
|
/*
|
||||||
* Anything that's marked as unknown is given a new ID that is <0 so that it doesn't conflict wityh any
|
* Anything that's marked as unknown is given a new ID that is <0 so that it doesn't conflict with any
|
||||||
* given IDs and can be figured out later
|
* given IDs and can be figured out later
|
||||||
*/
|
*/
|
||||||
while (order == Child.ORDER_UNKNOWN && orderMap.containsKey(order)) {
|
while (order == Child.ORDER_UNKNOWN && orderMap.containsKey(order)) {
|
||||||
|
|
|
@ -37,23 +37,27 @@ public class HapiLocalizer {
|
||||||
myBundle = ResourceBundle.getBundle(HapiLocalizer.class.getPackage().getName() + ".hapi-messages");
|
myBundle = ResourceBundle.getBundle(HapiLocalizer.class.getPackage().getName() + ".hapi-messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage(String theKey, Object... theParameters) {
|
public String getMessage(Class<?> theType, String theKey, Object... theParameters) {
|
||||||
|
return getMessage(theType.getName() + '.' + theKey, theParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage(String theQualifiedKey, Object... theParameters) {
|
||||||
if (theParameters != null && theParameters.length > 0) {
|
if (theParameters != null && theParameters.length > 0) {
|
||||||
MessageFormat format = myKeyToMessageFormat.get(theKey);
|
MessageFormat format = myKeyToMessageFormat.get(theQualifiedKey);
|
||||||
if (format != null) {
|
if (format != null) {
|
||||||
return format.format(theParameters).toString();
|
return format.format(theParameters).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
String formatString = myBundle.getString(theKey);
|
String formatString = myBundle.getString(theQualifiedKey);
|
||||||
if (formatString== null) {
|
if (formatString== null) {
|
||||||
formatString = "!MESSAGE!";
|
formatString = "!MESSAGE!";
|
||||||
}
|
}
|
||||||
|
|
||||||
format = new MessageFormat(formatString);
|
format = new MessageFormat(formatString);
|
||||||
myKeyToMessageFormat.put(theKey, format);
|
myKeyToMessageFormat.put(theQualifiedKey, format);
|
||||||
return format.format(theParameters).toString();
|
return format.format(theParameters).toString();
|
||||||
} else {
|
} else {
|
||||||
String retVal = myBundle.getString(theKey);
|
String retVal = myBundle.getString(theQualifiedKey);
|
||||||
if (retVal == null) {
|
if (retVal == null) {
|
||||||
retVal = "!MESSAGE!";
|
retVal = "!MESSAGE!";
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,20 +20,18 @@ package ca.uhn.fhir.model.api;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.gclient.StringClientParam;
|
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
import ca.uhn.fhir.model.api.annotation.SearchParamDefinition;
|
import ca.uhn.fhir.model.api.annotation.SearchParamDefinition;
|
||||||
|
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
|
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
|
||||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.rest.gclient.StringClientParam;
|
||||||
import ca.uhn.fhir.util.ElementUtil;
|
import ca.uhn.fhir.util.ElementUtil;
|
||||||
|
|
||||||
public abstract class BaseResource extends BaseElement implements IResource {
|
public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
|
@ -70,7 +68,7 @@ public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
@Child(name = "language", order = 0, min = 0, max = Child.MAX_UNLIMITED)
|
@Child(name = "language", order = 0, min = 0, max = Child.MAX_UNLIMITED)
|
||||||
private CodeDt myLanguage;
|
private CodeDt myLanguage;
|
||||||
|
|
||||||
private Map<ResourceMetadataKeyEnum<?>, Object> myResourceMetadata;
|
private ResourceMetadataMap myResourceMetadata;
|
||||||
|
|
||||||
@Child(name = "text", order = 1, min = 0, max = 1)
|
@Child(name = "text", order = 1, min = 0, max = 1)
|
||||||
private NarrativeDt myText;
|
private NarrativeDt myText;
|
||||||
|
@ -99,9 +97,9 @@ public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<ResourceMetadataKeyEnum<?>, Object> getResourceMetadata() {
|
public ResourceMetadataMap getResourceMetadata() {
|
||||||
if (myResourceMetadata == null) {
|
if (myResourceMetadata == null) {
|
||||||
myResourceMetadata = new HashMap<ResourceMetadataKeyEnum<?>, Object>();
|
myResourceMetadata = new ResourceMetadataMap();
|
||||||
}
|
}
|
||||||
return myResourceMetadata;
|
return myResourceMetadata;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +134,7 @@ public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setResourceMetadata(Map<ResourceMetadataKeyEnum<?>, Object> theMap) {
|
public void setResourceMetadata(ResourceMetadataMap theMap) {
|
||||||
Validate.notNull(theMap, "The Map must not be null");
|
Validate.notNull(theMap, "The Map must not be null");
|
||||||
myResourceMetadata = theMap;
|
myResourceMetadata = theMap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,17 +34,21 @@ import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
|
||||||
|
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
|
|
||||||
public class Bundle extends BaseBundle /* implements IElement */{
|
public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
|
|
||||||
|
private ResourceMetadataMap myResourceMetadata;
|
||||||
|
private BoundCodeDt<BundleTypeEnum> myType;
|
||||||
private StringDt myBundleId;
|
private StringDt myBundleId;
|
||||||
|
|
||||||
private TagList myCategories;
|
private TagList myCategories;
|
||||||
private List<BundleEntry> myEntries;
|
private List<BundleEntry> myEntries;
|
||||||
private volatile transient Map<IdDt, IResource> myIdToEntries;
|
private volatile transient Map<IdDt, IResource> myIdToEntries;
|
||||||
|
@ -60,7 +64,8 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
private InstantDt myUpdated;
|
private InstantDt myUpdated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Tags wil become immutable in a future release of HAPI, so {@link #addCategory(String, String, String)} should be used instead
|
* @deprecated Tags wil become immutable in a future release of HAPI, so
|
||||||
|
* {@link #addCategory(String, String, String)} should be used instead
|
||||||
*/
|
*/
|
||||||
public Tag addCategory() {
|
public Tag addCategory() {
|
||||||
Tag retVal = new Tag();
|
Tag retVal = new Tag();
|
||||||
|
@ -72,7 +77,6 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
getCategories().add(new Tag(theScheme, theTerm, theLabel));
|
getCategories().add(new Tag(theScheme, theTerm, theLabel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addCategory(Tag theTag) {
|
public void addCategory(Tag theTag) {
|
||||||
getCategories().add(theTag);
|
getCategories().add(theTag);
|
||||||
}
|
}
|
||||||
|
@ -208,6 +212,27 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StringDt getBundleId() {
|
||||||
|
if (myBundleId == null) {
|
||||||
|
myBundleId = new StringDt();
|
||||||
|
}
|
||||||
|
return myBundleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TagList getCategories() {
|
||||||
|
if (myCategories == null) {
|
||||||
|
myCategories = new TagList();
|
||||||
|
}
|
||||||
|
return myCategories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BundleEntry> getEntries() {
|
||||||
|
if (myEntries == null) {
|
||||||
|
myEntries = new ArrayList<BundleEntry>();
|
||||||
|
}
|
||||||
|
return myEntries;
|
||||||
|
}
|
||||||
|
|
||||||
// public static void main(String[] args) {
|
// public static void main(String[] args) {
|
||||||
//
|
//
|
||||||
// FhirContext ctx = new FhirContext();
|
// FhirContext ctx = new FhirContext();
|
||||||
|
@ -234,27 +259,6 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
||||||
public StringDt getBundleId() {
|
|
||||||
if (myBundleId == null) {
|
|
||||||
myBundleId = new StringDt();
|
|
||||||
}
|
|
||||||
return myBundleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TagList getCategories() {
|
|
||||||
if (myCategories == null) {
|
|
||||||
myCategories = new TagList();
|
|
||||||
}
|
|
||||||
return myCategories;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BundleEntry> getEntries() {
|
|
||||||
if (myEntries == null) {
|
|
||||||
myEntries = new ArrayList<BundleEntry>();
|
|
||||||
}
|
|
||||||
return myEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringDt getLinkBase() {
|
public StringDt getLinkBase() {
|
||||||
if (myLinkBase == null) {
|
if (myLinkBase == null) {
|
||||||
myLinkBase = new StringDt();
|
myLinkBase = new StringDt();
|
||||||
|
@ -307,9 +311,11 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
/**
|
/**
|
||||||
* Retrieves a resource from a bundle given its logical ID.
|
* Retrieves a resource from a bundle given its logical ID.
|
||||||
* <p>
|
* <p>
|
||||||
* <b>Important usage notes</b>: This method ignores base URLs (so passing in an ID of <code>http://foo/Patient/123</code> will return a resource if it has the logical ID of
|
* <b>Important usage notes</b>: This method ignores base URLs (so passing in an ID of
|
||||||
* <code>http://bar/Patient/123</code>. Also, this method is intended to be used for bundles which have already been populated. It will cache its results for fast performance, but that means that
|
* <code>http://foo/Patient/123</code> will return a resource if it has the logical ID of
|
||||||
* modifications to the bundle after this method is called may not be accurately reflected.
|
* <code>http://bar/Patient/123</code>. Also, this method is intended to be used for bundles which have already been
|
||||||
|
* populated. It will cache its results for fast performance, but that means that modifications to the bundle after
|
||||||
|
* this method is called may not be accurately reflected.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theId
|
* @param theId
|
||||||
|
@ -330,6 +336,13 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
return map.get(theId.toUnqualified());
|
return map.get(theId.toUnqualified());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ResourceMetadataMap getResourceMetadata() {
|
||||||
|
if (myResourceMetadata == null) {
|
||||||
|
myResourceMetadata = new ResourceMetadataMap();
|
||||||
|
}
|
||||||
|
return myResourceMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list containing all resources of the given type from this bundle
|
* Returns a list containing all resources of the given type from this bundle
|
||||||
*/
|
*/
|
||||||
|
@ -359,6 +372,13 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
return myTotalResults;
|
return myTotalResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BoundCodeDt<BundleTypeEnum> getType() {
|
||||||
|
if (myType == null) {
|
||||||
|
myType = new BoundCodeDt<BundleTypeEnum>(BundleTypeEnum.VALUESET_BINDER);
|
||||||
|
}
|
||||||
|
return myType;
|
||||||
|
}
|
||||||
|
|
||||||
public InstantDt getUpdated() {
|
public InstantDt getUpdated() {
|
||||||
if (myUpdated == null) {
|
if (myUpdated == null) {
|
||||||
myUpdated = new InstantDt();
|
myUpdated = new InstantDt();
|
||||||
|
@ -382,6 +402,10 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
myPublished = thePublished;
|
myPublished = thePublished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setType(BoundCodeDt<BundleTypeEnum> theType) {
|
||||||
|
myType = theType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of entries in this bundle
|
* Returns the number of entries in this bundle
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,9 +24,13 @@ import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.DecimalDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||||
|
import ca.uhn.fhir.model.valueset.BundleEntryStatusEnum;
|
||||||
import ca.uhn.fhir.util.ElementUtil;
|
import ca.uhn.fhir.util.ElementUtil;
|
||||||
|
|
||||||
public class BundleEntry extends BaseBundle {
|
public class BundleEntry extends BaseBundle {
|
||||||
|
@ -38,20 +42,61 @@ public class BundleEntry extends BaseBundle {
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
private TagList myCategories;
|
private TagList myCategories;
|
||||||
private InstantDt myDeletedAt;
|
private InstantDt myDeletedAt;
|
||||||
|
private CodeDt myDeletedResourceType;
|
||||||
|
private StringDt myDeletedResourceId;
|
||||||
|
private StringDt myDeletedResourceVersion;
|
||||||
|
|
||||||
|
public CodeDt getDeletedResourceType() {
|
||||||
|
if (myDeletedResourceType == null) {
|
||||||
|
myDeletedResourceType = new CodeDt();
|
||||||
|
}
|
||||||
|
return myDeletedResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeletedResourceType(CodeDt theDeletedResourceType) {
|
||||||
|
myDeletedResourceType = theDeletedResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getDeletedResourceId() {
|
||||||
|
if (myDeletedResourceId == null) {
|
||||||
|
myDeletedResourceId = new StringDt();
|
||||||
|
}
|
||||||
|
return myDeletedResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeletedResourceId(StringDt theDeletedResourceId) {
|
||||||
|
myDeletedResourceId = theDeletedResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDt getDeletedResourceVersion() {
|
||||||
|
if (myDeletedResourceVersion == null) {
|
||||||
|
myDeletedResourceVersion = new StringDt();
|
||||||
|
}
|
||||||
|
return myDeletedResourceVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeletedResourceVersion(StringDt theDeletedResourceVersion) {
|
||||||
|
myDeletedResourceVersion = theDeletedResourceVersion;
|
||||||
|
}
|
||||||
|
|
||||||
private StringDt myDeletedByEmail;
|
private StringDt myDeletedByEmail;
|
||||||
private StringDt myDeletedByName;
|
private StringDt myDeletedByName;
|
||||||
private StringDt myDeletedComment;
|
private StringDt myDeletedComment;
|
||||||
private StringDt myLinkAlternate;
|
private StringDt myLinkAlternate;
|
||||||
private StringDt myLinkSearch;
|
private StringDt myLinkSearch;
|
||||||
private StringDt myLinkSelf;
|
private StringDt myLinkSelf;
|
||||||
|
private StringDt myLinkBase;
|
||||||
private InstantDt myPublished;
|
private InstantDt myPublished;
|
||||||
private IResource myResource;
|
private IResource myResource;
|
||||||
private XhtmlDt mySummary;
|
private XhtmlDt mySummary;
|
||||||
private StringDt myTitle;
|
private StringDt myTitle;
|
||||||
private InstantDt myUpdated;
|
private InstantDt myUpdated;
|
||||||
|
private BoundCodeDt<BundleEntryStatusEnum> myStatus;
|
||||||
|
private DecimalDt myScore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Tags wil become immutable in a future release of HAPI, so {@link #addCategory(String, String, String)} should be used instead
|
* @deprecated Tags wil become immutable in a future release of HAPI, so
|
||||||
|
* {@link #addCategory(String, String, String)} should be used instead
|
||||||
*/
|
*/
|
||||||
public Tag addCategory() {
|
public Tag addCategory() {
|
||||||
Tag retVal = new Tag();
|
Tag retVal = new Tag();
|
||||||
|
@ -112,6 +157,13 @@ public class BundleEntry extends BaseBundle {
|
||||||
return myLinkAlternate;
|
return myLinkAlternate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StringDt getLinkBase() {
|
||||||
|
if (myLinkBase == null) {
|
||||||
|
myLinkBase = new StringDt();
|
||||||
|
}
|
||||||
|
return myLinkBase;
|
||||||
|
}
|
||||||
|
|
||||||
public StringDt getLinkSearch() {
|
public StringDt getLinkSearch() {
|
||||||
if (myLinkSearch == null) {
|
if (myLinkSearch == null) {
|
||||||
myLinkSearch = new StringDt();
|
myLinkSearch = new StringDt();
|
||||||
|
@ -137,6 +189,13 @@ public class BundleEntry extends BaseBundle {
|
||||||
return myResource;
|
return myResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BoundCodeDt<BundleEntryStatusEnum> getStatus() {
|
||||||
|
if (myStatus == null) {
|
||||||
|
myStatus = new BoundCodeDt<BundleEntryStatusEnum>(BundleEntryStatusEnum.VALUESET_BINDER);
|
||||||
|
}
|
||||||
|
return myStatus;
|
||||||
|
}
|
||||||
|
|
||||||
public XhtmlDt getSummary() {
|
public XhtmlDt getSummary() {
|
||||||
if (mySummary == null) {
|
if (mySummary == null) {
|
||||||
mySummary = new XhtmlDt();
|
mySummary = new XhtmlDt();
|
||||||
|
@ -162,7 +221,7 @@ public class BundleEntry extends BaseBundle {
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
return super.isEmpty() &&
|
return super.isEmpty() &&
|
||||||
ElementUtil.isEmpty(myCategories, myDeletedAt, myLinkAlternate, myLinkSelf, myPublished, myResource, mySummary, myTitle, myUpdated, myDeletedByEmail, myDeletedByName, myDeletedComment);
|
ElementUtil.isEmpty(myDeletedResourceId, myDeletedResourceType, myDeletedResourceVersion, myScore,myStatus, myCategories, myDeletedAt, myLinkAlternate, myLinkSelf, myPublished, myResource, mySummary, myTitle, myUpdated, myDeletedByEmail, myDeletedByName, myDeletedComment);
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +251,10 @@ public class BundleEntry extends BaseBundle {
|
||||||
myLinkAlternate = theLinkAlternate;
|
myLinkAlternate = theLinkAlternate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLinkBase(StringDt theLinkBase) {
|
||||||
|
myLinkBase = theLinkBase;
|
||||||
|
}
|
||||||
|
|
||||||
public void setLinkSearch(StringDt theLinkSearch) {
|
public void setLinkSearch(StringDt theLinkSearch) {
|
||||||
myLinkSearch = theLinkSearch;
|
myLinkSearch = theLinkSearch;
|
||||||
}
|
}
|
||||||
|
@ -212,6 +275,10 @@ public class BundleEntry extends BaseBundle {
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStatus(BoundCodeDt<BundleEntryStatusEnum> theStatus) {
|
||||||
|
myStatus = theStatus;
|
||||||
|
}
|
||||||
|
|
||||||
public void setUpdated(InstantDt theUpdated) {
|
public void setUpdated(InstantDt theUpdated) {
|
||||||
Validate.notNull(theUpdated, "Updated may not be null");
|
Validate.notNull(theUpdated, "Updated may not be null");
|
||||||
myUpdated = theUpdated;
|
myUpdated = theUpdated;
|
||||||
|
@ -229,4 +296,15 @@ public class BundleEntry extends BaseBundle {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DecimalDt getScore() {
|
||||||
|
if (myScore == null) {
|
||||||
|
myScore = new DecimalDt();
|
||||||
|
}
|
||||||
|
return myScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScore(DecimalDt theScore) {
|
||||||
|
myScore = theScore;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,16 +20,23 @@ package ca.uhn.fhir.model.api;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
|
||||||
public interface IFhirVersion {
|
public interface IFhirVersion {
|
||||||
|
|
||||||
|
FhirVersionEnum getVersion();
|
||||||
|
|
||||||
IResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition);
|
IResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition);
|
||||||
|
|
||||||
Object createServerConformanceProvider(RestfulServer theServer);
|
Object createServerConformanceProvider(RestfulServer theServer);
|
||||||
|
|
||||||
IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer);
|
IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer);
|
||||||
|
|
||||||
|
InputStream getFhirVersionPropertiesFile();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.model.api;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||||
|
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
|
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
|
||||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
|
@ -88,7 +89,7 @@ public interface IResource extends ICompositeElement {
|
||||||
* @see ResourceMetadataKeyEnum for a list of allowable keys and the object
|
* @see ResourceMetadataKeyEnum for a list of allowable keys and the object
|
||||||
* types that values of a given key must use.
|
* types that values of a given key must use.
|
||||||
*/
|
*/
|
||||||
Map<ResourceMetadataKeyEnum<?>, Object> getResourceMetadata();
|
ResourceMetadataMap getResourceMetadata();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the narrative block for this resource
|
* Returns the narrative block for this resource
|
||||||
|
@ -122,7 +123,7 @@ public interface IResource extends ICompositeElement {
|
||||||
* @throws NullPointerException
|
* @throws NullPointerException
|
||||||
* The map must not be null
|
* The map must not be null
|
||||||
*/
|
*/
|
||||||
void setResourceMetadata(Map<ResourceMetadataKeyEnum<?>, Object> theMap);
|
void setResourceMetadata(ResourceMetadataMap theMap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a String representing the name of this Resource. This return
|
* Returns a String representing the name of this Resource. This return
|
||||||
|
|
|
@ -206,6 +206,24 @@ public abstract class ResourceMetadataKeyEnum<T> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value for this key is the version ID of the resource object.
|
||||||
|
* <p>
|
||||||
|
* Values for this key are of type <b>{@link String}</b>
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public static final ResourceMetadataKeyEnum<String> VERSION = new ResourceMetadataKeyEnum<String>("VERSION") {
|
||||||
|
@Override
|
||||||
|
public String get(IResource theResource) {
|
||||||
|
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(IResource theResource, String theObject) {
|
||||||
|
theResource.getResourceMetadata().put(VERSION, theObject);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If present and populated with a string, provides the "search link" (the link element in the bundle entry with <code>rel="search"</code>). Server implementations may populate this with a
|
* If present and populated with a string, provides the "search link" (the link element in the bundle entry with <code>rel="search"</code>). Server implementations may populate this with a
|
||||||
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient?name=tester") in which case the server will convert
|
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient?name=tester") in which case the server will convert
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ca.uhn.fhir.model.base.resource;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
|
|
||||||
|
public class ResourceMetadataMap extends HashMap<ResourceMetadataKeyEnum<?>, Object> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
import ca.uhn.fhir.model.api.annotation.Description;
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
@ -86,6 +87,7 @@ public class ResourceReferenceDt
|
||||||
* @param theResource
|
* @param theResource
|
||||||
* The resource instance
|
* The resource instance
|
||||||
*/
|
*/
|
||||||
|
@SimpleSetter()
|
||||||
public ResourceReferenceDt(IResource theResource) {
|
public ResourceReferenceDt(IResource theResource) {
|
||||||
super(theResource);
|
super(theResource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
|
import org.hamcrest.core.IsNot;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
@ -134,6 +135,23 @@ public class IdDt implements IPrimitiveDatatype<String> {
|
||||||
* The version ID ("e.g. "456")
|
* The version ID ("e.g. "456")
|
||||||
*/
|
*/
|
||||||
public IdDt(String theResourceType, String theId, String theVersionId) {
|
public IdDt(String theResourceType, String theId, String theVersionId) {
|
||||||
|
this(null,theResourceType,theId,theVersionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param theBaseUrl
|
||||||
|
* The server base URL (e.g. "http://example.com/fhir")
|
||||||
|
* @param theResourceType
|
||||||
|
* The resource type (e.g. "Patient")
|
||||||
|
* @param theId
|
||||||
|
* The ID (e.g. "123")
|
||||||
|
* @param theVersionId
|
||||||
|
* The version ID ("e.g. "456")
|
||||||
|
*/
|
||||||
|
public IdDt(String theBaseUrl, String theResourceType, String theId, String theVersionId) {
|
||||||
|
myBaseUrl = theBaseUrl;
|
||||||
myResourceType = theResourceType;
|
myResourceType = theResourceType;
|
||||||
myUnqualifiedId = theId;
|
myUnqualifiedId = theId;
|
||||||
myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionId, null);
|
myUnqualifiedVersionId = StringUtils.defaultIfBlank(theVersionId, null);
|
||||||
|
@ -242,10 +260,21 @@ public class IdDt implements IPrimitiveDatatype<String> {
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
if (myValue == null && myHaveComponentParts) {
|
if (myValue == null && myHaveComponentParts) {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
|
if (isNotBlank(myBaseUrl)) {
|
||||||
|
b.append(myBaseUrl);
|
||||||
|
if (myBaseUrl.charAt(myBaseUrl.length()-1)!='/') {
|
||||||
|
b.append('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isNotBlank(myResourceType)) {
|
if (isNotBlank(myResourceType)) {
|
||||||
b.append(myResourceType);
|
b.append(myResourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.length() > 0) {
|
||||||
b.append('/');
|
b.append('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
b.append(myUnqualifiedId);
|
b.append(myUnqualifiedId);
|
||||||
if (isNotBlank(myUnqualifiedVersionId)) {
|
if (isNotBlank(myUnqualifiedVersionId)) {
|
||||||
b.append('/');
|
b.append('/');
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
|
||||||
|
package ca.uhn.fhir.model.valueset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||||
|
|
||||||
|
public enum BundleEntryStatusEnum {
|
||||||
|
|
||||||
|
CREATE("create", "http://hl7.org/fhir/bundle-entry-status"),
|
||||||
|
UPDATE("update", "http://hl7.org/fhir/bundle-entry-status"),
|
||||||
|
MATCH("match", "http://hl7.org/fhir/bundle-entry-status"),
|
||||||
|
INCLUDE("include", "http://hl7.org/fhir/bundle-entry-status"),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifier for this Value Set:
|
||||||
|
* http://hl7.org/fhir/vs/address-use
|
||||||
|
*/
|
||||||
|
public static final String VALUESET_IDENTIFIER = "http://hl7.org/fhir/bundle-entry-status";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name for this Value Set:
|
||||||
|
* AddressUse
|
||||||
|
*/
|
||||||
|
public static final String VALUESET_NAME = "BundleEntryStatus";
|
||||||
|
|
||||||
|
private static Map<String, BundleEntryStatusEnum> CODE_TO_ENUM = new HashMap<String, BundleEntryStatusEnum>();
|
||||||
|
private static Map<String, Map<String, BundleEntryStatusEnum>> SYSTEM_TO_CODE_TO_ENUM = new HashMap<String, Map<String, BundleEntryStatusEnum>>();
|
||||||
|
|
||||||
|
private final String myCode;
|
||||||
|
private final String mySystem;
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (BundleEntryStatusEnum next : BundleEntryStatusEnum.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, BundleEntryStatusEnum>());
|
||||||
|
}
|
||||||
|
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 BundleEntryStatusEnum forCode(String theCode) {
|
||||||
|
BundleEntryStatusEnum retVal = CODE_TO_ENUM.get(theCode);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts codes to their respective enumerated values
|
||||||
|
*/
|
||||||
|
public static final IValueSetEnumBinder<BundleEntryStatusEnum> VALUESET_BINDER = new IValueSetEnumBinder<BundleEntryStatusEnum>() {
|
||||||
|
@Override
|
||||||
|
public String toCodeString(BundleEntryStatusEnum theEnum) {
|
||||||
|
return theEnum.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toSystemString(BundleEntryStatusEnum theEnum) {
|
||||||
|
return theEnum.getSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BundleEntryStatusEnum fromCodeString(String theCodeString) {
|
||||||
|
return CODE_TO_ENUM.get(theCodeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BundleEntryStatusEnum fromCodeString(String theCodeString, String theSystemString) {
|
||||||
|
Map<String, BundleEntryStatusEnum> map = SYSTEM_TO_CODE_TO_ENUM.get(theSystemString);
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return map.get(theCodeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
BundleEntryStatusEnum(String theCode, String theSystem) {
|
||||||
|
myCode = theCode;
|
||||||
|
mySystem = theSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
|
||||||
|
package ca.uhn.fhir.model.valueset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||||
|
|
||||||
|
public enum BundleTypeEnum {
|
||||||
|
|
||||||
|
TRANSACTION("transaction", "http://hl7.org/fhir/bundle-type"),
|
||||||
|
|
||||||
|
DOCUMENT("document", "http://hl7.org/fhir/bundle-type"),
|
||||||
|
|
||||||
|
MESSAGE("message", "http://hl7.org/fhir/bundle-type"),
|
||||||
|
|
||||||
|
TRANSACTION_RESPONSE("transaction-response", "http://hl7.org/fhir/bundle-type"),
|
||||||
|
|
||||||
|
HISTORY("history", "http://hl7.org/fhir/bundle-type"),
|
||||||
|
|
||||||
|
SEARCHSET("searchset", "http://hl7.org/fhir/bundle-type"),
|
||||||
|
|
||||||
|
COLLECTION("collection", "http://hl7.org/fhir/bundle-type"),
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifier for this Value Set:
|
||||||
|
* http://hl7.org/fhir/vs/address-use
|
||||||
|
*/
|
||||||
|
public static final String VALUESET_IDENTIFIER = "http://hl7.org/fhir/bundle-type";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name for this Value Set:
|
||||||
|
* AddressUse
|
||||||
|
*/
|
||||||
|
public static final String VALUESET_NAME = "BundleType";
|
||||||
|
|
||||||
|
private static Map<String, BundleTypeEnum> CODE_TO_ENUM = new HashMap<String, BundleTypeEnum>();
|
||||||
|
private static Map<String, Map<String, BundleTypeEnum>> SYSTEM_TO_CODE_TO_ENUM = new HashMap<String, Map<String, BundleTypeEnum>>();
|
||||||
|
|
||||||
|
private final String myCode;
|
||||||
|
private final String mySystem;
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (BundleTypeEnum next : BundleTypeEnum.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, BundleTypeEnum>());
|
||||||
|
}
|
||||||
|
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 BundleTypeEnum forCode(String theCode) {
|
||||||
|
BundleTypeEnum retVal = CODE_TO_ENUM.get(theCode);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts codes to their respective enumerated values
|
||||||
|
*/
|
||||||
|
public static final IValueSetEnumBinder<BundleTypeEnum> VALUESET_BINDER = new IValueSetEnumBinder<BundleTypeEnum>() {
|
||||||
|
@Override
|
||||||
|
public String toCodeString(BundleTypeEnum theEnum) {
|
||||||
|
return theEnum.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toSystemString(BundleTypeEnum theEnum) {
|
||||||
|
return theEnum.getSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BundleTypeEnum fromCodeString(String theCodeString) {
|
||||||
|
return CODE_TO_ENUM.get(theCodeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BundleTypeEnum fromCodeString(String theCodeString, String theSystemString) {
|
||||||
|
Map<String, BundleTypeEnum> map = SYSTEM_TO_CODE_TO_ENUM.get(theSystemString);
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return map.get(theCodeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
BundleTypeEnum(String theCode, String theSystem) {
|
||||||
|
myCode = theCode;
|
||||||
|
mySystem = theSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.json.Json;
|
import javax.json.Json;
|
||||||
import javax.json.JsonArray;
|
import javax.json.JsonArray;
|
||||||
|
import javax.json.JsonNumber;
|
||||||
import javax.json.JsonObject;
|
import javax.json.JsonObject;
|
||||||
import javax.json.JsonReader;
|
import javax.json.JsonReader;
|
||||||
import javax.json.JsonString;
|
import javax.json.JsonString;
|
||||||
|
@ -56,6 +57,7 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeChildNarrativeDefinition;
|
import ca.uhn.fhir.context.RuntimeChildNarrativeDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
|
import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
|
||||||
|
@ -86,22 +88,32 @@ import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||||
|
|
||||||
public class JsonParser extends BaseParser implements IParser {
|
public class JsonParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
private static final Set<String> BUNDLE_TEXTNODE_CHILDREN;
|
private static final Set<String> BUNDLE_TEXTNODE_CHILDREN_DSTU1;
|
||||||
|
private static final Set<String> BUNDLE_TEXTNODE_CHILDREN_DSTU2;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParser.HeldExtension.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParser.HeldExtension.class);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
HashSet<String> hashSet = new HashSet<String>();
|
HashSet<String> hashSetDstu1 = new HashSet<String>();
|
||||||
hashSet.add("title");
|
hashSetDstu1.add("title");
|
||||||
hashSet.add("id");
|
hashSetDstu1.add("id");
|
||||||
hashSet.add("updated");
|
hashSetDstu1.add("updated");
|
||||||
hashSet.add("published");
|
hashSetDstu1.add("published");
|
||||||
BUNDLE_TEXTNODE_CHILDREN = Collections.unmodifiableSet(hashSet);
|
BUNDLE_TEXTNODE_CHILDREN_DSTU1 = Collections.unmodifiableSet(hashSetDstu1);
|
||||||
|
|
||||||
|
HashSet<String> hashSetDstu2 = new HashSet<String>();
|
||||||
|
hashSetDstu2.add("type");
|
||||||
|
hashSetDstu2.add("base");
|
||||||
|
hashSetDstu2.add("total");
|
||||||
|
BUNDLE_TEXTNODE_CHILDREN_DSTU2 = Collections.unmodifiableSet(hashSetDstu2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
|
||||||
private boolean myPrettyPrint;
|
private boolean myPrettyPrint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not use this constructor, the recommended way to obtain a new instance of the JSON parser is to invoke
|
||||||
|
* {@link FhirContext#newJsonParser()}.
|
||||||
|
*/
|
||||||
public JsonParser(FhirContext theContext) {
|
public JsonParser(FhirContext theContext) {
|
||||||
super(theContext);
|
super(theContext);
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
|
@ -145,6 +157,15 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
@Override
|
@Override
|
||||||
public void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws IOException {
|
public void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws IOException {
|
||||||
JsonGenerator eventWriter = createJsonGenerator(theWriter);
|
JsonGenerator eventWriter = createJsonGenerator(theWriter);
|
||||||
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
|
encodeBundleToWriterInDstu2Format(theBundle, eventWriter);
|
||||||
|
}else {
|
||||||
|
encodeBundleToWriterInDstu1Format(theBundle, eventWriter);
|
||||||
|
}
|
||||||
|
eventWriter.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void encodeBundleToWriterInDstu1Format(Bundle theBundle, JsonGenerator eventWriter) throws IOException {
|
||||||
eventWriter.writeStartObject();
|
eventWriter.writeStartObject();
|
||||||
|
|
||||||
eventWriter.write("resourceType", "Bundle");
|
eventWriter.write("resourceType", "Bundle");
|
||||||
|
@ -155,12 +176,12 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
||||||
|
|
||||||
boolean linkStarted = false;
|
boolean linkStarted = false;
|
||||||
linkStarted = writeAtomLink(eventWriter, "self", theBundle.getLinkSelf(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", theBundle.getLinkSelf(), linkStarted);
|
||||||
linkStarted = writeAtomLink(eventWriter, "first", theBundle.getLinkFirst(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "first", theBundle.getLinkFirst(), linkStarted);
|
||||||
linkStarted = writeAtomLink(eventWriter, "previous", theBundle.getLinkPrevious(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "previous", theBundle.getLinkPrevious(), linkStarted);
|
||||||
linkStarted = writeAtomLink(eventWriter, "next", theBundle.getLinkNext(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "next", theBundle.getLinkNext(), linkStarted);
|
||||||
linkStarted = writeAtomLink(eventWriter, "last", theBundle.getLinkLast(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "last", theBundle.getLinkLast(), linkStarted);
|
||||||
linkStarted = writeAtomLink(eventWriter, "fhir-base", theBundle.getLinkBase(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "fhir-base", theBundle.getLinkBase(), linkStarted);
|
||||||
if (linkStarted) {
|
if (linkStarted) {
|
||||||
eventWriter.writeEnd();
|
eventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
@ -183,9 +204,9 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
writeTagWithTextNode(eventWriter, "id", nextEntry.getId());
|
writeTagWithTextNode(eventWriter, "id", nextEntry.getId());
|
||||||
|
|
||||||
linkStarted = false;
|
linkStarted = false;
|
||||||
linkStarted = writeAtomLink(eventWriter, "self", nextEntry.getLinkSelf(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", nextEntry.getLinkSelf(), linkStarted);
|
||||||
linkStarted = writeAtomLink(eventWriter, "alternate", nextEntry.getLinkAlternate(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "alternate", nextEntry.getLinkAlternate(), linkStarted);
|
||||||
linkStarted = writeAtomLink(eventWriter, "search", nextEntry.getLinkSearch(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "search", nextEntry.getLinkSearch(), linkStarted);
|
||||||
if (linkStarted) {
|
if (linkStarted) {
|
||||||
eventWriter.writeEnd();
|
eventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
@ -203,7 +224,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
encodeResourceToJsonStreamWriter(resDef, resource, eventWriter, "content", false);
|
encodeResourceToJsonStreamWriter(resDef, resource, eventWriter, "content", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextEntry.getSummary().isEmpty()==false) {
|
if (nextEntry.getSummary().isEmpty() == false) {
|
||||||
eventWriter.write("summary", nextEntry.getSummary().getValueAsString());
|
eventWriter.write("summary", nextEntry.getSummary().getValueAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,25 +233,71 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
eventWriter.writeEnd(); // entry array
|
eventWriter.writeEnd(); // entry array
|
||||||
|
|
||||||
eventWriter.writeEnd();
|
eventWriter.writeEnd();
|
||||||
eventWriter.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeCategories(JsonGenerator eventWriter, TagList categories) {
|
private void encodeBundleToWriterInDstu2Format(Bundle theBundle, JsonGenerator eventWriter) throws IOException {
|
||||||
if (categories != null && categories.size() > 0) {
|
eventWriter.writeStartObject();
|
||||||
eventWriter.writeStartArray("category");
|
|
||||||
for (Tag next : categories) {
|
eventWriter.write("resourceType", "Bundle");
|
||||||
eventWriter.writeStartObject();
|
|
||||||
eventWriter.write("term", defaultString(next.getTerm()));
|
writeTagWithTextNode(eventWriter, "id", theBundle.getId().getIdPart());
|
||||||
eventWriter.write("label", defaultString(next.getLabel()));
|
writeOptionalTagWithTextNode(eventWriter, "type", theBundle.getType());
|
||||||
eventWriter.write("scheme", defaultString(next.getScheme()));
|
writeOptionalTagWithTextNode(eventWriter, "base", theBundle.getLinkBase());
|
||||||
eventWriter.writeEnd();
|
writeOptionalTagWithNumberNode(eventWriter, "base", theBundle.getTotalResults());
|
||||||
}
|
|
||||||
|
boolean linkStarted = false;
|
||||||
|
linkStarted = writeAtomLinkInDstu2Format(eventWriter, "self", theBundle.getLinkSelf(), linkStarted);
|
||||||
|
linkStarted = writeAtomLinkInDstu2Format(eventWriter, "first", theBundle.getLinkFirst(), linkStarted);
|
||||||
|
linkStarted = writeAtomLinkInDstu2Format(eventWriter, "previous", theBundle.getLinkPrevious(), linkStarted);
|
||||||
|
linkStarted = writeAtomLinkInDstu2Format(eventWriter, "next", theBundle.getLinkNext(), linkStarted);
|
||||||
|
linkStarted = writeAtomLinkInDstu2Format(eventWriter, "last", theBundle.getLinkLast(), linkStarted);
|
||||||
|
if (linkStarted) {
|
||||||
eventWriter.writeEnd();
|
eventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventWriter.writeStartArray("entry");
|
||||||
|
for (BundleEntry nextEntry : theBundle.getEntries()) {
|
||||||
|
eventWriter.writeStartObject();
|
||||||
|
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "base", nextEntry.getLinkBase());
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "status", nextEntry.getStatus());
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "search", nextEntry.getLinkSearch());
|
||||||
|
writeOptionalTagWithDecimalNode(eventWriter, "score", nextEntry.getScore());
|
||||||
|
|
||||||
|
linkStarted = false;
|
||||||
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", nextEntry.getLinkSelf(), linkStarted);
|
||||||
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "alternate", nextEntry.getLinkAlternate(), linkStarted);
|
||||||
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "search", nextEntry.getLinkSearch(), linkStarted);
|
||||||
|
if (linkStarted) {
|
||||||
|
eventWriter.writeEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "updated", nextEntry.getUpdated());
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "published", nextEntry.getPublished());
|
||||||
|
|
||||||
|
writeCategories(eventWriter, nextEntry.getCategories());
|
||||||
|
|
||||||
|
writeAuthor(nextEntry, eventWriter);
|
||||||
|
|
||||||
|
IResource resource = nextEntry.getResource();
|
||||||
|
if (resource != null && !resource.isEmpty() && !deleted) {
|
||||||
|
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(resource);
|
||||||
|
encodeResourceToJsonStreamWriter(resDef, resource, eventWriter, "content", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextEntry.getSummary().isEmpty() == false) {
|
||||||
|
eventWriter.write("summary", nextEntry.getSummary().getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
eventWriter.writeEnd(); // entry object
|
||||||
|
}
|
||||||
|
eventWriter.writeEnd(); // entry array
|
||||||
|
|
||||||
|
eventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theWriter, IElement theValue, BaseRuntimeElementDefinition<?> theChildDef,
|
|
||||||
String theChildName, boolean theIsSubElementWithinResource) throws IOException {
|
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theWriter, IElement theValue, BaseRuntimeElementDefinition<?> theChildDef, String theChildName, boolean theIsSubElementWithinResource) throws IOException {
|
||||||
|
|
||||||
switch (theChildDef.getChildType()) {
|
switch (theChildDef.getChildType()) {
|
||||||
case PRIMITIVE_DATATYPE: {
|
case PRIMITIVE_DATATYPE: {
|
||||||
|
@ -305,7 +372,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
theWriter.writeStartArray(theChildName);
|
theWriter.writeStartArray(theChildName);
|
||||||
ContainedDt value = (ContainedDt) theValue;
|
ContainedDt value = (ContainedDt) theValue;
|
||||||
for (IResource next : value.getContainedResources()) {
|
for (IResource next : value.getContainedResources()) {
|
||||||
if (getContainedResources().getResourceId(next)!=null) {
|
if (getContainedResources().getResourceId(next) != null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true, fixContainedResourceId(next.getId().getValue()));
|
encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true, fixContainedResourceId(next.getId().getValue()));
|
||||||
|
@ -341,8 +408,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter,
|
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter, List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException {
|
||||||
List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException {
|
|
||||||
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
||||||
if (nextChild instanceof RuntimeChildNarrativeDefinition) {
|
if (nextChild instanceof RuntimeChildNarrativeDefinition) {
|
||||||
INarrativeGenerator gen = myContext.getNarrativeGenerator();
|
INarrativeGenerator gen = myContext.getNarrativeGenerator();
|
||||||
|
@ -395,12 +461,13 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
if (nextChild instanceof RuntimeChildDeclaredExtensionDefinition) {
|
if (nextChild instanceof RuntimeChildDeclaredExtensionDefinition) {
|
||||||
// Don't encode extensions
|
// Don't encode extensions
|
||||||
// RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition) nextChild;
|
// RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition)
|
||||||
// if (extDef.isModifier()) {
|
// nextChild;
|
||||||
// addToHeldExtensions(valueIdx, modifierExtensions, extDef, nextValue);
|
// if (extDef.isModifier()) {
|
||||||
// } else {
|
// addToHeldExtensions(valueIdx, modifierExtensions, extDef, nextValue);
|
||||||
// addToHeldExtensions(valueIdx, extensions, extDef, nextValue);
|
// } else {
|
||||||
// }
|
// addToHeldExtensions(valueIdx, extensions, extDef, nextValue);
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (currentChildName == null || !currentChildName.equals(childName)) {
|
if (currentChildName == null || !currentChildName.equals(childName)) {
|
||||||
|
@ -465,15 +532,13 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter,
|
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, JsonGenerator theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIsSubElementWithinResource) throws IOException, DataFormatException {
|
||||||
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIsSubElementWithinResource) throws IOException, DataFormatException {
|
|
||||||
extractAndWriteExtensionsAsDirectChild(theElement, theEventWriter, resDef, theResDef, theResource);
|
extractAndWriteExtensionsAsDirectChild(theElement, theEventWriter, resDef, theResDef, theResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions(), theIsSubElementWithinResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions(), theIsSubElementWithinResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren(),theIsSubElementWithinResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren(), theIsSubElementWithinResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull,
|
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theIsSubElementWithinResource) throws IOException {
|
||||||
boolean theIsSubElementWithinResource) throws IOException {
|
|
||||||
String resourceId = null;
|
String resourceId = null;
|
||||||
if (theIsSubElementWithinResource && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
if (theIsSubElementWithinResource && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
||||||
resourceId = theResource.getId().getValue();
|
resourceId = theResource.getId().getValue();
|
||||||
|
@ -482,8 +547,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
encodeResourceToJsonStreamWriter(theResDef, theResource, theEventWriter, theObjectNameOrNull, theIsSubElementWithinResource, resourceId);
|
encodeResourceToJsonStreamWriter(theResDef, theResource, theEventWriter, theObjectNameOrNull, theIsSubElementWithinResource, resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theIsSubElementWithinResource,
|
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theIsSubElementWithinResource, String theResourceId) throws IOException {
|
||||||
String theResourceId) throws IOException {
|
|
||||||
if (!theIsSubElementWithinResource) {
|
if (!theIsSubElementWithinResource) {
|
||||||
super.containResourcesForEncoding(theResource);
|
super.containResourcesForEncoding(theResource);
|
||||||
}
|
}
|
||||||
|
@ -553,10 +617,10 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is useful only for the two cases where extensions are encoded as direct children (e.g. not in some object called _name): resource extensions, and extension extensions
|
* This is useful only for the two cases where extensions are encoded as direct children (e.g. not in some object
|
||||||
|
* called _name): resource extensions, and extension extensions
|
||||||
*/
|
*/
|
||||||
private void extractAndWriteExtensionsAsDirectChild(IElement theElement, JsonGenerator theEventWriter, BaseRuntimeElementDefinition<?> theElementDef, RuntimeResourceDefinition theResDef,
|
private void extractAndWriteExtensionsAsDirectChild(IElement theElement, JsonGenerator theEventWriter, BaseRuntimeElementDefinition<?> theElementDef, RuntimeResourceDefinition theResDef, IResource theResource) throws IOException {
|
||||||
IResource theResource) throws IOException {
|
|
||||||
List<HeldExtension> extensions = new ArrayList<HeldExtension>(0);
|
List<HeldExtension> extensions = new ArrayList<HeldExtension>(0);
|
||||||
List<HeldExtension> modifierExtensions = new ArrayList<HeldExtension>(0);
|
List<HeldExtension> modifierExtensions = new ArrayList<HeldExtension>(0);
|
||||||
|
|
||||||
|
@ -665,7 +729,11 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
ParserState<Bundle> state = ParserState.getPreAtomInstance(myContext, theResourceType, true);
|
ParserState<Bundle> state = ParserState.getPreAtomInstance(myContext, theResourceType, true);
|
||||||
state.enteringNewElement(null, "feed");
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
|
state.enteringNewElement(null, "Bundle");
|
||||||
|
} else {
|
||||||
|
state.enteringNewElement(null, "feed");
|
||||||
|
}
|
||||||
|
|
||||||
parseBundleChildren(object, state);
|
parseBundleChildren(object, state);
|
||||||
|
|
||||||
|
@ -680,18 +748,6 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
for (String nextName : theObject.keySet()) {
|
for (String nextName : theObject.keySet()) {
|
||||||
if ("resourceType".equals(nextName)) {
|
if ("resourceType".equals(nextName)) {
|
||||||
continue;
|
continue;
|
||||||
} else if ("link".equals(nextName)) {
|
|
||||||
JsonArray entries = theObject.getJsonArray(nextName);
|
|
||||||
for (JsonValue jsonValue : entries) {
|
|
||||||
theState.enteringNewElement(null, "link");
|
|
||||||
JsonObject linkObj = (JsonObject) jsonValue;
|
|
||||||
String rel = linkObj.getString("rel", null);
|
|
||||||
String href = linkObj.getString("href", null);
|
|
||||||
theState.attributeValue("rel", rel);
|
|
||||||
theState.attributeValue("href", href);
|
|
||||||
theState.endingElement();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
} else if ("entry".equals(nextName)) {
|
} else if ("entry".equals(nextName)) {
|
||||||
JsonArray entries = theObject.getJsonArray(nextName);
|
JsonArray entries = theObject.getJsonArray(nextName);
|
||||||
for (JsonValue jsonValue : entries) {
|
for (JsonValue jsonValue : entries) {
|
||||||
|
@ -700,11 +756,60 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
theState.endingElement();
|
theState.endingElement();
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (BUNDLE_TEXTNODE_CHILDREN.contains(nextName)) {
|
} else if (myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
|
||||||
theState.enteringNewElement(null, nextName);
|
if ("link".equals(nextName)) {
|
||||||
theState.string(theObject.getString(nextName, null));
|
JsonArray entries = theObject.getJsonArray(nextName);
|
||||||
theState.endingElement();
|
for (JsonValue jsonValue : entries) {
|
||||||
continue;
|
theState.enteringNewElement(null, "link");
|
||||||
|
JsonObject linkObj = (JsonObject) jsonValue;
|
||||||
|
String rel = linkObj.getString("rel", null);
|
||||||
|
String href = linkObj.getString("href", null);
|
||||||
|
theState.attributeValue("rel", rel);
|
||||||
|
theState.attributeValue("href", href);
|
||||||
|
theState.endingElement();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (BUNDLE_TEXTNODE_CHILDREN_DSTU1.contains(nextName)) {
|
||||||
|
theState.enteringNewElement(null, nextName);
|
||||||
|
theState.string(theObject.getString(nextName, null));
|
||||||
|
theState.endingElement();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ("link".equals(nextName)) {
|
||||||
|
JsonArray entries = theObject.getJsonArray(nextName);
|
||||||
|
for (JsonValue jsonValue : entries) {
|
||||||
|
theState.enteringNewElement(null, "link");
|
||||||
|
JsonObject linkObj = (JsonObject) jsonValue;
|
||||||
|
String rel = linkObj.getString("relation", null);
|
||||||
|
String href = linkObj.getString("url", null);
|
||||||
|
theState.enteringNewElement(null, "relation");
|
||||||
|
theState.attributeValue("value", rel);
|
||||||
|
theState.endingElement();
|
||||||
|
theState.enteringNewElement(null, "url");
|
||||||
|
theState.attributeValue("value", href);
|
||||||
|
theState.endingElement();
|
||||||
|
theState.endingElement();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (BUNDLE_TEXTNODE_CHILDREN_DSTU2.contains(nextName)) {
|
||||||
|
theState.enteringNewElement(null, nextName);
|
||||||
|
// String obj = theObject.getString(nextName, null);
|
||||||
|
|
||||||
|
JsonValue obj = theObject.get(nextName);
|
||||||
|
if (obj == null) {
|
||||||
|
theState.attributeValue("value", null);
|
||||||
|
} else if (obj instanceof JsonString) {
|
||||||
|
theState.attributeValue("value", theObject.getString(nextName, null));
|
||||||
|
} else if (obj instanceof JsonNumber) {
|
||||||
|
theState.attributeValue("value", obj.toString());
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Unexpected JSON object for entry '" + nextName + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
theState.endingElement();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonValue nextVal = theObject.get(nextName);
|
JsonValue nextVal = theObject.get(nextName);
|
||||||
|
@ -720,7 +825,9 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
continue;
|
continue;
|
||||||
} else if ("id".equals(nextName)) {
|
} else if ("id".equals(nextName)) {
|
||||||
elementId = theObject.getString(nextName);
|
elementId = theObject.getString(nextName);
|
||||||
continue;
|
// if (myContext.getVersion().getVersion()==FhirVersionEnum.DSTU1) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
} else if ("_id".equals(nextName)) {
|
} else if ("_id".equals(nextName)) {
|
||||||
// _id is incorrect, but some early examples in the FHIR spec used it
|
// _id is incorrect, but some early examples in the FHIR spec used it
|
||||||
elementId = theObject.getString(nextName);
|
elementId = theObject.getString(nextName);
|
||||||
|
@ -893,7 +1000,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean writeAtomLink(JsonGenerator theEventWriter, String theRel, StringDt theLink, boolean theStarted) {
|
private boolean writeAtomLinkInDstu1Format(JsonGenerator theEventWriter, String theRel, StringDt theLink, boolean theStarted) {
|
||||||
boolean retVal = theStarted;
|
boolean retVal = theStarted;
|
||||||
if (isNotBlank(theLink.getValue())) {
|
if (isNotBlank(theLink.getValue())) {
|
||||||
if (theStarted == false) {
|
if (theStarted == false) {
|
||||||
|
@ -909,6 +1016,21 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean writeAtomLinkInDstu2Format(JsonGenerator theEventWriter, String theRel, StringDt theLink, boolean theStarted) {
|
||||||
|
boolean retVal = theStarted;
|
||||||
|
if (isNotBlank(theLink.getValue())) {
|
||||||
|
if (theStarted == false) {
|
||||||
|
theEventWriter.writeStartArray("link");
|
||||||
|
retVal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
theEventWriter.writeStartObject();
|
||||||
|
theEventWriter.write("relation", theRel);
|
||||||
|
theEventWriter.write("url", theLink.getValue());
|
||||||
|
theEventWriter.writeEnd();
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
private void writeAuthor(BaseBundle theBundle, JsonGenerator eventWriter) {
|
private void writeAuthor(BaseBundle theBundle, JsonGenerator eventWriter) {
|
||||||
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
|
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
|
||||||
eventWriter.writeStartArray("author");
|
eventWriter.writeStartArray("author");
|
||||||
|
@ -920,8 +1042,21 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeExtensionsAsDirectChild(IResource theResource, JsonGenerator theEventWriter, RuntimeResourceDefinition resDef, List<HeldExtension> extensions,
|
private void writeCategories(JsonGenerator eventWriter, TagList categories) {
|
||||||
List<HeldExtension> modifierExtensions) throws IOException {
|
if (categories != null && categories.size() > 0) {
|
||||||
|
eventWriter.writeStartArray("category");
|
||||||
|
for (Tag next : categories) {
|
||||||
|
eventWriter.writeStartObject();
|
||||||
|
eventWriter.write("term", defaultString(next.getTerm()));
|
||||||
|
eventWriter.write("label", defaultString(next.getLabel()));
|
||||||
|
eventWriter.write("scheme", defaultString(next.getScheme()));
|
||||||
|
eventWriter.writeEnd();
|
||||||
|
}
|
||||||
|
eventWriter.writeEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeExtensionsAsDirectChild(IResource theResource, JsonGenerator theEventWriter, RuntimeResourceDefinition resDef, List<HeldExtension> extensions, List<HeldExtension> modifierExtensions) throws IOException {
|
||||||
if (extensions.isEmpty() == false) {
|
if (extensions.isEmpty() == false) {
|
||||||
theEventWriter.writeStartArray("extension");
|
theEventWriter.writeStartArray("extension");
|
||||||
for (HeldExtension next : extensions) {
|
for (HeldExtension next : extensions) {
|
||||||
|
@ -938,6 +1073,17 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeOptionalTagWithNumberNode(JsonGenerator theEventWriter, String theElementName, IntegerDt theValue) {
|
||||||
|
if (theValue != null && theValue.isEmpty()==false) {
|
||||||
|
theEventWriter.write(theElementName, theValue.getValue().intValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeOptionalTagWithDecimalNode(JsonGenerator theEventWriter, String theElementName, DecimalDt theValue) {
|
||||||
|
if (theValue != null && theValue.isEmpty()==false) {
|
||||||
|
theEventWriter.write(theElementName, theValue.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
private void writeOptionalTagWithTextNode(JsonGenerator theEventWriter, String theElementName, IPrimitiveDatatype<?> theInstantDt) {
|
private void writeOptionalTagWithTextNode(JsonGenerator theEventWriter, String theElementName, IPrimitiveDatatype<?> theInstantDt) {
|
||||||
String str = theInstantDt.getValueAsString();
|
String str = theInstantDt.getValueAsString();
|
||||||
if (StringUtils.isNotBlank(str)) {
|
if (StringUtils.isNotBlank(str)) {
|
||||||
|
@ -953,6 +1099,14 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, String theValue) {
|
||||||
|
if (theValue != null && !theValue.isEmpty()) {
|
||||||
|
theEventWriter.write(theElementName, theValue);
|
||||||
|
} else {
|
||||||
|
theEventWriter.writeNull(theElementName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, StringDt theStringDt) {
|
private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, StringDt theStringDt) {
|
||||||
if (StringUtils.isNotBlank(theStringDt.getValue())) {
|
if (StringUtils.isNotBlank(theStringDt.getValue())) {
|
||||||
theEventWriter.write(theElementName, theStringDt.getValue());
|
theEventWriter.write(theElementName, theStringDt.getValue());
|
||||||
|
@ -995,7 +1149,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
// theEventWriter, myValue, def, "value" +
|
// theEventWriter, myValue, def, "value" +
|
||||||
// WordUtils.capitalize(def.getName()));
|
// WordUtils.capitalize(def.getName()));
|
||||||
String childName = myDef.getChildNameByDatatype(myValue.getClass());
|
String childName = myDef.getChildNameByDatatype(myValue.getClass());
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName,false);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// theEventWriter.name(myUndeclaredExtension.get);
|
// theEventWriter.name(myUndeclaredExtension.get);
|
||||||
|
@ -1026,7 +1180,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
|
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
|
BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName,true);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// theEventWriter.name(myUndeclaredExtension.get);
|
// theEventWriter.name(myUndeclaredExtension.get);
|
||||||
|
|
|
@ -37,6 +37,7 @@ import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeElemContainedResources;
|
import ca.uhn.fhir.context.RuntimeElemContainedResources;
|
||||||
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
|
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
|
||||||
|
@ -59,11 +60,13 @@ import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.api.Tag;
|
import ca.uhn.fhir.model.api.Tag;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
|
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.util.IModelVisitor;
|
import ca.uhn.fhir.util.IModelVisitor;
|
||||||
|
@ -158,7 +161,8 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked after any new XML event is individually processed, containing a copy of the XML event. This is basically intended for embedded XHTML content
|
* Invoked after any new XML event is individually processed, containing a copy of the XML event. This is basically
|
||||||
|
* intended for embedded XHTML content
|
||||||
*/
|
*/
|
||||||
public void xmlEvent(XMLEvent theNextEvent) {
|
public void xmlEvent(XMLEvent theNextEvent) {
|
||||||
myState.xmlEvent(theNextEvent);
|
myState.xmlEvent(theNextEvent);
|
||||||
|
@ -166,7 +170,11 @@ class ParserState<T> {
|
||||||
|
|
||||||
public static ParserState<Bundle> getPreAtomInstance(FhirContext theContext, Class<? extends IResource> theResourceType, boolean theJsonMode) throws DataFormatException {
|
public static ParserState<Bundle> getPreAtomInstance(FhirContext theContext, Class<? extends IResource> theResourceType, boolean theJsonMode) throws DataFormatException {
|
||||||
ParserState<Bundle> retVal = new ParserState<Bundle>(theContext, theJsonMode);
|
ParserState<Bundle> retVal = new ParserState<Bundle>(theContext, theJsonMode);
|
||||||
retVal.push(retVal.new PreAtomState(theResourceType));
|
if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
|
||||||
|
retVal.push(retVal.new PreAtomState(theResourceType));
|
||||||
|
} else {
|
||||||
|
retVal.push(retVal.new PreBundleState(theResourceType));
|
||||||
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +249,8 @@ class ParserState<T> {
|
||||||
myScheme = theValue;
|
myScheme = theValue;
|
||||||
} else if ("value".equals(theName)) {
|
} else if ("value".equals(theName)) {
|
||||||
/*
|
/*
|
||||||
* This handles XML parsing, which is odd for this quasi-resource type, since the tag has three values instead of one like everything else.
|
* This handles XML parsing, which is odd for this quasi-resource type, since the tag has three values
|
||||||
|
* instead of one like everything else.
|
||||||
*/
|
*/
|
||||||
switch (myCatState) {
|
switch (myCatState) {
|
||||||
case STATE_LABEL:
|
case STATE_LABEL:
|
||||||
|
@ -289,6 +298,33 @@ class ParserState<T> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AtomDeletedEntryByState extends BaseState {
|
||||||
|
|
||||||
|
private BundleEntry myEntry;
|
||||||
|
|
||||||
|
public AtomDeletedEntryByState(BundleEntry theEntry) {
|
||||||
|
super(null);
|
||||||
|
myEntry = theEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
if ("name".equals(theLocalPart)) {
|
||||||
|
push(new AtomPrimitiveState(myEntry.getDeletedByName()));
|
||||||
|
} else if ("email".equals(theLocalPart)) {
|
||||||
|
push(new AtomPrimitiveState(myEntry.getDeletedByEmail()));
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public class AtomDeletedEntryState extends AtomEntryState {
|
public class AtomDeletedEntryState extends AtomEntryState {
|
||||||
|
|
||||||
public AtomDeletedEntryState(Bundle theInstance, Class<? extends IResource> theResourceType) {
|
public AtomDeletedEntryState(Bundle theInstance, Class<? extends IResource> theResourceType) {
|
||||||
|
@ -304,6 +340,12 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
putPlacerResourceInDeletedEntry(getEntry());
|
||||||
|
super.endingElement();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
if ("by".equals(theLocalPart) && verifyNamespace(XmlParser.TOMBSTONES_NS, theNamespaceURI)) {
|
if ("by".equals(theLocalPart) && verifyNamespace(XmlParser.TOMBSTONES_NS, theNamespaceURI)) {
|
||||||
|
@ -315,39 +357,6 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endingElement() throws DataFormatException {
|
|
||||||
putPlacerResourceInDeletedEntry(getEntry());
|
|
||||||
super.endingElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AtomDeletedEntryByState extends BaseState {
|
|
||||||
|
|
||||||
private BundleEntry myEntry;
|
|
||||||
|
|
||||||
public AtomDeletedEntryByState(BundleEntry theEntry) {
|
|
||||||
super(null);
|
|
||||||
myEntry = theEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
|
||||||
if ("name".equals(theLocalPart)) {
|
|
||||||
push(new AtomPrimitiveState(myEntry.getDeletedByName()));
|
|
||||||
} else if ("email".equals(theLocalPart)) {
|
|
||||||
push(new AtomPrimitiveState(myEntry.getDeletedByEmail()));
|
|
||||||
} else {
|
|
||||||
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endingElement() throws DataFormatException {
|
|
||||||
pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AtomDeletedJsonWhenState extends BaseState {
|
private class AtomDeletedJsonWhenState extends BaseState {
|
||||||
|
@ -654,6 +663,72 @@ class ParserState<T> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class BasePreAtomOrBundleState extends BaseState {
|
||||||
|
|
||||||
|
private Bundle myInstance;
|
||||||
|
|
||||||
|
private Class<? extends IResource> myResourceType;
|
||||||
|
|
||||||
|
public BasePreAtomOrBundleState(Class<? extends IResource> theResourceType) {
|
||||||
|
super(null);
|
||||||
|
myResourceType = theResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IElement getCurrentElement() {
|
||||||
|
return myInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bundle getInstance() {
|
||||||
|
return myInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Class<? extends IResource> getResourceType() {
|
||||||
|
return myResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstance(Bundle theInstance) {
|
||||||
|
myInstance = theInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void wereBack() {
|
||||||
|
myObject = (T) myInstance;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stitch together resource references
|
||||||
|
*/
|
||||||
|
|
||||||
|
Map<String, IResource> idToResource = new HashMap<String, IResource>();
|
||||||
|
List<IResource> resources = myInstance.toListOfResources();
|
||||||
|
for (IResource next : resources) {
|
||||||
|
if (next.getId() != null && next.getId().isEmpty() == false) {
|
||||||
|
idToResource.put(next.getId().toUnqualifiedVersionless().getValue(), next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IResource next : resources) {
|
||||||
|
List<ResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, ResourceReferenceDt.class);
|
||||||
|
for (ResourceReferenceDt nextRef : refs) {
|
||||||
|
if (nextRef.isEmpty() == false && nextRef.getReference() != null) {
|
||||||
|
IResource target = idToResource.get(nextRef.getReference().getValue());
|
||||||
|
if (target != null) {
|
||||||
|
nextRef.setResource(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private abstract class BaseState {
|
private abstract class BaseState {
|
||||||
|
|
||||||
private PreResourceState myPreResourceState;
|
private PreResourceState myPreResourceState;
|
||||||
|
@ -809,6 +884,303 @@ class ParserState<T> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class BundleEntryDeletedState extends BaseState {
|
||||||
|
|
||||||
|
private BundleEntry myEntry;
|
||||||
|
|
||||||
|
public BundleEntryDeletedState(PreResourceState thePreResourceState, BundleEntry theEntry) {
|
||||||
|
super(thePreResourceState);
|
||||||
|
myEntry = theEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
String resType = myEntry.getDeletedResourceType().getValue();
|
||||||
|
String id = myEntry.getDeletedResourceId().getValue();
|
||||||
|
String version = myEntry.getDeletedResourceVersion().getValue();
|
||||||
|
myEntry.setLinkSelf(new StringDt(new IdDt(resType, id, version).getValue()));
|
||||||
|
putPlacerResourceInDeletedEntry(myEntry);
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
if ("type".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceType()));
|
||||||
|
} else if ("id".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceId()));
|
||||||
|
} else if ("version".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceVersion()));
|
||||||
|
} else if ("instant".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedAt()));
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Unexpected element '" + theLocalPart + "' in element 'deleted'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BundleEntryState extends BaseState {
|
||||||
|
|
||||||
|
private BundleEntry myEntry;
|
||||||
|
private Class<? extends IResource> myResourceType;
|
||||||
|
|
||||||
|
public BundleEntryState(Bundle theInstance, Class<? extends IResource> theResourceType) {
|
||||||
|
super(null);
|
||||||
|
myEntry = new BundleEntry();
|
||||||
|
myResourceType = theResourceType;
|
||||||
|
theInstance.getEntries().add(myEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
populateResourceMetadata();
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
if ("base".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getLinkBase()));
|
||||||
|
} else if ("status".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getStatus()));
|
||||||
|
} else if ("search".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getLinkSearch()));
|
||||||
|
} else if ("score".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myEntry.getScore()));
|
||||||
|
} else if ("resource".equals(theLocalPart)) {
|
||||||
|
push(new PreResourceState(myEntry, myResourceType));
|
||||||
|
} else if ("deleted".equals(theLocalPart)) {
|
||||||
|
push(new BundleEntryDeletedState(getPreResourceState(), myEntry));
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle category
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BundleEntry getEntry() {
|
||||||
|
return myEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void populateResourceMetadata() {
|
||||||
|
if (myEntry.getResource() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IdDt id = myEntry.getId();
|
||||||
|
if (id != null && id.isEmpty() == false) {
|
||||||
|
myEntry.getResource().setId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<ResourceMetadataKeyEnum<?>, Object> metadata = myEntry.getResource().getResourceMetadata();
|
||||||
|
if (myEntry.getPublished().isEmpty() == false) {
|
||||||
|
ResourceMetadataKeyEnum.PUBLISHED.put(myEntry.getResource(), myEntry.getPublished());
|
||||||
|
}
|
||||||
|
if (myEntry.getUpdated().isEmpty() == false) {
|
||||||
|
ResourceMetadataKeyEnum.UPDATED.put(myEntry.getResource(), myEntry.getUpdated());
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceMetadataKeyEnum.TITLE.put(myEntry.getResource(), myEntry.getTitle().getValue());
|
||||||
|
|
||||||
|
if (myEntry.getCategories().isEmpty() == false) {
|
||||||
|
TagList tagList = new TagList();
|
||||||
|
for (Tag next : myEntry.getCategories()) {
|
||||||
|
tagList.add(next);
|
||||||
|
}
|
||||||
|
ResourceMetadataKeyEnum.TAG_LIST.put(myEntry.getResource(), tagList);
|
||||||
|
}
|
||||||
|
if (!myEntry.getLinkSelf().isEmpty()) {
|
||||||
|
String linkSelfValue = myEntry.getLinkSelf().getValue();
|
||||||
|
IdDt linkSelf = new IdDt(linkSelfValue);
|
||||||
|
myEntry.getResource().setId(linkSelf);
|
||||||
|
if (isNotBlank(linkSelf.getVersionIdPart())) {
|
||||||
|
metadata.put(ResourceMetadataKeyEnum.VERSION_ID, linkSelf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!myEntry.getLinkAlternate().isEmpty()) {
|
||||||
|
ResourceMetadataKeyEnum.LINK_ALTERNATE.put(myEntry.getResource(), myEntry.getLinkAlternate().getValue());
|
||||||
|
}
|
||||||
|
if (!myEntry.getLinkSearch().isEmpty()) {
|
||||||
|
ResourceMetadataKeyEnum.LINK_SEARCH.put(myEntry.getResource(), myEntry.getLinkSearch().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BundleLinkState extends BaseState {
|
||||||
|
|
||||||
|
private BundleEntry myEntry;
|
||||||
|
private String myHref;
|
||||||
|
private Bundle myInstance;
|
||||||
|
private String myRel;
|
||||||
|
private boolean myInRelation = false;
|
||||||
|
private boolean myInUrl = false;
|
||||||
|
|
||||||
|
public BundleLinkState(Bundle theInstance) {
|
||||||
|
super(null);
|
||||||
|
myInstance = theInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BundleLinkState(BundleEntry theEntry) {
|
||||||
|
super(null);
|
||||||
|
myEntry = theEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attributeValue(String theName, String theValue) throws DataFormatException {
|
||||||
|
if (myInRelation) {
|
||||||
|
myRel = theValue;
|
||||||
|
} else if (myInUrl) {
|
||||||
|
myHref = theValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
if (!myInRelation && !myInUrl) {
|
||||||
|
if (myInstance != null) {
|
||||||
|
if ("self".equals(myRel)) {
|
||||||
|
myInstance.getLinkSelf().setValueAsString(myHref);
|
||||||
|
} else if ("first".equals(myRel)) {
|
||||||
|
myInstance.getLinkFirst().setValueAsString(myHref);
|
||||||
|
} else if ("previous".equals(myRel)) {
|
||||||
|
myInstance.getLinkPrevious().setValueAsString(myHref);
|
||||||
|
} else if ("next".equals(myRel)) {
|
||||||
|
myInstance.getLinkNext().setValueAsString(myHref);
|
||||||
|
} else if ("last".equals(myRel)) {
|
||||||
|
myInstance.getLinkLast().setValueAsString(myHref);
|
||||||
|
} else if ("fhir-base".equals(myRel)) {
|
||||||
|
myInstance.getLinkBase().setValueAsString(myHref);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ("self".equals(myRel)) {
|
||||||
|
myEntry.getLinkSelf().setValueAsString(myHref);
|
||||||
|
} else if ("search".equals(myRel)) {
|
||||||
|
myEntry.getLinkSearch().setValueAsString(myHref);
|
||||||
|
} else if ("alternate".equals(myRel)) {
|
||||||
|
myEntry.getLinkAlternate().setValueAsString(myHref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
} else {
|
||||||
|
myInRelation = false;
|
||||||
|
myInUrl = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
if (myInRelation || myInUrl) {
|
||||||
|
throw new DataFormatException("Unexpected element '" + theLocalPart + "' in element 'link'");
|
||||||
|
}
|
||||||
|
if ("relation".equals(theLocalPart)) {
|
||||||
|
myInRelation = true;
|
||||||
|
} else if ("url".equals(theLocalPart)) {
|
||||||
|
myInUrl = true;
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Unexpected element '" + theLocalPart + "' in element 'link'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BundleState extends BaseState {
|
||||||
|
|
||||||
|
private Bundle myInstance;
|
||||||
|
private Class<? extends IResource> myResourceType;
|
||||||
|
|
||||||
|
public BundleState(Bundle theInstance, Class<? extends IResource> theResourceType) {
|
||||||
|
super(null);
|
||||||
|
myInstance = theInstance;
|
||||||
|
myResourceType = theResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void wereBack() {
|
||||||
|
for (BundleEntry nextEntry : myInstance.getEntries()) {
|
||||||
|
IResource nextResource = nextEntry.getResource();
|
||||||
|
|
||||||
|
String baseUrl = myInstance.getLinkBase().getValue();
|
||||||
|
String version = ResourceMetadataKeyEnum.VERSION.get(nextResource);
|
||||||
|
String resourceName = myContext.getResourceDefinition(nextResource).getName();
|
||||||
|
nextResource.setId(new IdDt(baseUrl, resourceName, nextResource.getId().getIdPart(), version));
|
||||||
|
}
|
||||||
|
|
||||||
|
String bundleVersion = (String) myInstance.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION);
|
||||||
|
String baseUrl = myInstance.getLinkBase().getValue();
|
||||||
|
String id = myInstance.getId().getIdPart();
|
||||||
|
myInstance.setId(new IdDt(baseUrl, "Bundle", id, bundleVersion));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
if ("id".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(null, myInstance.getId()));
|
||||||
|
} else if ("meta".equals(theLocalPart)) {
|
||||||
|
push(new MetaElementState(null, myInstance.getResourceMetadata()));
|
||||||
|
} else if ("type".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myInstance.getType()));
|
||||||
|
} else if ("base".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myInstance.getLinkBase()));
|
||||||
|
} else if ("total".equals(theLocalPart)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), myInstance.getTotalResults()));
|
||||||
|
} else if ("link".equals(theLocalPart)) {
|
||||||
|
push(new BundleLinkState(myInstance));
|
||||||
|
} else if ("entry".equals(theLocalPart)) {
|
||||||
|
push(new BundleEntryState(myInstance, myResourceType));
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Unxpected element '" + theLocalPart + " in element 'Bundle'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) {
|
||||||
|
// push(new AtomEntryState(myInstance, myResourceType));
|
||||||
|
// } else if (theLocalPart.equals("published")) {
|
||||||
|
// push(new AtomPrimitiveState(myInstance.getPublished()));
|
||||||
|
// } else if (theLocalPart.equals("title")) {
|
||||||
|
// push(new AtomPrimitiveState(myInstance.getTitle()));
|
||||||
|
// } else if ("id".equals(theLocalPart)) {
|
||||||
|
// push(new AtomPrimitiveState(myInstance.getBundleId()));
|
||||||
|
// } else if ("link".equals(theLocalPart)) {
|
||||||
|
// push(new AtomLinkState(myInstance));
|
||||||
|
// } else if ("totalResults".equals(theLocalPart) && (verifyNamespace(XmlParser.OPENSEARCH_NS,
|
||||||
|
// theNamespaceURI) || verifyNamespace(Constants.OPENSEARCH_NS_OLDER, theNamespaceURI))) {
|
||||||
|
// push(new AtomPrimitiveState(myInstance.getTotalResults()));
|
||||||
|
// } else if ("updated".equals(theLocalPart)) {
|
||||||
|
// push(new AtomPrimitiveState(myInstance.getUpdated()));
|
||||||
|
// } else if ("author".equals(theLocalPart)) {
|
||||||
|
// push(new AtomAuthorState(myInstance));
|
||||||
|
// } else if ("category".equals(theLocalPart)) {
|
||||||
|
// push(new AtomCategoryState(myInstance.getCategories()));
|
||||||
|
// } else if ("deleted-entry".equals(theLocalPart) && verifyNamespace(XmlParser.TOMBSTONES_NS,
|
||||||
|
// theNamespaceURI)) {
|
||||||
|
// push(new AtomDeletedEntryState(myInstance, myResourceType));
|
||||||
|
// } else {
|
||||||
|
// if (theNamespaceURI != null) {
|
||||||
|
// throw new DataFormatException("Unexpected element: {" + theNamespaceURI + "}" + theLocalPart);
|
||||||
|
// } else {
|
||||||
|
// throw new DataFormatException("Unexpected element: " + theLocalPart);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TODO: handle category and DSig
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IElement getCurrentElement() {
|
||||||
|
return myInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private class ContainedResourcesState extends PreResourceState {
|
private class ContainedResourcesState extends PreResourceState {
|
||||||
|
|
||||||
public ContainedResourcesState(PreResourceState thePreResourcesState) {
|
public ContainedResourcesState(PreResourceState thePreResourcesState) {
|
||||||
|
@ -920,12 +1292,12 @@ class ParserState<T> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ElementCompositeState extends BaseState {
|
private class ElementCompositeState<T2 extends IElement> extends BaseState {
|
||||||
|
|
||||||
private BaseRuntimeElementCompositeDefinition<?> myDefinition;
|
private BaseRuntimeElementCompositeDefinition<?> myDefinition;
|
||||||
private ICompositeElement myInstance;
|
private T2 myInstance;
|
||||||
|
|
||||||
public ElementCompositeState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, ICompositeElement theInstance) {
|
public ElementCompositeState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, T2 theInstance) {
|
||||||
super(thePreResourceState);
|
super(thePreResourceState);
|
||||||
myDefinition = theDef;
|
myDefinition = theDef;
|
||||||
myInstance = theInstance;
|
myInstance = theInstance;
|
||||||
|
@ -976,7 +1348,7 @@ class ParserState<T> {
|
||||||
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
|
||||||
ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance(child.getInstanceConstructorArguments());
|
ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance(child.getInstanceConstructorArguments());
|
||||||
child.getMutator().addValue(myInstance, newChildInstance);
|
child.getMutator().addValue(myInstance, newChildInstance);
|
||||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
|
ElementCompositeState<ICompositeElement> newState = new ElementCompositeState<ICompositeElement>(getPreResourceState(), compositeTarget, newChildInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1002,7 +1374,7 @@ class ParserState<T> {
|
||||||
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
|
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
|
||||||
IResourceBlock newBlockInstance = blockTarget.newInstance();
|
IResourceBlock newBlockInstance = blockTarget.newInstance();
|
||||||
child.getMutator().addValue(myInstance, newBlockInstance);
|
child.getMutator().addValue(myInstance, newBlockInstance);
|
||||||
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), blockTarget, newBlockInstance);
|
ElementCompositeState<ICompositeElement> newState = new ElementCompositeState<ICompositeElement>(getPreResourceState(), blockTarget, newBlockInstance);
|
||||||
push(newState);
|
push(newState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1423,7 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IElement getCurrentElement() {
|
protected T2 getCurrentElement() {
|
||||||
return myInstance;
|
return myInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,14 +1494,64 @@ class ParserState<T> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PreAtomState extends BaseState {
|
private class MetaElementState extends BaseState {
|
||||||
|
private ResourceMetadataMap myMap;
|
||||||
|
|
||||||
private Bundle myInstance;
|
public MetaElementState(ParserState<T>.PreResourceState thePreResourceState, ResourceMetadataMap theMap) {
|
||||||
private Class<? extends IResource> myResourceType;
|
super(thePreResourceState);
|
||||||
|
myMap = theMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
if (theLocalPart.equals("versionId")) {
|
||||||
|
push(new MetaVersionElementState(getPreResourceState(), myMap));
|
||||||
|
} else if (theLocalPart.equals("lastUpdated")) {
|
||||||
|
InstantDt updated = new InstantDt();
|
||||||
|
push(new PrimitiveState(getPreResourceState(), updated));
|
||||||
|
myMap.put(ResourceMetadataKeyEnum.UPDATED, updated);
|
||||||
|
} else {
|
||||||
|
throw new DataFormatException("Unexpected element '" + theLocalPart + "' found in 'meta' element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MetaVersionElementState extends BaseState {
|
||||||
|
|
||||||
|
private ResourceMetadataMap myMap;
|
||||||
|
|
||||||
|
public MetaVersionElementState(ParserState<T>.PreResourceState thePreResourceState, ResourceMetadataMap theMap) {
|
||||||
|
super(thePreResourceState);
|
||||||
|
myMap = theMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attributeValue(String theName, String theValue) throws DataFormatException {
|
||||||
|
myMap.put(ResourceMetadataKeyEnum.VERSION, theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
throw new DataFormatException("Unexpected child element '" + theLocalPart + "' in element 'meta'");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PreAtomState extends BasePreAtomOrBundleState {
|
||||||
|
|
||||||
public PreAtomState(Class<? extends IResource> theResourceType) {
|
public PreAtomState(Class<? extends IResource> theResourceType) {
|
||||||
super(null);
|
super(theResourceType);
|
||||||
myResourceType = theResourceType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1143,49 +1565,59 @@ class ParserState<T> {
|
||||||
throw new DataFormatException("Expecting outer element called 'feed', found: " + theLocalPart);
|
throw new DataFormatException("Expecting outer element called 'feed', found: " + theLocalPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
myInstance = new Bundle();
|
setInstance(new Bundle());
|
||||||
push(new AtomState(myInstance, myResourceType));
|
push(new AtomState(getInstance(), getResourceType()));
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IElement getCurrentElement() {
|
|
||||||
return myInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public void wereBack() {
|
|
||||||
myObject = (T) myInstance;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stitch together resource references
|
|
||||||
*/
|
|
||||||
|
|
||||||
Map<String, IResource> idToResource = new HashMap<String, IResource>();
|
|
||||||
List<IResource> resources = myInstance.toListOfResources();
|
|
||||||
for (IResource next : resources) {
|
|
||||||
if (next.getId() != null && next.getId().isEmpty() == false) {
|
|
||||||
idToResource.put(next.getId().toUnqualifiedVersionless().getValue(), next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IResource next : resources) {
|
|
||||||
List<ResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, ResourceReferenceDt.class);
|
|
||||||
for (ResourceReferenceDt nextRef : refs) {
|
|
||||||
if (nextRef.isEmpty() == false && nextRef.getReference() != null) {
|
|
||||||
IResource target = idToResource.get(nextRef.getReference().getValue());
|
|
||||||
if (target != null) {
|
|
||||||
nextRef.setResource(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class PreBundleState extends BasePreAtomOrBundleState {
|
||||||
|
|
||||||
|
public PreBundleState(Class<? extends IResource> theResourceType) {
|
||||||
|
super(theResourceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endingElement() throws DataFormatException {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
|
if (!"Bundle".equals(theLocalPart)) {
|
||||||
|
throw new DataFormatException("Expecting outer element called 'Bundle', found: " + theLocalPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
setInstance(new Bundle());
|
||||||
|
push(new BundleState(getInstance(), getResourceType()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ResourceState extends ElementCompositeState<IResource>
|
||||||
|
{
|
||||||
|
|
||||||
|
public ResourceState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IResource theInstance) {
|
||||||
|
super(thePreResourceState, theDef, theInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enteringNewElement(String theNamespace, String theChildName) throws DataFormatException {
|
||||||
|
if ("id".equals(theChildName)) {
|
||||||
|
push(new PrimitiveState(getPreResourceState(), getCurrentElement().getId()));
|
||||||
|
} else if ("meta".equals(theChildName)) {
|
||||||
|
push(new MetaElementState(getPreResourceState(), getCurrentElement().getResourceMetadata()));
|
||||||
|
}else {
|
||||||
|
super.enteringNewElement(theNamespace, theChildName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class PreResourceState extends BaseState {
|
private class PreResourceState extends BaseState {
|
||||||
|
|
||||||
private Map<String, IResource> myContainedResources = new HashMap<String, IResource>();
|
private Map<String, IResource> myContainedResources = new HashMap<String, IResource>();
|
||||||
|
@ -1242,10 +1674,11 @@ class ParserState<T> {
|
||||||
myEntry.setResource(myInstance);
|
myEntry.setResource(myInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("Binary".equals(def.getName())) {
|
String resourceName = def.getName();
|
||||||
|
if ("Binary".equals(resourceName)) {
|
||||||
push(new BinaryResourceState(getRootPreResourceState(), (Binary) myInstance));
|
push(new BinaryResourceState(getRootPreResourceState(), (Binary) myInstance));
|
||||||
} else {
|
} else {
|
||||||
push(new ElementCompositeState(getRootPreResourceState(), def, myInstance));
|
push(new ResourceState(getRootPreResourceState(), def, myInstance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1284,12 +1717,6 @@ class ParserState<T> {
|
||||||
|
|
||||||
myContext.newTerser().visit(myInstance, new IModelVisitor() {
|
myContext.newTerser().visit(myInstance, new IModelVisitor() {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
|
|
||||||
ExtensionDt theNextExt) {
|
|
||||||
acceptElement(theNextExt.getValue(), null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptElement(IElement theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
public void acceptElement(IElement theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||||
if (theElement instanceof ResourceReferenceDt) {
|
if (theElement instanceof ResourceReferenceDt) {
|
||||||
|
@ -1307,6 +1734,11 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
||||||
|
acceptElement(theNextExt.getValue(), null, null);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1496,12 +1928,12 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
myDepth++;
|
myDepth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
|
||||||
myDepth++;
|
myDepth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,7 @@ package ca.uhn.fhir.parser;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
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.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -53,6 +51,7 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeChildNarrativeDefinition;
|
import ca.uhn.fhir.context.RuntimeChildNarrativeDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
|
import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
|
||||||
|
@ -64,6 +63,7 @@ import ca.uhn.fhir.model.api.IElement;
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.api.Tag;
|
import ca.uhn.fhir.model.api.Tag;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
|
||||||
|
@ -94,6 +94,10 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
private boolean myPrettyPrint;
|
private boolean myPrettyPrint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not use this constructor, the recommended way to obtain a new instance of the
|
||||||
|
* XML parser is to invoke {@link FhirContext#newXmlParser()}.
|
||||||
|
*/
|
||||||
public XmlParser(FhirContext theContext) {
|
public XmlParser(FhirContext theContext) {
|
||||||
super(theContext);
|
super(theContext);
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
|
@ -111,118 +115,213 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
public void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws DataFormatException {
|
public void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws DataFormatException {
|
||||||
try {
|
try {
|
||||||
XMLStreamWriter eventWriter = createXmlWriter(theWriter);
|
XMLStreamWriter eventWriter = createXmlWriter(theWriter);
|
||||||
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
eventWriter.writeStartElement("feed");
|
encodeBundleToWriterUsingBundleResource(theBundle, eventWriter);
|
||||||
eventWriter.writeDefaultNamespace(ATOM_NS);
|
} else {
|
||||||
|
encodeBundleToWriterUsingAtom(theBundle, eventWriter);
|
||||||
writeTagWithTextNode(eventWriter, "title", theBundle.getTitle());
|
|
||||||
writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId());
|
|
||||||
|
|
||||||
writeAtomLink(eventWriter, "self", theBundle.getLinkSelf());
|
|
||||||
writeAtomLink(eventWriter, "first", theBundle.getLinkFirst());
|
|
||||||
writeAtomLink(eventWriter, "previous", theBundle.getLinkPrevious());
|
|
||||||
writeAtomLink(eventWriter, "next", theBundle.getLinkNext());
|
|
||||||
writeAtomLink(eventWriter, "last", theBundle.getLinkLast());
|
|
||||||
writeAtomLink(eventWriter, "fhir-base", theBundle.getLinkBase());
|
|
||||||
|
|
||||||
if (theBundle.getTotalResults().getValue() != null) {
|
|
||||||
eventWriter.writeStartElement("os", "totalResults", OPENSEARCH_NS);
|
|
||||||
eventWriter.writeNamespace("os", OPENSEARCH_NS);
|
|
||||||
eventWriter.writeCharacters(theBundle.getTotalResults().getValue().toString());
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
|
||||||
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
|
|
||||||
eventWriter.writeStartElement("author");
|
|
||||||
writeTagWithTextNode(eventWriter, "name", theBundle.getAuthorName());
|
|
||||||
writeOptionalTagWithTextNode(eventWriter, "uri", theBundle.getAuthorUri());
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeCategories(eventWriter, theBundle.getCategories());
|
|
||||||
|
|
||||||
for (BundleEntry nextEntry : theBundle.getEntries()) {
|
|
||||||
boolean deleted = false;
|
|
||||||
if (nextEntry.getDeletedAt() != null && nextEntry.getDeletedAt().isEmpty() == false) {
|
|
||||||
deleted = true;
|
|
||||||
eventWriter.writeStartElement("at", "deleted-entry", TOMBSTONES_NS);
|
|
||||||
eventWriter.writeNamespace("at", TOMBSTONES_NS);
|
|
||||||
eventWriter.writeAttribute("ref", nextEntry.getId().getValueAsString());
|
|
||||||
eventWriter.writeAttribute("when", nextEntry.getDeletedAt().getValueAsString());
|
|
||||||
if (nextEntry.getDeletedByEmail().isEmpty() == false || nextEntry.getDeletedByName().isEmpty() == false) {
|
|
||||||
eventWriter.writeStartElement(TOMBSTONES_NS, "by");
|
|
||||||
if (nextEntry.getDeletedByName().isEmpty() == false) {
|
|
||||||
eventWriter.writeStartElement(TOMBSTONES_NS, "name");
|
|
||||||
eventWriter.writeCharacters(nextEntry.getDeletedByName().getValue());
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
if (nextEntry.getDeletedByEmail().isEmpty() == false) {
|
|
||||||
eventWriter.writeStartElement(TOMBSTONES_NS, "email");
|
|
||||||
eventWriter.writeCharacters(nextEntry.getDeletedByEmail().getValue());
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
if (nextEntry.getDeletedComment().isEmpty() == false) {
|
|
||||||
eventWriter.writeStartElement(TOMBSTONES_NS, "comment");
|
|
||||||
eventWriter.writeCharacters(nextEntry.getDeletedComment().getValue());
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
eventWriter.writeStartElement("entry");
|
|
||||||
}
|
|
||||||
|
|
||||||
writeOptionalTagWithTextNode(eventWriter, "title", nextEntry.getTitle());
|
|
||||||
if (!deleted) {
|
|
||||||
writeTagWithTextNode(eventWriter, "id", nextEntry.getId());
|
|
||||||
}
|
|
||||||
writeOptionalTagWithTextNode(eventWriter, "updated", nextEntry.getUpdated());
|
|
||||||
writeOptionalTagWithTextNode(eventWriter, "published", nextEntry.getPublished());
|
|
||||||
|
|
||||||
writeCategories(eventWriter, nextEntry.getCategories());
|
|
||||||
|
|
||||||
if (!nextEntry.getLinkSelf().isEmpty()) {
|
|
||||||
writeAtomLink(eventWriter, "self", nextEntry.getLinkSelf());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nextEntry.getLinkAlternate().isEmpty()) {
|
|
||||||
writeAtomLink(eventWriter, "alternate", nextEntry.getLinkAlternate());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nextEntry.getLinkSearch().isEmpty()) {
|
|
||||||
writeAtomLink(eventWriter, "search", nextEntry.getLinkSearch());
|
|
||||||
}
|
|
||||||
|
|
||||||
IResource resource = nextEntry.getResource();
|
|
||||||
if (resource != null && !resource.isEmpty() && !deleted) {
|
|
||||||
eventWriter.writeStartElement("content");
|
|
||||||
eventWriter.writeAttribute("type", "text/xml");
|
|
||||||
encodeResourceToXmlStreamWriter(resource, eventWriter, false);
|
|
||||||
eventWriter.writeEndElement(); // content
|
|
||||||
} else {
|
|
||||||
ourLog.debug("Bundle entry contains null resource");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nextEntry.getSummary().isEmpty()) {
|
|
||||||
eventWriter.writeStartElement("summary");
|
|
||||||
eventWriter.writeAttribute("type", "xhtml");
|
|
||||||
encodeXhtml(nextEntry.getSummary(), eventWriter);
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
eventWriter.writeEndElement(); // entry
|
|
||||||
}
|
|
||||||
|
|
||||||
eventWriter.writeEndElement();
|
|
||||||
eventWriter.close();
|
|
||||||
} catch (XMLStreamException e) {
|
} catch (XMLStreamException e) {
|
||||||
throw new ConfigurationException("Failed to initialize STaX event factory", e);
|
throw new ConfigurationException("Failed to initialize STaX event factory", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void encodeBundleToWriterUsingAtom(Bundle theBundle, XMLStreamWriter eventWriter) throws XMLStreamException {
|
||||||
|
eventWriter.writeStartElement("feed");
|
||||||
|
eventWriter.writeDefaultNamespace(ATOM_NS);
|
||||||
|
|
||||||
|
writeTagWithTextNode(eventWriter, "title", theBundle.getTitle());
|
||||||
|
writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId());
|
||||||
|
|
||||||
|
writeAtomLink(eventWriter, "self", theBundle.getLinkSelf());
|
||||||
|
writeAtomLink(eventWriter, "first", theBundle.getLinkFirst());
|
||||||
|
writeAtomLink(eventWriter, "previous", theBundle.getLinkPrevious());
|
||||||
|
writeAtomLink(eventWriter, "next", theBundle.getLinkNext());
|
||||||
|
writeAtomLink(eventWriter, "last", theBundle.getLinkLast());
|
||||||
|
writeAtomLink(eventWriter, "fhir-base", theBundle.getLinkBase());
|
||||||
|
|
||||||
|
if (theBundle.getTotalResults().getValue() != null) {
|
||||||
|
eventWriter.writeStartElement("os", "totalResults", OPENSEARCH_NS);
|
||||||
|
eventWriter.writeNamespace("os", OPENSEARCH_NS);
|
||||||
|
eventWriter.writeCharacters(theBundle.getTotalResults().getValue().toString());
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
|
||||||
|
eventWriter.writeStartElement("author");
|
||||||
|
writeTagWithTextNode(eventWriter, "name", theBundle.getAuthorName());
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "uri", theBundle.getAuthorUri());
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeCategories(eventWriter, theBundle.getCategories());
|
||||||
|
|
||||||
|
for (BundleEntry nextEntry : theBundle.getEntries()) {
|
||||||
|
boolean deleted = false;
|
||||||
|
if (nextEntry.getDeletedAt() != null && nextEntry.getDeletedAt().isEmpty() == false) {
|
||||||
|
deleted = true;
|
||||||
|
eventWriter.writeStartElement("at", "deleted-entry", TOMBSTONES_NS);
|
||||||
|
eventWriter.writeNamespace("at", TOMBSTONES_NS);
|
||||||
|
eventWriter.writeAttribute("ref", nextEntry.getId().getValueAsString());
|
||||||
|
eventWriter.writeAttribute("when", nextEntry.getDeletedAt().getValueAsString());
|
||||||
|
if (nextEntry.getDeletedByEmail().isEmpty() == false || nextEntry.getDeletedByName().isEmpty() == false) {
|
||||||
|
eventWriter.writeStartElement(TOMBSTONES_NS, "by");
|
||||||
|
if (nextEntry.getDeletedByName().isEmpty() == false) {
|
||||||
|
eventWriter.writeStartElement(TOMBSTONES_NS, "name");
|
||||||
|
eventWriter.writeCharacters(nextEntry.getDeletedByName().getValue());
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
if (nextEntry.getDeletedByEmail().isEmpty() == false) {
|
||||||
|
eventWriter.writeStartElement(TOMBSTONES_NS, "email");
|
||||||
|
eventWriter.writeCharacters(nextEntry.getDeletedByEmail().getValue());
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
if (nextEntry.getDeletedComment().isEmpty() == false) {
|
||||||
|
eventWriter.writeStartElement(TOMBSTONES_NS, "comment");
|
||||||
|
eventWriter.writeCharacters(nextEntry.getDeletedComment().getValue());
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eventWriter.writeStartElement("entry");
|
||||||
|
}
|
||||||
|
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "title", nextEntry.getTitle());
|
||||||
|
if (!deleted) {
|
||||||
|
writeTagWithTextNode(eventWriter, "id", nextEntry.getId());
|
||||||
|
}
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "updated", nextEntry.getUpdated());
|
||||||
|
writeOptionalTagWithTextNode(eventWriter, "published", nextEntry.getPublished());
|
||||||
|
|
||||||
|
writeCategories(eventWriter, nextEntry.getCategories());
|
||||||
|
|
||||||
|
if (!nextEntry.getLinkSelf().isEmpty()) {
|
||||||
|
writeAtomLink(eventWriter, "self", nextEntry.getLinkSelf());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextEntry.getLinkAlternate().isEmpty()) {
|
||||||
|
writeAtomLink(eventWriter, "alternate", nextEntry.getLinkAlternate());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextEntry.getLinkSearch().isEmpty()) {
|
||||||
|
writeAtomLink(eventWriter, "search", nextEntry.getLinkSearch());
|
||||||
|
}
|
||||||
|
|
||||||
|
IResource resource = nextEntry.getResource();
|
||||||
|
if (resource != null && !resource.isEmpty() && !deleted) {
|
||||||
|
eventWriter.writeStartElement("content");
|
||||||
|
eventWriter.writeAttribute("type", "text/xml");
|
||||||
|
encodeResourceToXmlStreamWriter(resource, eventWriter, false);
|
||||||
|
eventWriter.writeEndElement(); // content
|
||||||
|
} else {
|
||||||
|
ourLog.debug("Bundle entry contains null resource");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextEntry.getSummary().isEmpty()) {
|
||||||
|
eventWriter.writeStartElement("summary");
|
||||||
|
eventWriter.writeAttribute("type", "xhtml");
|
||||||
|
encodeXhtml(nextEntry.getSummary(), eventWriter);
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
eventWriter.writeEndElement(); // entry
|
||||||
|
}
|
||||||
|
|
||||||
|
eventWriter.writeEndElement();
|
||||||
|
eventWriter.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void encodeBundleToWriterUsingBundleResource(Bundle theBundle, XMLStreamWriter theEventWriter) throws XMLStreamException {
|
||||||
|
theEventWriter.writeStartElement("Bundle");
|
||||||
|
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
||||||
|
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "id", theBundle.getId().getIdPart());
|
||||||
|
|
||||||
|
theEventWriter.writeStartElement("meta");
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "versionId", theBundle.getId().getVersionIdPart());
|
||||||
|
InstantDt updated = (InstantDt) theBundle.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
||||||
|
if (updated != null) {
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
|
||||||
|
}
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
|
||||||
|
String bundleBaseUrl = theBundle.getLinkBase().getValue();
|
||||||
|
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "type", theBundle.getType().getValue());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "base", bundleBaseUrl);
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "total", theBundle.getTotalResults().getValueAsString());
|
||||||
|
|
||||||
|
writeBundleResourceLink(theEventWriter, "first", theBundle.getLinkFirst());
|
||||||
|
writeBundleResourceLink(theEventWriter, "previous", theBundle.getLinkPrevious());
|
||||||
|
writeBundleResourceLink(theEventWriter, "next", theBundle.getLinkNext());
|
||||||
|
writeBundleResourceLink(theEventWriter, "last", theBundle.getLinkLast());
|
||||||
|
writeBundleResourceLink(theEventWriter, "self", theBundle.getLinkSelf());
|
||||||
|
|
||||||
|
for (BundleEntry nextEntry : theBundle.getEntries()) {
|
||||||
|
theEventWriter.writeStartElement("entry");
|
||||||
|
|
||||||
|
IResource nextResource = nextEntry.getResource();
|
||||||
|
if (nextResource.getId() != null && nextResource.getId().hasBaseUrl()) {
|
||||||
|
if (!nextResource.getId().getBaseUrl().equals(bundleBaseUrl)) {
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "base", bundleBaseUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "status", nextEntry.getStatus().getValue());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "search", nextEntry.getLinkSearch().getValue());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "score", nextEntry.getScore().getValueAsString());
|
||||||
|
|
||||||
|
boolean deleted = false;
|
||||||
|
if (nextEntry.getDeletedAt() != null && nextEntry.getDeletedAt().isEmpty() == false) {
|
||||||
|
deleted = true;
|
||||||
|
theEventWriter.writeStartElement("deleted");
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "type", nextEntry.getId().getResourceType());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "id", nextEntry.getId().getIdPart());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "versionId", nextEntry.getId().getVersionIdPart());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "instant", nextEntry.getDeletedAt().getValueAsString());
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
IResource resource = nextEntry.getResource();
|
||||||
|
if (resource != null && !resource.isEmpty() && !deleted) {
|
||||||
|
theEventWriter.writeStartElement("resource");
|
||||||
|
encodeResourceToXmlStreamWriter(resource, theEventWriter, false);
|
||||||
|
theEventWriter.writeEndElement(); // content
|
||||||
|
} else {
|
||||||
|
ourLog.debug("Bundle entry contains null resource");
|
||||||
|
}
|
||||||
|
|
||||||
|
theEventWriter.writeEndElement(); // entry
|
||||||
|
}
|
||||||
|
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
theEventWriter.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeBundleResourceLink(XMLStreamWriter theEventWriter, String theRel, StringDt theUrl) throws XMLStreamException {
|
||||||
|
if (theUrl.isEmpty()==false) {
|
||||||
|
theEventWriter.writeStartElement("link");
|
||||||
|
theEventWriter.writeStartElement("relation");
|
||||||
|
theEventWriter.writeAttribute("value", theRel);
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
theEventWriter.writeStartElement("url");
|
||||||
|
theEventWriter.writeAttribute("value", theUrl.getValue());
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeOptionalTagWithValue(XMLStreamWriter theEventWriter, String theName, String theValue) throws XMLStreamException {
|
||||||
|
if (StringUtils.isNotBlank(theValue)) {
|
||||||
|
theEventWriter.writeStartElement(theName);
|
||||||
|
theEventWriter.writeAttribute("value", theValue);
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void writeCategories(XMLStreamWriter eventWriter, TagList categories) throws XMLStreamException {
|
private void writeCategories(XMLStreamWriter eventWriter, TagList categories) throws XMLStreamException {
|
||||||
if (categories != null) {
|
if (categories != null) {
|
||||||
for (Tag next : categories) {
|
for (Tag next : categories) {
|
||||||
|
@ -421,10 +520,10 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theEventWriter, IElement nextValue, String childName,
|
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theEventWriter, IElement nextValue, String childName, BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl, boolean theIncludedResource)
|
||||||
BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
throws XMLStreamException, DataFormatException {
|
||||||
if (nextValue.isEmpty()) {
|
if (nextValue.isEmpty()) {
|
||||||
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && getContainedResources().isEmpty()==false && theIncludedResource == false) {
|
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && getContainedResources().isEmpty() == false && theIncludedResource == false) {
|
||||||
// We still want to go in..
|
// We still want to go in..
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -467,7 +566,7 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
ContainedDt value = (ContainedDt) nextValue;
|
ContainedDt value = (ContainedDt) nextValue;
|
||||||
theEventWriter.writeStartElement("contained");
|
theEventWriter.writeStartElement("contained");
|
||||||
for (IResource next : value.getContainedResources()) {
|
for (IResource next : value.getContainedResources()) {
|
||||||
if (getContainedResources().getResourceId(next)!=null) {
|
if (getContainedResources().getResourceId(next) != null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
encodeResourceToXmlStreamWriter(next, theEventWriter, true, fixContainedResourceId(next.getId().getValue()));
|
encodeResourceToXmlStreamWriter(next, theEventWriter, true, fixContainedResourceId(next.getId().getValue()));
|
||||||
|
@ -497,9 +596,8 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, XMLStreamWriter theEventWriter, List<? extends BaseRuntimeChildDefinition> children, boolean theIncludedResource) throws XMLStreamException,
|
||||||
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, XMLStreamWriter theEventWriter,
|
DataFormatException {
|
||||||
List<? extends BaseRuntimeChildDefinition> children, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
|
||||||
for (BaseRuntimeChildDefinition nextChild : children) {
|
for (BaseRuntimeChildDefinition nextChild : children) {
|
||||||
if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) {
|
if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) {
|
||||||
INarrativeGenerator gen = myContext.getNarrativeGenerator();
|
INarrativeGenerator gen = myContext.getNarrativeGenerator();
|
||||||
|
@ -558,15 +656,13 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, XMLStreamWriter theEventWriter,
|
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, XMLStreamWriter theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
||||||
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
|
||||||
encodeExtensionsIfPresent(theResDef, theResource, theEventWriter, theElement, theIncludedResource);
|
encodeExtensionsIfPresent(theResDef, theResource, theEventWriter, theElement, theIncludedResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions(), theIncludedResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions(), theIncludedResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren(), theIncludedResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren(), theIncludedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeExtensionsIfPresent(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theWriter, IElement theElement, boolean theIncludedResource)
|
private void encodeExtensionsIfPresent(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theWriter, IElement theElement, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
||||||
throws XMLStreamException, DataFormatException {
|
|
||||||
if (theElement instanceof ISupportsUndeclaredExtensions) {
|
if (theElement instanceof ISupportsUndeclaredExtensions) {
|
||||||
ISupportsUndeclaredExtensions res = (ISupportsUndeclaredExtensions) theElement;
|
ISupportsUndeclaredExtensions res = (ISupportsUndeclaredExtensions) theElement;
|
||||||
encodeUndeclaredExtensions(theResDef, theResource, theWriter, res.getUndeclaredExtensions(), "extension", theIncludedResource);
|
encodeUndeclaredExtensions(theResDef, theResource, theWriter, res.getUndeclaredExtensions(), "extension", theIncludedResource);
|
||||||
|
@ -589,7 +685,6 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
private void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
||||||
String resourceId = null;
|
String resourceId = null;
|
||||||
if (theIncludedResource && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
if (theIncludedResource && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
||||||
|
@ -612,10 +707,24 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
theEventWriter.writeStartElement(resDef.getName());
|
theEventWriter.writeStartElement(resDef.getName());
|
||||||
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
||||||
|
|
||||||
if (theResourceId != null) {
|
if (!myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
theEventWriter.writeAttribute("id", theResourceId);
|
if (theResourceId != null) {
|
||||||
|
theEventWriter.writeAttribute("id", theResourceId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "id", theResource.getId().getIdPart());
|
||||||
|
|
||||||
|
theEventWriter.writeStartElement("meta");
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "versionId", theResource.getId().getVersionIdPart());
|
||||||
|
InstantDt updated = (InstantDt) theResource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
||||||
|
if (updated != null) {
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
|
||||||
|
}
|
||||||
|
theEventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (theResource instanceof Binary) {
|
if (theResource instanceof Binary) {
|
||||||
Binary bin = (Binary) theResource;
|
Binary bin = (Binary) theResource;
|
||||||
theEventWriter.writeAttribute("contentType", bin.getContentType());
|
theEventWriter.writeAttribute("contentType", bin.getContentType());
|
||||||
|
@ -627,8 +736,7 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeUndeclaredExtensions(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theWriter, List<ExtensionDt> extensions, String tagName,
|
private void encodeUndeclaredExtensions(RuntimeResourceDefinition theResDef, IResource theResource, XMLStreamWriter theWriter, List<ExtensionDt> extensions, String tagName, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
||||||
boolean theIncludedResource) throws XMLStreamException, DataFormatException {
|
|
||||||
for (ExtensionDt next : extensions) {
|
for (ExtensionDt next : extensions) {
|
||||||
theWriter.writeStartElement(tagName);
|
theWriter.writeStartElement(tagName);
|
||||||
theWriter.writeAttribute("url", next.getUrl().getValue());
|
theWriter.writeAttribute("url", next.getUrl().getValue());
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
ca.uhn.fhir.context.FhirContext.noStructures=Could not find any HAPI-FHIR structure JARs on the classpath. Note that as of HAPI-FHIR v0.8, a separate FHIR strcture JAR must be added to your classpath (or project pom.xml if you are using Maven)
|
||||||
|
ca.uhn.fhir.context.FhirContext.noStructuresForSpecifiedVersion=Could not find the HAPI-FHIR structure JAR on the classpath for version {0}. Note that as of HAPI-FHIR v0.8, a separate FHIR strcture JAR must be added to your classpath (or project pom.xml if you are using Maven)
|
||||||
|
|
||||||
ca.uhn.fhir.rest.client.GenericClient.noVersionIdForVread=No version specified in URL for 'vread' operation: {0}
|
ca.uhn.fhir.rest.client.GenericClient.noVersionIdForVread=No version specified in URL for 'vread' operation: {0}
|
||||||
ca.uhn.fhir.rest.client.GenericClient.incompleteUriForRead=The given URI is not an absolute URL and is not usable for this operation: {0}
|
ca.uhn.fhir.rest.client.GenericClient.incompleteUriForRead=The given URI is not an absolute URL and is not usable for this operation: {0}
|
||||||
ca.uhn.fhir.rest.client.GenericClient.cannotDetermineResourceTypeFromUri=Unable to determine the resource type from the given URI: {0}
|
ca.uhn.fhir.rest.client.GenericClient.cannotDetermineResourceTypeFromUri=Unable to determine the resource type from the given URI: {0}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<value>blaze , Blaze (Orion Health) , https://fhir.orionhealth.com/blaze/fhir</value>
|
<value>blaze , Blaze (Orion Health) , https://fhir.orionhealth.com/blaze/fhir</value>
|
||||||
<value>oridashi , Oridashi , http://demo.oridashi.com.au:8190</value>
|
<value>oridashi , Oridashi , http://demo.oridashi.com.au:8190</value>
|
||||||
<!-- <value>fhirbase , FHIRPlace (Health Samurai) , http://try-fhirplace.hospital-systems.com/ </value> -->
|
<!-- <value>fhirbase , FHIRPlace (Health Samurai) , http://try-fhirplace.hospital-systems.com/ </value> -->
|
||||||
|
<value>nortal , Nortal , http://fhir.nortal.com/fhir-server</value>
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" path="src/test/resources"/>
|
||||||
<classpathentry kind="src" path="target/generated-resources/tinder"/>
|
<classpathentry kind="src" path="target/generated-resources/tinder"/>
|
||||||
<classpathentry kind="src" path="target/generated-sources/tinder"/>
|
<classpathentry kind="src" path="target/generated-sources/tinder"/>
|
||||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||||
|
|
|
@ -20,8 +20,12 @@ package ca.uhn.fhir.model.dev;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.IFhirVersion;
|
import ca.uhn.fhir.model.api.IFhirVersion;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -61,4 +65,21 @@ public class FhirDev implements IFhirVersion {
|
||||||
return new ServerProfileProvider(theRestfulServer.getFhirContext());
|
return new ServerProfileProvider(theRestfulServer.getFhirContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FhirVersionEnum getVersion() {
|
||||||
|
return FhirVersionEnum.DEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getFhirVersionPropertiesFile() {
|
||||||
|
InputStream str = FhirDev.class.getResourceAsStream("/ca/uhn/fhir/model/dev/fhirversion.properties");
|
||||||
|
if (str == null) {
|
||||||
|
str = FhirDev.class.getResourceAsStream("ca/uhn/fhir/model/dev/fhirversion.properties");
|
||||||
|
}
|
||||||
|
if (str == null) {
|
||||||
|
throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/dev/model.properties");
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.dev.composite;
|
package ca.uhn.fhir.model.dev.composite;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR Structures - DEV (FHIR Latest)
|
* HAPI FHIR Structures - DEV (FHIR Latest)
|
||||||
|
@ -20,6 +22,7 @@ package ca.uhn.fhir.model.dev.composite;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@DatatypeDef(name="AgeDt")
|
||||||
public class AgeDt extends QuantityDt {
|
public class AgeDt extends QuantityDt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.dev.composite;
|
package ca.uhn.fhir.model.dev.composite;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR Structures - DEV (FHIR Latest)
|
* HAPI FHIR Structures - DEV (FHIR Latest)
|
||||||
|
@ -20,6 +22,7 @@ package ca.uhn.fhir.model.dev.composite;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@DatatypeDef(name="CountDt")
|
||||||
public class CountDt extends QuantityDt {
|
public class CountDt extends QuantityDt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.dev.composite;
|
package ca.uhn.fhir.model.dev.composite;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR Structures - DEV (FHIR Latest)
|
* HAPI FHIR Structures - DEV (FHIR Latest)
|
||||||
|
@ -20,6 +22,7 @@ package ca.uhn.fhir.model.dev.composite;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@DatatypeDef(name="DistanceDt")
|
||||||
public class DistanceDt extends QuantityDt {
|
public class DistanceDt extends QuantityDt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.dev.composite;
|
package ca.uhn.fhir.model.dev.composite;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR Structures - DEV (FHIR Latest)
|
* HAPI FHIR Structures - DEV (FHIR Latest)
|
||||||
|
@ -20,6 +22,7 @@ package ca.uhn.fhir.model.dev.composite;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@DatatypeDef(name="DurationDt")
|
||||||
public class DurationDt extends QuantityDt {
|
public class DurationDt extends QuantityDt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.model.dev.composite;
|
package ca.uhn.fhir.model.dev.composite;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR Structures - DEV (FHIR Latest)
|
* HAPI FHIR Structures - DEV (FHIR Latest)
|
||||||
|
@ -20,6 +22,7 @@ package ca.uhn.fhir.model.dev.composite;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@DatatypeDef(name="MoneyDt")
|
||||||
public class MoneyDt extends QuantityDt {
|
public class MoneyDt extends QuantityDt {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import net.sf.json.JSON;
|
||||||
|
import net.sf.json.JSONSerializer;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
|
import ca.uhn.fhir.model.dev.resource.MedicationPrescription;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
|
||||||
|
public class JsonParserTest {
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserTest.class);
|
||||||
|
private static final FhirContext ourCtx = FhirContext.forDev();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseBundleWithBinary() {
|
||||||
|
// TODO: implement this test, make sure we handle ID and meta correctly in Binary
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseAndEncodeBundle() throws Exception {
|
||||||
|
String content = IOUtils.toString(JsonParserTest.class.getResourceAsStream("/bundle-example.json"));
|
||||||
|
|
||||||
|
Bundle parsed = ourCtx.newJsonParser().parseBundle(content);
|
||||||
|
assertEquals("http://example.com/base/Bundle/example/_history/1", parsed.getId().getValue());
|
||||||
|
assertEquals("1", parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION));
|
||||||
|
assertEquals("1", parsed.getId().getVersionIdPart());
|
||||||
|
assertEquals(new InstantDt("2014-08-18T01:43:30Z"), parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
||||||
|
assertEquals("transaction", parsed.getType().getValue());
|
||||||
|
assertEquals(3, parsed.getTotalResults().getValue().intValue());
|
||||||
|
assertEquals("http://example.com/base", parsed.getLinkBase().getValue());
|
||||||
|
assertEquals("https://example.com/base/MedicationPrescription?patient=347&searchId=ff15fd40-ff71-4b48-b366-09c706bed9d0&page=2", parsed.getLinkNext().getValue());
|
||||||
|
assertEquals("https://example.com/base/MedicationPrescription?patient=347", parsed.getLinkSelf().getValue());
|
||||||
|
|
||||||
|
assertEquals(1, parsed.getEntries().size());
|
||||||
|
assertEquals("update", parsed.getEntries().get(0).getStatus().getValue());
|
||||||
|
|
||||||
|
MedicationPrescription p = (MedicationPrescription) parsed.getEntries().get(0).getResource();
|
||||||
|
assertEquals("Patient/example", p.getPatient().getReference().getValue());
|
||||||
|
assertEquals("2014-08-16T05:31:17Z", ResourceMetadataKeyEnum.UPDATED.get(p).getValueAsString());
|
||||||
|
assertEquals("http://example.com/base/MedicationPrescription/3123/_history/1", p.getId().getValue());
|
||||||
|
|
||||||
|
String reencoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(parsed);
|
||||||
|
ourLog.info(reencoded);
|
||||||
|
|
||||||
|
JSON expected = JSONSerializer.toJSON(content.trim());
|
||||||
|
JSON actual = JSONSerializer.toJSON(reencoded.trim());
|
||||||
|
|
||||||
|
String exp = expected.toString().replace("\\r\\n", "\\n"); // .replace("§", "§");
|
||||||
|
String act = actual.toString().replace("\\r\\n", "\\n");
|
||||||
|
|
||||||
|
ourLog.info("Expected: {}", exp);
|
||||||
|
ourLog.info("Actual : {}", act);
|
||||||
|
|
||||||
|
assertEquals(exp, act);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.custommonkey.xmlunit.Diff;
|
||||||
|
import org.custommonkey.xmlunit.XMLUnit;
|
||||||
|
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.ResourceMetadataKeyEnum;
|
||||||
|
import ca.uhn.fhir.model.dev.resource.MedicationPrescription;
|
||||||
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
|
||||||
|
public class XmlParserTest {
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserTest.class);
|
||||||
|
private static final FhirContext ourCtx = FhirContext.forDev();
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
XMLUnit.setIgnoreAttributeOrder(true);
|
||||||
|
XMLUnit.setIgnoreComments(true);
|
||||||
|
XMLUnit.setIgnoreWhitespace(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseBundleWithBinary() {
|
||||||
|
// TODO: implement this test, make sure we handle ID and meta correctly in Binary
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseAndEncodeBundle() throws Exception {
|
||||||
|
String content = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/bundle-example(example).xml"));
|
||||||
|
|
||||||
|
Bundle parsed = ourCtx.newXmlParser().parseBundle(content);
|
||||||
|
assertEquals("http://example.com/base/Bundle/example/_history/1", parsed.getId().getValue());
|
||||||
|
assertEquals("1", parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION));
|
||||||
|
assertEquals("1", parsed.getId().getVersionIdPart());
|
||||||
|
assertEquals(new InstantDt("2014-08-18T01:43:30Z"), parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
||||||
|
assertEquals("transaction", parsed.getType().getValue());
|
||||||
|
assertEquals(3, parsed.getTotalResults().getValue().intValue());
|
||||||
|
assertEquals("http://example.com/base", parsed.getLinkBase().getValue());
|
||||||
|
assertEquals("https://example.com/base/MedicationPrescription?patient=347&searchId=ff15fd40-ff71-4b48-b366-09c706bed9d0&page=2", parsed.getLinkNext().getValue());
|
||||||
|
assertEquals("https://example.com/base/MedicationPrescription?patient=347", parsed.getLinkSelf().getValue());
|
||||||
|
|
||||||
|
assertEquals(1, parsed.getEntries().size());
|
||||||
|
assertEquals("update", parsed.getEntries().get(0).getStatus().getValue());
|
||||||
|
|
||||||
|
MedicationPrescription p = (MedicationPrescription) parsed.getEntries().get(0).getResource();
|
||||||
|
assertEquals("Patient/example", p.getPatient().getReference().getValue());
|
||||||
|
assertEquals("2014-08-16T05:31:17Z", ResourceMetadataKeyEnum.UPDATED.get(p).getValueAsString());
|
||||||
|
assertEquals("http://example.com/base/MedicationPrescription/3123/_history/1", p.getId().getValue());
|
||||||
|
|
||||||
|
String reencoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(parsed);
|
||||||
|
ourLog.info(reencoded);
|
||||||
|
|
||||||
|
Diff d = new Diff(new StringReader(content), new StringReader(reencoded));
|
||||||
|
assertTrue(d.toString(), d.identical());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?><Bundle xmlns="http://hl7.org/fhir">
|
||||||
|
<id value="example"/>
|
||||||
|
<meta>
|
||||||
|
<versionId value="1"/>
|
||||||
|
<lastUpdated value="2014-08-18T01:43:30Z"/>
|
||||||
|
</meta>
|
||||||
|
<type value="transaction"/>
|
||||||
|
<base value="http://example.com/base"/>
|
||||||
|
<total value="3"/>
|
||||||
|
<link>
|
||||||
|
<relation value="next"/>
|
||||||
|
<url value="https://example.com/base/MedicationPrescription?patient=347&searchId=ff15fd40-ff71-4b48-b366-09c706bed9d0&page=2"/>
|
||||||
|
</link>
|
||||||
|
<link>
|
||||||
|
<relation value="self"/>
|
||||||
|
<url value="https://example.com/base/MedicationPrescription?patient=347"/>
|
||||||
|
</link>
|
||||||
|
<entry>
|
||||||
|
<status value="update"/>
|
||||||
|
<resource>
|
||||||
|
<MedicationPrescription>
|
||||||
|
<id value="3123"/>
|
||||||
|
<meta>
|
||||||
|
<versionId value="1"/>
|
||||||
|
<lastUpdated value="2014-08-16T05:31:17Z"/>
|
||||||
|
</meta>
|
||||||
|
<text>
|
||||||
|
<status value="generated"/>
|
||||||
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p>Penicillin VK 5ml suspension to be administered by oral route</p>
|
||||||
|
<p>ONE 5ml spoonful to be taken THREE times a day</p>
|
||||||
|
<p>100ml bottle</p>
|
||||||
|
<p>to patient ref: a23</p>
|
||||||
|
<p>by doctor X</p>
|
||||||
|
</div>
|
||||||
|
</text>
|
||||||
|
<status value="active"/>
|
||||||
|
<patient>
|
||||||
|
<reference value="Patient/example"/>
|
||||||
|
</patient>
|
||||||
|
<prescriber>
|
||||||
|
<reference value="Practitioner/example"/>
|
||||||
|
</prescriber>
|
||||||
|
|
||||||
|
<medication>
|
||||||
|
<reference value="Medication/example"/>
|
||||||
|
</medication>
|
||||||
|
|
||||||
|
<dosageInstruction>
|
||||||
|
<scheduledTiming>
|
||||||
|
<repeat>
|
||||||
|
<frequency value="3"/>
|
||||||
|
<duration value="1"/>
|
||||||
|
<units value="d"/>
|
||||||
|
</repeat>
|
||||||
|
</scheduledTiming>
|
||||||
|
<route>
|
||||||
|
<coding>
|
||||||
|
<system value="http://snomed.info/sct"/>
|
||||||
|
<code value="394899003"/>
|
||||||
|
<display value="oral administration of treatment"/>
|
||||||
|
</coding>
|
||||||
|
</route>
|
||||||
|
<doseQuantity>
|
||||||
|
<value value="5"/>
|
||||||
|
<units value="ml"/>
|
||||||
|
<system value="http://unitsofmeasure.org"/>
|
||||||
|
<code value="ml"/>
|
||||||
|
</doseQuantity>
|
||||||
|
</dosageInstruction>
|
||||||
|
|
||||||
|
<dispense>
|
||||||
|
<quantity>
|
||||||
|
<value value="100"/>
|
||||||
|
<units value="ml"/>
|
||||||
|
<system value="http://unitsofmeasure.org"/>
|
||||||
|
<code value="ml"/>
|
||||||
|
</quantity>
|
||||||
|
</dispense>
|
||||||
|
|
||||||
|
</MedicationPrescription>
|
||||||
|
</resource>
|
||||||
|
</entry>
|
||||||
|
</Bundle>
|
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
"resourceType": "Bundle",
|
||||||
|
"id": "example",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "1",
|
||||||
|
"lastUpdated": "2014-08-18T01:43:30Z"
|
||||||
|
},
|
||||||
|
"type": "transaction",
|
||||||
|
"base": "http://example.com/base",
|
||||||
|
"total": 3,
|
||||||
|
"link": [
|
||||||
|
{
|
||||||
|
"relation": "next",
|
||||||
|
"url": "https://example.com/base/MedicationPrescription?patient=347&searchId=ff15fd40-ff71-4b48-b366-09c706bed9d0&page=2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"relation": "self",
|
||||||
|
"url": "https://example.com/base/MedicationPrescription?patient=347"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"entry": [
|
||||||
|
{
|
||||||
|
"status": "update",
|
||||||
|
"resource": {
|
||||||
|
"resourceType": "MedicationPrescription",
|
||||||
|
"id": "3123",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "1",
|
||||||
|
"lastUpdated": "2014-08-16T05:31:17Z"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"status": "generated",
|
||||||
|
"div": "<div>\n <p>Penicillin VK 5ml suspension to be administered by oral route</p>\n <p>ONE 5ml spoonful to be taken THREE times a day</p>\n <p>100ml bottle</p>\n <p>to patient ref: a23</p>\n <p>by doctor X</p>\n </div>"
|
||||||
|
},
|
||||||
|
"status": "active",
|
||||||
|
"patient": {
|
||||||
|
"reference": "Patient/example"
|
||||||
|
},
|
||||||
|
"prescriber": {
|
||||||
|
"reference": "Practitioner/example"
|
||||||
|
},
|
||||||
|
"medication": {
|
||||||
|
"reference": "Medication/example"
|
||||||
|
},
|
||||||
|
"dosageInstruction": [
|
||||||
|
{
|
||||||
|
"scheduledTiming": {
|
||||||
|
"repeat": {
|
||||||
|
"frequency": 3,
|
||||||
|
"duration": 1,
|
||||||
|
"units": "d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://snomed.info/sct",
|
||||||
|
"code": "394899003",
|
||||||
|
"display": "oral administration of treatment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"doseQuantity": {
|
||||||
|
"value": 5,
|
||||||
|
"units": "ml",
|
||||||
|
"system": "http://unitsofmeasure.org",
|
||||||
|
"code": "ml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dispense": {
|
||||||
|
"quantity": {
|
||||||
|
"value": 100,
|
||||||
|
"units": "ml",
|
||||||
|
"system": "http://unitsofmeasure.org",
|
||||||
|
"code": "ml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -20,9 +20,9 @@ package ca.uhn.fhir.model.dstu;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.join;
|
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -31,12 +31,30 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.*;
|
|
||||||
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.text.WordUtils;
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
||||||
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildCompositeDatatypeDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildContainedResources;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildPrimitiveDatatypeDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildResourceBlockDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeCompositeDatatypeDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
|
||||||
|
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||||
import ca.uhn.fhir.model.api.IFhirVersion;
|
import ca.uhn.fhir.model.api.IFhirVersion;
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -318,4 +336,24 @@ public class FhirDstu1 implements IFhirVersion {
|
||||||
return new ServerProfileProvider(theRestfulServer.getFhirContext());
|
return new ServerProfileProvider(theRestfulServer.getFhirContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FhirVersionEnum getVersion() {
|
||||||
|
return FhirVersionEnum.DSTU1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getFhirVersionPropertiesFile() {
|
||||||
|
InputStream str = FhirDstu1.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/fhirversion.properties");
|
||||||
|
if (str == null) {
|
||||||
|
str = FhirDstu1.class.getResourceAsStream("ca/uhn/fhir/model/dstu/fhirversion.properties");
|
||||||
|
}
|
||||||
|
if (str == null) {
|
||||||
|
throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/dstu/model.properties");
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package ca.uhn.fhir.context;
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -23,4 +24,14 @@ public class FhirContextTest {
|
||||||
assertEquals("Binary", def.getName());
|
assertEquals("Binary", def.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnknownVersion() {
|
||||||
|
try {
|
||||||
|
new FhirContext(FhirVersionEnum.DEV);
|
||||||
|
fail();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("Could not find the HAPI-FHIR structure JAR on the classpath for version {0}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package ca.uhn.fhir.context;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class FhirVersionEnumTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsNewerThan() {
|
||||||
|
assertTrue(FhirVersionEnum.DEV.isNewerThan(FhirVersionEnum.DSTU1));
|
||||||
|
assertFalse(FhirVersionEnum.DSTU1.isNewerThan(FhirVersionEnum.DEV));
|
||||||
|
assertFalse(FhirVersionEnum.DEV.isNewerThan(FhirVersionEnum.DEV));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,7 +18,6 @@ import net.sf.json.JSON;
|
||||||
import net.sf.json.JSONSerializer;
|
import net.sf.json.JSONSerializer;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.hamcrest.Matchers;
|
|
||||||
import org.hamcrest.core.IsNot;
|
import org.hamcrest.core.IsNot;
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
import org.hamcrest.text.StringContainsInOrder;
|
import org.hamcrest.text.StringContainsInOrder;
|
||||||
|
|
|
@ -132,7 +132,7 @@ function addSearchControls(theConformance, theSearchParamType, theSearchParamNam
|
||||||
} else if (theSearchParamType == 'date') {
|
} else if (theSearchParamType == 'date') {
|
||||||
addSearchControlDate(theSearchParamName, theContainerRowNum, theRowNum, true);
|
addSearchControlDate(theSearchParamName, theContainerRowNum, theRowNum, true);
|
||||||
addSearchControlDate(theSearchParamName, theContainerRowNum, theRowNum, false);
|
addSearchControlDate(theSearchParamName, theContainerRowNum, theRowNum, false);
|
||||||
} else if (theSearchParamType == 'reference' && theSearchParamChain.length == 0) {
|
} else if (theSearchParamType == 'reference' && (!theSearchParamChain || theSearchParamChain.length == 0)) {
|
||||||
/*
|
/*
|
||||||
* This is a reference parameter with no chain options, so just display a simple
|
* This is a reference parameter with no chain options, so just display a simple
|
||||||
* text box for the ID of the referenced resource
|
* text box for the ID of the referenced resource
|
||||||
|
|
|
@ -30,6 +30,18 @@
|
||||||
</ul>
|
</ul>
|
||||||
]]>
|
]]>
|
||||||
</action>
|
</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">
|
<action type="add" issue="38" dev="wdebeau1">
|
||||||
Profile generation on the server was not working due to IdDt being
|
Profile generation on the server was not working due to IdDt being
|
||||||
incorrectly used. Thanks to Bill de Beaubien for the pull request!
|
incorrectly used. Thanks to Bill de Beaubien for the pull request!
|
||||||
|
|
Loading…
Reference in New Issue