More work on HL7.org structs

This commit is contained in:
James Agnew 2014-12-10 14:28:25 -05:00
parent 463fe249e6
commit ec8fdc7d68
32 changed files with 132 additions and 218 deletions

View File

@ -29,6 +29,8 @@ import java.util.Map;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.text.WordUtils;
import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.i18n.HapiLocalizer; import ca.uhn.fhir.i18n.HapiLocalizer;
import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IElement;
@ -66,7 +68,7 @@ import ca.uhn.fhir.validation.FhirValidator;
public class FhirContext { public class FhirContext {
private static final List<Class<? extends IResource>> EMPTY_LIST = Collections.emptyList(); private static final List<Class<? extends IResource>> EMPTY_LIST = Collections.emptyList();
private volatile Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> myClassToElementDefinition = Collections.emptyMap(); private volatile Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinition = Collections.emptyMap();
private volatile Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = Collections.emptyMap(); private volatile Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = Collections.emptyMap();
private HapiLocalizer myLocalizer = new HapiLocalizer(); private HapiLocalizer myLocalizer = new HapiLocalizer();
private volatile Map<String, RuntimeResourceDefinition> myNameToElementDefinition = Collections.emptyMap(); private volatile Map<String, RuntimeResourceDefinition> myNameToElementDefinition = Collections.emptyMap();
@ -131,7 +133,7 @@ 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 IBaseResource> theResourceType) {
RuntimeResourceDefinition retVal = (RuntimeResourceDefinition) myClassToElementDefinition.get(theResourceType); RuntimeResourceDefinition retVal = (RuntimeResourceDefinition) myClassToElementDefinition.get(theResourceType);
if (retVal == null) { if (retVal == null) {
retVal = scanResourceType(theResourceType); retVal = scanResourceType(theResourceType);
@ -296,11 +298,11 @@ public class FhirContext {
private RuntimeResourceDefinition scanResourceType(Class<? extends IResource> theResourceType) { private RuntimeResourceDefinition scanResourceType(Class<? extends IResource> theResourceType) {
ArrayList<Class<? extends IResource>> resourceTypes = new ArrayList<Class<? extends IResource>>(); ArrayList<Class<? extends IResource>> resourceTypes = new ArrayList<Class<? extends IResource>>();
resourceTypes.add(theResourceType); resourceTypes.add(theResourceType);
Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> defs = scanResourceTypes(resourceTypes); Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> defs = scanResourceTypes(resourceTypes);
return (RuntimeResourceDefinition) defs.get(theResourceType); return (RuntimeResourceDefinition) defs.get(theResourceType);
} }
private Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> scanResourceTypes(Collection<Class<? extends IResource>> theResourceTypes) { private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> scanResourceTypes(Collection<Class<? extends IBaseResource>> theResourceTypes) {
ModelScanner scanner = new ModelScanner(this, myClassToElementDefinition, theResourceTypes); ModelScanner scanner = new ModelScanner(this, myClassToElementDefinition, theResourceTypes);
if (myRuntimeChildUndeclaredExtensionDefinition == null) { if (myRuntimeChildUndeclaredExtensionDefinition == null) {
myRuntimeChildUndeclaredExtensionDefinition = scanner.getRuntimeChildUndeclaredExtensionDefinition(); myRuntimeChildUndeclaredExtensionDefinition = scanner.getRuntimeChildUndeclaredExtensionDefinition();
@ -310,7 +312,7 @@ public class FhirContext {
nameToElementDefinition.putAll(myNameToElementDefinition); nameToElementDefinition.putAll(myNameToElementDefinition);
nameToElementDefinition.putAll(scanner.getNameToResourceDefinitions()); nameToElementDefinition.putAll(scanner.getNameToResourceDefinitions());
Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> classToElementDefinition = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>(); Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> classToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
classToElementDefinition.putAll(myClassToElementDefinition); classToElementDefinition.putAll(myClassToElementDefinition);
classToElementDefinition.putAll(scanner.getClassToElementDefinitions()); classToElementDefinition.putAll(scanner.getClassToElementDefinitions());

View File

@ -43,6 +43,10 @@ import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.ICompositeType;
import ca.uhn.fhir.model.api.CodeableConceptElement; import ca.uhn.fhir.model.api.CodeableConceptElement;
import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IBoundCodeableConcept; import ca.uhn.fhir.model.api.IBoundCodeableConcept;
@ -74,7 +78,7 @@ import ca.uhn.fhir.util.ReflectionUtil;
class ModelScanner { class ModelScanner {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
private Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>(); private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
private Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = new HashMap<String, RuntimeResourceDefinition>(); private Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = new HashMap<String, RuntimeResourceDefinition>();
private Map<String, RuntimeResourceDefinition> myNameToResourceDefinitions = new HashMap<String, RuntimeResourceDefinition>(); private Map<String, RuntimeResourceDefinition> myNameToResourceDefinitions = new HashMap<String, RuntimeResourceDefinition>();
@ -86,30 +90,30 @@ class ModelScanner {
private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition; private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
private Set<Class<? extends IElement>> myScanAlso = new HashSet<Class<? extends IElement>>(); private Set<Class<? extends IBase>> myScanAlso = new HashSet<Class<? extends IBase>>();
private Set<Class<? extends ICodeEnum>> myScanAlsoCodeTable = new HashSet<Class<? extends ICodeEnum>>(); private Set<Class<? extends ICodeEnum>> myScanAlsoCodeTable = new HashSet<Class<? extends ICodeEnum>>();
private FhirContext myContext; private FhirContext myContext;
ModelScanner(FhirContext theContext, Class<? extends IResource> theResourceTypes) throws ConfigurationException { ModelScanner(FhirContext theContext, Class<? extends IBaseResource> theResourceTypes) throws ConfigurationException {
myContext=theContext; myContext=theContext;
Set<Class<? extends IElement>> singleton = new HashSet<Class<? extends IElement>>(); Set<Class<? extends IBase>> singleton = new HashSet<Class<? extends IBase>>();
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 IBaseResource>> theResourceTypes) throws ConfigurationException {
myContext=theContext; myContext=theContext;
init(null, new HashSet<Class<? extends IElement>>(theResourceTypes)); init(null, new HashSet<Class<? extends IBase>>(theResourceTypes));
} }
ModelScanner(FhirContext theContext, Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Collection<Class<? extends IResource>> theResourceTypes) throws ConfigurationException { ModelScanner(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Collection<Class<? extends IBase>> theResourceTypes) throws ConfigurationException {
myContext=theContext; myContext=theContext;
init(theExistingDefinitions, new HashSet<Class<? extends IElement>>(theResourceTypes)); init(theExistingDefinitions, new HashSet<Class<? extends IBase>>(theResourceTypes));
} }
public Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> getClassToElementDefinitions() { public Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> getClassToElementDefinitions() {
return myClassToElementDefinitions; return myClassToElementDefinitions;
} }
@ -167,7 +171,7 @@ class ModelScanner {
} }
} }
private void init(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Set<Class<? extends IElement>> toScan) { private void init(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Set<Class<? extends IBase>> toScan) {
if (theExistingDefinitions != null) { if (theExistingDefinitions != null) {
myClassToElementDefinitions.putAll(theExistingDefinitions); myClassToElementDefinitions.putAll(theExistingDefinitions);
} }
@ -222,10 +226,10 @@ class ModelScanner {
// toScan.add(QuantityDt.class); // toScan.add(QuantityDt.class);
do { do {
for (Class<? extends IElement> nextClass : toScan) { for (Class<? extends IBase> nextClass : toScan) {
scan(nextClass); scan(nextClass);
} }
for (Iterator<Class<? extends IElement>> iter = myScanAlso.iterator(); iter.hasNext();) { for (Iterator<Class<? extends IBase>> iter = myScanAlso.iterator(); iter.hasNext();) {
if (myClassToElementDefinitions.containsKey(iter.next())) { if (myClassToElementDefinitions.containsKey(iter.next())) {
iter.remove(); iter.remove();
} }
@ -235,7 +239,7 @@ class ModelScanner {
myScanAlso.clear(); myScanAlso.clear();
} while (!toScan.isEmpty()); } while (!toScan.isEmpty());
for (Entry<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> nextEntry : myClassToElementDefinitions.entrySet()) { for (Entry<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> nextEntry : myClassToElementDefinitions.entrySet()) {
if (theExistingDefinitions != null && theExistingDefinitions.containsKey(nextEntry.getKey())) { if (theExistingDefinitions != null && theExistingDefinitions.containsKey(nextEntry.getKey())) {
continue; continue;
} }
@ -251,7 +255,7 @@ class ModelScanner {
ourLog.info("Done scanning FHIR library, found {} model entries in {}ms", size, time); ourLog.info("Done scanning FHIR library, found {} model entries in {}ms", size, time);
} }
private void scan(Class<? extends IElement> theClass) throws ConfigurationException { private void scan(Class<? extends IBase> theClass) throws ConfigurationException {
BaseRuntimeElementDefinition<?> existingDef = myClassToElementDefinitions.get(theClass); BaseRuntimeElementDefinition<?> existingDef = myClassToElementDefinitions.get(theClass);
if (existingDef != null) { if (existingDef != null) {
return; return;
@ -269,13 +273,13 @@ class ModelScanner {
DatatypeDef datatypeDefinition = theClass.getAnnotation(DatatypeDef.class); DatatypeDef datatypeDefinition = theClass.getAnnotation(DatatypeDef.class);
if (datatypeDefinition != null) { if (datatypeDefinition != null) {
if (ICompositeDatatype.class.isAssignableFrom(theClass)) { if (ICompositeType.class.isAssignableFrom(theClass)) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Class<? extends ICompositeDatatype> resClass = (Class<? extends ICompositeDatatype>) theClass; Class<? extends ICompositeType> resClass = (Class<? extends ICompositeType>) theClass;
scanCompositeDatatype(resClass, datatypeDefinition); scanCompositeDatatype(resClass, datatypeDefinition);
} else if (IPrimitiveDatatype.class.isAssignableFrom(theClass)) { } else if (IPrimitiveType.class.isAssignableFrom(theClass)) {
@SuppressWarnings({ "unchecked" }) @SuppressWarnings({ "unchecked" })
Class<? extends IPrimitiveDatatype<?>> resClass = (Class<? extends IPrimitiveDatatype<?>>) theClass; Class<? extends IPrimitiveType) resClass = (Class<? extends IPrimitiveType>) theClass;
scanPrimitiveDatatype(resClass, datatypeDefinition); scanPrimitiveDatatype(resClass, datatypeDefinition);
} else { } else {
throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": " + theClass.getCanonicalName()); throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": " + theClass.getCanonicalName());

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.api; package ca.uhn.fhir.model.api;
import org.hl7.fhir.instance.model.ICompositeType;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -22,6 +24,6 @@ package ca.uhn.fhir.model.api;
public interface ICompositeDatatype extends IDatatype, ICompositeElement { public interface ICompositeDatatype extends IDatatype, ICompositeElement, ICompositeType {
} }

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.api; package ca.uhn.fhir.model.api;
import org.hl7.fhir.instance.model.IBase;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -22,7 +24,7 @@ package ca.uhn.fhir.model.api;
public interface IElement { public interface IElement extends IBase {
boolean isEmpty(); boolean isEmpty();

View File

@ -20,9 +20,11 @@ package ca.uhn.fhir.model.api;
* #L% * #L%
*/ */
import org.hl7.fhir.instance.model.IPrimitiveType;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
public interface IPrimitiveDatatype<T> extends IDatatype { public interface IPrimitiveDatatype<T> extends IDatatype, IPrimitiveType {
void setValueAsString(String theValue) throws DataFormatException; void setValueAsString(String theValue) throws DataFormatException;

View File

@ -39,7 +39,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
* should not need to implement it directly. * should not need to implement it directly.
* <p> * <p>
*/ */
public interface IResource extends ICompositeElement { public interface IResource extends ICompositeElement, org.hl7.fhir.instance.model.IBaseResource {
/** /**
* Returns the contained resource list for this resource. * Returns the contained resource list for this resource.

View File

@ -34,6 +34,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition; import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
@ -65,7 +66,7 @@ public abstract class BaseParser implements IParser {
} }
private void containResourcesForEncoding(ContainedResources theContained, IResource theResource, IResource theTarget) { private void containResourcesForEncoding(ContainedResources theContained, IBaseResource theResource, IBaseResource theTarget) {
List<ResourceReferenceDt> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, ResourceReferenceDt.class); List<ResourceReferenceDt> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, ResourceReferenceDt.class);
Set<String> allIds = new HashSet<String>(); Set<String> allIds = new HashSet<String>();
@ -92,7 +93,7 @@ public abstract class BaseParser implements IParser {
} }
public void containResourcesForEncoding(IResource theResource) { public void containResourcesForEncoding(IBaseResource theResource) {
ContainedResources contained = new ContainedResources(); ContainedResources contained = new ContainedResources();
containResourcesForEncoding(contained, theResource, theResource); containResourcesForEncoding(contained, theResource, theResource);
myContainedResources = contained; myContainedResources = contained;
@ -114,7 +115,7 @@ public abstract class BaseParser implements IParser {
} }
@Override @Override
public String encodeResourceToString(IResource theResource) throws DataFormatException { public String encodeResourceToString(IBaseResource theResource) throws DataFormatException {
Writer stringWriter = new StringWriter(); Writer stringWriter = new StringWriter();
try { try {
encodeResourceToWriter(theResource, stringWriter); encodeResourceToWriter(theResource, stringWriter);
@ -159,7 +160,7 @@ public abstract class BaseParser implements IParser {
@SuppressWarnings("cast") @SuppressWarnings("cast")
@Override @Override
public <T extends IResource> T parseResource(Class<T> theResourceType, String theMessageString) { public <T extends IBaseResource> T parseResource(Class<T> theResourceType, String theMessageString) {
StringReader reader = new StringReader(theMessageString); StringReader reader = new StringReader(theMessageString);
return (T) parseResource(theResourceType, reader); return (T) parseResource(theResourceType, reader);
} }

View File

@ -24,6 +24,7 @@ import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.Resource; import org.hl7.fhir.instance.model.Resource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
@ -43,9 +44,9 @@ public interface IParser {
void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws IOException, DataFormatException; void encodeBundleToWriter(Bundle theBundle, Writer theWriter) throws IOException, DataFormatException;
String encodeResourceToString(IResource theResource) throws DataFormatException; String encodeResourceToString(IBaseResource theResource) throws DataFormatException;
void encodeResourceToWriter(IResource theResource, Writer theWriter) throws IOException, DataFormatException; void encodeResourceToWriter(IBaseResource theResource, Writer theWriter) throws IOException, DataFormatException;
/** /**
* Encodes a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR Specification</a>. * Encodes a tag list, as defined in the <a href="http://hl7.org/implement/standards/fhir/http.html#tags">FHIR Specification</a>.
@ -83,7 +84,7 @@ public interface IParser {
* @throws DataFormatException * @throws DataFormatException
* If the resource can not be parsed because the data is not recognized or invalid for any reason * If the resource can not be parsed because the data is not recognized or invalid for any reason
*/ */
<T extends IResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException; <T extends IBaseResource> T parseResource(Class<T> theResourceType, Reader theReader) throws DataFormatException;
/** /**
* Parses a resource * Parses a resource
@ -96,7 +97,7 @@ public interface IParser {
* @throws DataFormatException * @throws DataFormatException
* If the resource can not be parsed because the data is not recognized or invalid for any reason * If the resource can not be parsed because the data is not recognized or invalid for any reason
*/ */
<T extends IResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException; <T extends IBaseResource> T parseResource(Class<T> theResourceType, String theString) throws DataFormatException;
/** /**
* Parses a resource * Parses a resource

View File

@ -46,6 +46,8 @@ import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent; import javax.xml.stream.events.XMLEvent;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.Resource;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
@ -236,7 +238,7 @@ public class XmlParser extends BaseParser implements IParser {
} }
@Override @Override
public String encodeResourceToString(IResource theResource) throws DataFormatException { public String encodeResourceToString(IBaseResource theResource) throws DataFormatException {
if (theResource == null) { if (theResource == null) {
throw new NullPointerException("Resource can not be null"); throw new NullPointerException("Resource can not be null");
} }
@ -247,7 +249,7 @@ public class XmlParser extends BaseParser implements IParser {
} }
@Override @Override
public void encodeResourceToWriter(IResource theResource, Writer theWriter) throws DataFormatException { public void encodeResourceToWriter(IBaseResource theResource, Writer theWriter) throws DataFormatException {
XMLStreamWriter eventWriter; XMLStreamWriter eventWriter;
try { try {
eventWriter = createXmlWriter(theWriter); eventWriter = createXmlWriter(theWriter);
@ -424,7 +426,7 @@ 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) throws XMLStreamException, DataFormatException { BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl, boolean theIncludedResource) 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 +469,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,7 +499,6 @@ public class XmlParser extends BaseParser implements IParser {
} }
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, XMLStreamWriter theEventWriter, private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IResource theResource, IElement theElement, XMLStreamWriter theEventWriter,
List<? extends BaseRuntimeChildDefinition> children, boolean theIncludedResource) throws XMLStreamException, DataFormatException { List<? extends BaseRuntimeChildDefinition> children, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
for (BaseRuntimeChildDefinition nextChild : children) { for (BaseRuntimeChildDefinition nextChild : children) {
@ -589,17 +590,25 @@ public class XmlParser extends BaseParser implements IParser {
} }
} }
private void encodeResourceToXmlStreamWriter(IBaseResource 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 (theResource instanceof IResource) {
resourceId = theResource.getId().getValue(); // HAPI structs
IResource iResource = (IResource) theResource;
if (theIncludedResource && StringUtils.isNotBlank(iResource.getId().getValue())) {
resourceId = iResource.getId().getValue();
}
} else {
// HL7 structs
Resource resource = (Resource) theResource;
if (theIncludedResource && StringUtils.isNotBlank(resource.getId())) {
resourceId = resource.getId();
}
} }
encodeResourceToXmlStreamWriter(theResource, theEventWriter, theIncludedResource, resourceId); encodeResourceToXmlStreamWriter(theResource, theEventWriter, theIncludedResource, resourceId);
} }
private void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource, String theResourceId) throws XMLStreamException { private void encodeResourceToXmlStreamWriter(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource, String theResourceId) throws XMLStreamException {
if (!theIncludedResource) { if (!theIncludedResource) {
super.containResourcesForEncoding(theResource); super.containResourcesForEncoding(theResource);
} }

View File

@ -26,6 +26,9 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.TreeSet; import java.util.TreeSet;
import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; 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;
@ -78,7 +81,7 @@ public class FhirTerser {
* The type to search for. Must not be null. * The type to search for. Must not be null.
* @return Returns a list of all matching elements * @return Returns a list of all matching elements
*/ */
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(IResource theResource, final Class<T> theType) { public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) {
final ArrayList<T> retVal = new ArrayList<T>(); final ArrayList<T> retVal = new ArrayList<T>();
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
visit(theResource, null, def, new IModelVisitor() { visit(theResource, null, def, new IModelVisitor() {

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* There is a variety of postal address formats defined around the world. This format defines a superset that is the basis for all addresses around the world. * There is a variety of postal address formats defined around the world. This format defines a superset that is the basis for all addresses around the world.
*/ */
@DatatypeDef(name="Address") @DatatypeDef(name="Address")
public class Address extends Type { public class Address extends Type implements ICompositeType{
public enum AddressUse implements FhirEnum { public enum AddressUse implements FhirEnum {
/** /**

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* For referring to data content defined in other formats. * For referring to data content defined in other formats.
*/ */
@DatatypeDef(name="Attachment") @DatatypeDef(name="Attachment")
public class Attachment extends Type { public class Attachment extends Type implements ICompositeType{
/** /**
* Identifies the type of the data in the attachment and allows a method to be chosen to interpret or render the data. Includes mime type parameters such as charset where appropriate. * Identifies the type of the data in the attachment and allows a method to be chosen to interpret or render the data. Includes mime type parameters such as charset where appropriate.

View File

@ -6,7 +6,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class Base implements Serializable { public abstract class Base implements Serializable, IBase {
/** /**
* User appended data items - allow users to add extra information to the class * User appended data items - allow users to add extra information to the class

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A concept that may be defined by a formal reference to a terminology or ontology or may be provided by text. * A concept that may be defined by a formal reference to a terminology or ontology or may be provided by text.
*/ */
@DatatypeDef(name="CodeableConcept") @DatatypeDef(name="CodeableConcept")
public class CodeableConcept extends Type { public class CodeableConcept extends Type implements ICompositeType{
/** /**
* A reference to a code defined by a terminology system. * A reference to a code defined by a terminology system.

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A reference to a code defined by a terminology system. * A reference to a code defined by a terminology system.
*/ */
@DatatypeDef(name="Coding") @DatatypeDef(name="Coding")
public class Coding extends Type { public class Coding extends Type implements ICompositeType{
/** /**
* The identification of the code system that defines the meaning of the symbol in the code. * The identification of the code system that defines the meaning of the symbol in the code.

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* Details for All kinds of technology mediated contact points for a person or organization, including telephone, email, etc. * Details for All kinds of technology mediated contact points for a person or organization, including telephone, email, etc.
*/ */
@DatatypeDef(name="ContactPoint") @DatatypeDef(name="ContactPoint")
public class ContactPoint extends Type { public class ContactPoint extends Type implements ICompositeType{
public enum ContactPointSystem implements FhirEnum { public enum ContactPointSystem implements FhirEnum {
/** /**

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* Captures constraints on each element within the resource, profile, or extension. * Captures constraints on each element within the resource, profile, or extension.
*/ */
@DatatypeDef(name="ElementDefinition") @DatatypeDef(name="ElementDefinition")
public class ElementDefinition extends Type { public class ElementDefinition extends Type implements ICompositeType{
public enum PropertyRepresentation implements FhirEnum { public enum PropertyRepresentation implements FhirEnum {
/** /**

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A human's name with the ability to identify parts and usage. * A human's name with the ability to identify parts and usage.
*/ */
@DatatypeDef(name="HumanName") @DatatypeDef(name="HumanName")
public class HumanName extends Type { public class HumanName extends Type implements ICompositeType {
public enum NameUse implements FhirEnum { public enum NameUse implements FhirEnum {
/** /**

View File

@ -0,0 +1,10 @@
package org.hl7.fhir.instance.model;
/**
* This interface is a simple marker for anything which is an HL7
* structure of some kind. It is provided mostly to simplify convergence
* between the HL7.org structures and the HAPI ones.
*/
public interface IBase {
}

View File

@ -0,0 +1,13 @@
package org.hl7.fhir.instance.model;
/**
* For now, this is a simple marker interface indicating that a class is a resource type.
* There are two concrete types of implementations of this interrface. The first are
* HL7.org's Resource structures (e.g.
* <code>org.hl7.fhir.instance.model.Patient</code>) and
* the second are HAPI's Resource structures, e.g.
* <code>ca.uhn.fhir.model.dstu.resource.Patient</code>)
*/
public interface IBaseResource extends IBase {
// nothing here yet
}

View File

@ -0,0 +1,5 @@
package org.hl7.fhir.instance.model;
public interface ICompositeType extends IBase {
}

View File

@ -0,0 +1,5 @@
package org.hl7.fhir.instance.model;
public interface IPrimitiveType extends IBase {
}

View File

@ -41,7 +41,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A technical identifier - identifies some entity uniquely and unambiguously. * A technical identifier - identifies some entity uniquely and unambiguously.
*/ */
@DatatypeDef(name="Identifier") @DatatypeDef(name="Identifier")
public class Identifier extends Type { public class Identifier extends Type implements ICompositeType{
public enum IdentifierUse implements FhirEnum { public enum IdentifierUse implements FhirEnum {
/** /**

View File

@ -40,7 +40,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A time period defined by a start and end date and optionally time. * A time period defined by a start and end date and optionally time.
*/ */
@DatatypeDef(name="Period") @DatatypeDef(name="Period")
public class Period extends Type { public class Period extends Type implements ICompositeType {
/** /**
* The start of the period. The boundary is inclusive. * The start of the period. The boundary is inclusive.

View File

@ -3,7 +3,7 @@ package org.hl7.fhir.instance.model;
import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder;
public abstract class PrimitiveType<T> extends Type { public abstract class PrimitiveType<T> extends Type implements IPrimitiveType {
private static final long serialVersionUID = 2L; private static final long serialVersionUID = 2L;

View File

@ -32,8 +32,8 @@ package org.hl7.fhir.instance.model;
// Generated on Sun, Dec 7, 2014 21:45-0500 for FHIR v0.3.0 // Generated on Sun, Dec 7, 2014 21:45-0500 for FHIR v0.3.0
import java.util.*; import java.util.*;
import java.math.*; import java.math.*;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
@ -42,7 +42,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A measured amount (or an amount that can potentially be measured). Note that measured amounts include amounts that are not precisely quantified, including amounts involving arbitrary units and floating currencies. * A measured amount (or an amount that can potentially be measured). Note that measured amounts include amounts that are not precisely quantified, including amounts involving arbitrary units and floating currencies.
*/ */
@DatatypeDef(name="Quantity") @DatatypeDef(name="Quantity")
public class Quantity extends Type { public class Quantity extends Type implements ICompositeType{
public enum QuantityComparator implements FhirEnum { public enum QuantityComparator implements FhirEnum {
/** /**

View File

@ -40,7 +40,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A set of ordered Quantities defined by a low and high limit. * A set of ordered Quantities defined by a low and high limit.
*/ */
@DatatypeDef(name="Range") @DatatypeDef(name="Range")
public class Range extends Type { public class Range extends Type implements ICompositeType{
/** /**
* The low limit. The boundary is inclusive. * The low limit. The boundary is inclusive.

View File

@ -40,7 +40,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A relationship of two Quantity values - expressed as a numerator and a denominator. * A relationship of two Quantity values - expressed as a numerator and a denominator.
*/ */
@DatatypeDef(name="Ratio") @DatatypeDef(name="Ratio")
public class Ratio extends Type { public class Ratio extends Type implements ICompositeType{
/** /**
* The value of the numerator. * The value of the numerator.

View File

@ -31,19 +31,20 @@ package org.hl7.fhir.instance.model;
// Generated on Fri, Dec 5, 2014 09:17+1100 for FHIR v0.3.0 // Generated on Fri, Dec 5, 2014 09:17+1100 for FHIR v0.3.0
import java.util.*; import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.instance.model.annotations.ResourceDef;
import org.hl7.fhir.instance.model.annotations.SearchParamDefinition;
import org.hl7.fhir.instance.model.annotations.Block; import org.hl7.fhir.instance.model.annotations.Block;
import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
import org.hl7.fhir.instance.model.annotations.ResourceDef;
import org.hl7.fhir.utilities.Utilities;
/** /**
* Base Resource for everything. * Base Resource for everything.
*/ */
@ResourceDef(name="Resource", profile="http://hl7.org/fhir/Profile/Resource") @ResourceDef(name="Resource", profile="http://hl7.org/fhir/Profile/Resource")
public abstract class Resource extends Base { public abstract class Resource extends Base implements IBaseResource {
@Block() @Block()
public static class ResourceMetaComponent extends BackboneElement { public static class ResourceMetaComponent extends BackboneElement {

View File

@ -1,146 +0,0 @@
package org.hl7.fhir.instance.model;
/*
Copyright (c) 2011-2013, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
// Generated on Sun, Feb 16, 2014 16:44-0500 for FHIR v0.80
import java.util.List;
/**
* A reference from one resource to another.
*/
public class ResourceReference extends Type {
/**
* A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.
*/
protected StringType reference;
/**
* Plain text narrative that identifies the resource in addition to the resource reference.
*/
protected StringType display;
public ResourceReference() {
super();
}
/**
* @return {@link #reference} (A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.)
*/
public StringType getReference() {
return this.reference;
}
/**
* @param value {@link #reference} (A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.)
*/
public ResourceReference setReference(StringType value) {
this.reference = value;
return this;
}
/**
* @return A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.
*/
public String getReferenceSimple() {
return this.reference == null ? null : this.reference.getValue();
}
/**
* @param value A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.
*/
public ResourceReference setReferenceSimple(String value) {
if (value == null)
this.reference = null;
else {
if (this.reference == null)
this.reference = new StringType();
this.reference.setValue(value);
}
return this;
}
/**
* @return {@link #display} (Plain text narrative that identifies the resource in addition to the resource reference.)
*/
public StringType getDisplay() {
return this.display;
}
/**
* @param value {@link #display} (Plain text narrative that identifies the resource in addition to the resource reference.)
*/
public ResourceReference setDisplay(StringType value) {
this.display = value;
return this;
}
/**
* @return Plain text narrative that identifies the resource in addition to the resource reference.
*/
public String getDisplaySimple() {
return this.display == null ? null : this.display.getValue();
}
/**
* @param value Plain text narrative that identifies the resource in addition to the resource reference.
*/
public ResourceReference setDisplaySimple(String value) {
if (value == null)
this.display = null;
else {
if (this.display == null)
this.display = new StringType();
this.display.setValue(value);
}
return this;
}
protected void listChildren(List<Property> childrenList) {
super.listChildren(childrenList);
childrenList.add(new Property("reference", "string", "A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.", 0, java.lang.Integer.MAX_VALUE, reference));
childrenList.add(new Property("display", "string", "Plain text narrative that identifies the resource in addition to the resource reference.", 0, java.lang.Integer.MAX_VALUE, display));
}
public ResourceReference copy() {
ResourceReference dst = new ResourceReference();
dst.reference = reference == null ? null : reference.copy();
dst.display = display == null ? null : display.copy();
return dst;
}
protected ResourceReference typedCopy() {
return copy();
}
}

View File

@ -32,8 +32,8 @@ package org.hl7.fhir.instance.model;
// Generated on Sun, Dec 7, 2014 21:45-0500 for FHIR v0.3.0 // Generated on Sun, Dec 7, 2014 21:45-0500 for FHIR v0.3.0
import java.util.*; import java.util.*;
import java.math.*; import java.math.*;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
@ -42,7 +42,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* A series of measurements taken by a device, with upper and lower limits. There may be more than one dimension in the data. * A series of measurements taken by a device, with upper and lower limits. There may be more than one dimension in the data.
*/ */
@DatatypeDef(name="SampledData") @DatatypeDef(name="SampledData")
public class SampledData extends Type { public class SampledData extends Type implements ICompositeType{
/** /**
* The base quantity that a measured value of zero represents. In addition, this provides the units of the entire measurement series. * The base quantity that a measured value of zero represents. In addition, this provides the units of the entire measurement series.

View File

@ -32,8 +32,8 @@ package org.hl7.fhir.instance.model;
// Generated on Sun, Dec 7, 2014 21:45-0500 for FHIR v0.3.0 // Generated on Sun, Dec 7, 2014 21:45-0500 for FHIR v0.3.0
import java.util.*; import java.util.*;
import java.math.*; import java.math.*;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
@ -42,7 +42,7 @@ import org.hl7.fhir.instance.model.annotations.DatatypeDef;
* Specifies an event that may occur multiple times. Timing schedules are used for to record when things are expected or requested to occur. * Specifies an event that may occur multiple times. Timing schedules are used for to record when things are expected or requested to occur.
*/ */
@DatatypeDef(name="Timing") @DatatypeDef(name="Timing")
public class Timing extends Type { public class Timing extends Type implements ICompositeType{
public enum EventTiming implements FhirEnum { public enum EventTiming implements FhirEnum {
/** /**