Correctly parse List resource

This commit is contained in:
jamesagnew 2014-08-26 08:10:15 -04:00
parent e6d6ec88b2
commit 9413bfa47b
11 changed files with 238 additions and 152 deletions

View File

@ -107,6 +107,10 @@
Server now gives a more helpful error message if a @Read method has a search parameter (which is invalid, but
previously lead to a very unhelpful error message). Thanks to Tahura Chaudhry of UHN for reporting!
</action>
<action type="fix">
Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health
for reporting!
</action>
</release>
<release version="0.5" date="2014-Jul-30">
<action type="add">

View File

@ -72,12 +72,14 @@ public class FhirContext {
private volatile INarrativeGenerator myNarrativeGenerator;
private volatile IRestfulClientFactory myRestfulClientFactory;
private volatile RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
private Map<String, String> myNameToResourceType;
private static final List<Class<? extends IResource>> EMPTY_LIST = Collections.emptyList();
/**
* Default constructor. In most cases this is the right constructor to use.
*/
public FhirContext() {
super();
this(EMPTY_LIST);
}
public FhirContext(Class<? extends IResource> theResourceType) {
@ -146,8 +148,11 @@ public class FhirContext {
if (retVal == null) {
try {
String candidateName = Patient.class.getPackage().getName() + "." + resourceName;
Class<?> clazz = Class.forName(candidateName);
String className = myNameToResourceType.get(resourceName.toLowerCase());
if (className == null) {
return null;
}
Class<?> clazz = Class.forName(className);
if (IResource.class.isAssignableFrom(clazz)) {
retVal = scanResourceType((Class<? extends IResource>) clazz);
}
@ -298,6 +303,8 @@ public class FhirContext {
myClassToElementDefinition = classToElementDefinition;
myIdToResourceDefinition = idToElementDefinition;
myNameToResourceType = scanner.getNameToResourceType();
return classToElementDefinition;
}

View File

@ -82,6 +82,8 @@ class ModelScanner {
// myNameToDatatypeDefinitions = new HashMap<String,
// RuntimeDatatypeDefinition>();
private Map<String, String> myNameToResourceType = new HashMap<String, String>();
private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
private Set<Class<? extends IElement>> myScanAlso = new HashSet<Class<? extends IElement>>();
@ -106,10 +108,18 @@ class ModelScanner {
return myClassToElementDefinitions;
}
public Map<String, RuntimeResourceDefinition> getIdToResourceDefinition() {
return myIdToResourceDefinition;
}
public Map<String, RuntimeResourceDefinition> getNameToResourceDefinitions() {
return (myNameToResourceDefinitions);
}
public Map<String, String> getNameToResourceType() {
return myNameToResourceType;
}
public RuntimeChildUndeclaredExtensionDefinition getRuntimeChildUndeclaredExtensionDefinition() {
return myRuntimeChildUndeclaredExtensionDefinition;
}
@ -160,9 +170,9 @@ class ModelScanner {
int startSize = myClassToElementDefinitions.size();
long start = System.currentTimeMillis();
InputStream str = ModelScanner.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/model.properties");
InputStream str = ModelScanner.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/fhirversion.properties");
if (str == null) {
str = ModelScanner.class.getResourceAsStream("ca/uhn/fhir/model/dstu/model.properties");
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");
@ -170,7 +180,18 @@ class ModelScanner {
Properties prop = new Properties();
try {
prop.load(str);
for (Object nextValue : prop.values()) {
for (Entry<Object, Object> nextEntry : prop.entrySet()) {
String nextKey = nextEntry.getKey().toString();
String nextValue = nextEntry.getValue().toString();
if (!nextKey.startsWith("datatype.")) {
if (nextKey.startsWith("resource.")) {
String resName = nextKey.substring("resource.".length()).toLowerCase();
myNameToResourceType.put(resName, nextValue);
}
continue;
}
try {
@SuppressWarnings("unchecked")
Class<? extends IElement> nextClass = (Class<? extends IElement>) Class.forName((String) nextValue);
@ -234,8 +255,7 @@ class ModelScanner {
ResourceDef resourceDefinition = theClass.getAnnotation(ResourceDef.class);
if (resourceDefinition != null) {
if (!IResource.class.isAssignableFrom(theClass)) {
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": "
+ theClass.getCanonicalName());
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": " + theClass.getCanonicalName());
}
@SuppressWarnings("unchecked")
Class<? extends IResource> resClass = (Class<? extends IResource>) theClass;
@ -253,8 +273,7 @@ class ModelScanner {
Class<? extends IPrimitiveDatatype<?>> resClass = (Class<? extends IPrimitiveDatatype<?>>) theClass;
scanPrimitiveDatatype(resClass, datatypeDefinition);
} 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());
}
}
@ -265,8 +284,7 @@ class ModelScanner {
Class<? extends IResourceBlock> blockClass = (Class<? extends IResourceBlock>) theClass;
scanBlock(blockClass, blockDefinition);
} else {
throw new ConfigurationException("Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": "
+ theClass.getCanonicalName());
throw new ConfigurationException("Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": " + theClass.getCanonicalName());
}
}
@ -357,8 +375,7 @@ class ModelScanner {
}
@SuppressWarnings("unchecked")
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, Set<String> elementNames, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef,
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToExtensionDef) {
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, Set<String> elementNames, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToExtensionDef) {
int baseElementOrder = theOrderToElementDef.isEmpty() ? 0 : theOrderToElementDef.lastEntry().getKey() + 1;
for (Field next : theClass.getDeclaredFields()) {
@ -395,8 +412,8 @@ class ModelScanner {
}
}
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() + " could be found on type " + next.getDeclaringClass().getSimpleName());
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 " + next.getDeclaringClass().getSimpleName());
}
} else {
@ -411,8 +428,8 @@ class ModelScanner {
}
}
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 name " + elementName + " could be found on type " + next.getDeclaringClass().getSimpleName());
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT + ") but no parent element with name " + elementName + " could be found on type "
+ next.getDeclaringClass().getSimpleName());
}
}
@ -427,7 +444,8 @@ class ModelScanner {
int min = childAnnotation.min();
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 given IDs and can be figured out later
* Anything that's marked as unknown is given a new ID that is <0 so that it doesn't conflict wityh any
* given IDs and can be figured out later
*/
while (order == Child.ORDER_UNKNOWN && orderMap.containsKey(order)) {
order--;
@ -439,8 +457,7 @@ class ModelScanner {
}
if (orderMap.containsKey(order)) {
throw new ConfigurationException("Detected duplicate field order '" + childAnnotation.order() + "' for element named '" + elementName + "' in type '" + theClass.getCanonicalName()
+ "'");
throw new ConfigurationException("Detected duplicate field order '" + childAnnotation.order() + "' for element named '" + elementName + "' in type '" + theClass.getCanonicalName() + "'");
}
if (elementNames.contains(elementName)) {
@ -479,8 +496,7 @@ class ModelScanner {
* Child is an extension
*/
Class<? extends IElement> et = (Class<? extends IElement>) nextElementType;
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName,
extensionAttr.url(), et);
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et);
orderMap.put(order, def);
if (IElement.class.isAssignableFrom(nextElementType)) {
addScanAlso((Class<? extends IElement>) nextElementType);
@ -492,8 +508,7 @@ class ModelScanner {
List<Class<? extends IResource>> refTypesList = new ArrayList<Class<? extends IResource>>();
for (Class<? extends IElement> nextType : childAnnotation.type()) {
if (IResource.class.isAssignableFrom(nextType) == false) {
throw new ConfigurationException("Field '" + next.getName() + "' in class '" + next.getDeclaringClass().getCanonicalName() + "' is of type " + ResourceReferenceDt.class
+ " but contains a non-resource type: " + nextType.getCanonicalName());
throw new ConfigurationException("Field '" + next.getName() + "' in class '" + next.getDeclaringClass().getCanonicalName() + "' is of type " + ResourceReferenceDt.class + " but contains a non-resource type: " + nextType.getCanonicalName());
}
refTypesList.add((Class<? extends IResource>) nextType);
addScanAlso(nextType);
@ -503,7 +518,8 @@ class ModelScanner {
} else if (IResourceBlock.class.isAssignableFrom(nextElementType)) {
/*
* Child is a resource block (i.e. a sub-tag within a resource) TODO: do these have a better name according to HL7?
* Child is a resource block (i.e. a sub-tag within a resource) TODO: do these have a better name
* according to HL7?
*/
Class<? extends IResourceBlock> blockDef = (Class<? extends IResourceBlock>) nextElementType;
@ -542,8 +558,7 @@ class ModelScanner {
CodeableConceptElement concept = next.getAnnotation(CodeableConceptElement.class);
if (concept != null) {
if (!ICodedDatatype.class.isAssignableFrom(nextDatatype)) {
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName()
+ " but type is not a subtype of " + ICodedDatatype.class.getName());
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName() + " but type is not a subtype of " + ICodedDatatype.class.getName());
} else {
Class<? extends ICodeEnum> type = concept.type();
myScanAlsoCodeTable.add(type);
@ -589,8 +604,8 @@ class ModelScanner {
String resourceName = resourceDefinition.name();
if (isBlank(resourceName)) {
Class<?> parent = theClass.getSuperclass();
primaryNameProvider=false;
while (parent.equals(Object.class)==false && isBlank(resourceName)) {
primaryNameProvider = false;
while (parent.equals(Object.class) == false && isBlank(resourceName)) {
ResourceDef nextDef = parent.getAnnotation(ResourceDef.class);
if (nextDef != null) {
resourceName = nextDef.name();
@ -602,19 +617,19 @@ class ModelScanner {
}
}
// if (myNameToResourceDefinitions.containsKey(resourceName)) {
// if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
// // throw new
// // ConfigurationException("Detected duplicate element name '" +
// // resourceName + "' in types '" + theClass.getCanonicalName() +
// // "' and '"
// // +
// // myNameToResourceDefinitions.get(resourceName).getImplementingClass()
// // + "'");
// } else {
// return resourceName;
// }
// }
// if (myNameToResourceDefinitions.containsKey(resourceName)) {
// if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
// // throw new
// // ConfigurationException("Detected duplicate element name '" +
// // resourceName + "' in types '" + theClass.getCanonicalName() +
// // "' and '"
// // +
// // myNameToResourceDefinitions.get(resourceName).getImplementingClass()
// // + "'");
// } else {
// return resourceName;
// }
// }
String resourceId = resourceDefinition.id();
if (isBlank(resourceId)) {
@ -624,8 +639,7 @@ class ModelScanner {
// theClass.getCanonicalName());
} else {
if (myIdToResourceDefinition.containsKey(resourceId)) {
throw new ConfigurationException("The following resource types have the same ID of '" + resourceId + "' - " + theClass.getCanonicalName() + " and "
+ myIdToResourceDefinition.get(resourceId).getImplementingClass().getCanonicalName());
throw new ConfigurationException("The following resource types have the same ID of '" + resourceId + "' - " + theClass.getCanonicalName() + " and " + myIdToResourceDefinition.get(resourceId).getImplementingClass().getCanonicalName());
}
}
@ -672,8 +686,7 @@ class ModelScanner {
for (String nextName : searchParam.compositeOf()) {
RuntimeSearchParam param = nameToParam.get(nextName);
if (param == null) {
ourLog.warn("Search parameter {}.{} declares that it is a composite with compositeOf value '{}' but that is not a valid parametr name itself. Valid values are: {}", new Object[] {
theResourceDef.getName(), searchParam.name(), nextName, nameToParam.keySet() });
ourLog.warn("Search parameter {}.{} declares that it is a composite with compositeOf value '{}' but that is not a valid parametr name itself. Valid values are: {}", new Object[] { theResourceDef.getName(), searchParam.name(), nextName, nameToParam.keySet() });
continue;
}
compositeOf.add(param);
@ -684,10 +697,6 @@ class ModelScanner {
}
}
public Map<String, RuntimeResourceDefinition> getIdToResourceDefinition() {
return myIdToResourceDefinition;
}
private static Class<?> getGenericCollectionTypeOfCodedField(Field next) {
Class<?> type;
ParameterizedType collectionType = (ParameterizedType) next.getGenericType();

View File

@ -285,7 +285,7 @@ public class RestfulServer extends HttpServlet {
ourLog.error("An error occurred while loading request handlers!", ex);
throw new ServletException("Failed to initialize FHIR Restful server", ex);
}
myStarted = true;
ourLog.info("A FHIR has been lit on this server");
}

View File

@ -0,0 +1,95 @@
# This file contains version definitions
resource.AdverseReaction=ca.uhn.fhir.model.dstu.resource.AdverseReaction
resource.Alert=ca.uhn.fhir.model.dstu.resource.Alert
resource.AllergyIntolerance=ca.uhn.fhir.model.dstu.resource.AllergyIntolerance
resource.Appointment=ca.uhn.fhir.model.dstu.resource.Appointment
resource.AppointmentResponse=ca.uhn.fhir.model.dstu.resource.AppointmentResponse
resource.Availability=ca.uhn.fhir.model.dstu.resource.Availability
resource.CarePlan=ca.uhn.fhir.model.dstu.resource.CarePlan
resource.Claim=ca.uhn.fhir.model.dstu.resource.Claim
resource.Composition=ca.uhn.fhir.model.dstu.resource.Composition
resource.ConceptMap=ca.uhn.fhir.model.dstu.resource.ConceptMap
resource.Condition=ca.uhn.fhir.model.dstu.resource.Condition
resource.Conformance=ca.uhn.fhir.model.dstu.resource.Conformance
resource.Coverage=ca.uhn.fhir.model.dstu.resource.Coverage
resource.Device=ca.uhn.fhir.model.dstu.resource.Device
resource.DeviceObservationReport=ca.uhn.fhir.model.dstu.resource.DeviceObservationReport
resource.DiagnosticOrder=ca.uhn.fhir.model.dstu.resource.DiagnosticOrder
resource.DiagnosticReport=ca.uhn.fhir.model.dstu.resource.DiagnosticReport
resource.DocumentManifest=ca.uhn.fhir.model.dstu.resource.DocumentManifest
resource.DocumentReference=ca.uhn.fhir.model.dstu.resource.DocumentReference
resource.Encounter=ca.uhn.fhir.model.dstu.resource.Encounter
resource.FamilyHistory=ca.uhn.fhir.model.dstu.resource.FamilyHistory
resource.GVFMeta=ca.uhn.fhir.model.dstu.resource.GVFMeta
resource.GVFVariant=ca.uhn.fhir.model.dstu.resource.GVFVariant
resource.GeneExpression=ca.uhn.fhir.model.dstu.resource.GeneExpression
resource.GeneticAnalysis=ca.uhn.fhir.model.dstu.resource.GeneticAnalysis
resource.Group=ca.uhn.fhir.model.dstu.resource.Group
resource.ImagingStudy=ca.uhn.fhir.model.dstu.resource.ImagingStudy
resource.Immunization=ca.uhn.fhir.model.dstu.resource.Immunization
resource.ImmunizationRecommendation=ca.uhn.fhir.model.dstu.resource.ImmunizationRecommendation
resource.List=ca.uhn.fhir.model.dstu.resource.ListResource
resource.Location=ca.uhn.fhir.model.dstu.resource.Location
resource.Media=ca.uhn.fhir.model.dstu.resource.Media
resource.Medication=ca.uhn.fhir.model.dstu.resource.Medication
resource.MedicationAdministration=ca.uhn.fhir.model.dstu.resource.MedicationAdministration
resource.MedicationDispense=ca.uhn.fhir.model.dstu.resource.MedicationDispense
resource.MedicationPrescription=ca.uhn.fhir.model.dstu.resource.MedicationPrescription
resource.MedicationStatement=ca.uhn.fhir.model.dstu.resource.MedicationStatement
resource.MessageHeader=ca.uhn.fhir.model.dstu.resource.MessageHeader
resource.Microarray=ca.uhn.fhir.model.dstu.resource.Microarray
resource.Observation=ca.uhn.fhir.model.dstu.resource.Observation
resource.OperationOutcome=ca.uhn.fhir.model.dstu.resource.OperationOutcome
resource.Order=ca.uhn.fhir.model.dstu.resource.Order
resource.OrderResponse=ca.uhn.fhir.model.dstu.resource.OrderResponse
resource.Organization=ca.uhn.fhir.model.dstu.resource.Organization
resource.Other=ca.uhn.fhir.model.dstu.resource.Other
resource.Patient=ca.uhn.fhir.model.dstu.resource.Patient
resource.Practitioner=ca.uhn.fhir.model.dstu.resource.Practitioner
resource.Procedure=ca.uhn.fhir.model.dstu.resource.Procedure
resource.Profile=ca.uhn.fhir.model.dstu.resource.Profile
resource.Provenance=ca.uhn.fhir.model.dstu.resource.Provenance
resource.Query=ca.uhn.fhir.model.dstu.resource.Query
resource.Questionnaire=ca.uhn.fhir.model.dstu.resource.Questionnaire
resource.RelatedPerson=ca.uhn.fhir.model.dstu.resource.RelatedPerson
resource.Remittance=ca.uhn.fhir.model.dstu.resource.Remittance
resource.SecurityEvent=ca.uhn.fhir.model.dstu.resource.SecurityEvent
resource.SequencingAnalysis=ca.uhn.fhir.model.dstu.resource.SequencingAnalysis
resource.SequencingLab=ca.uhn.fhir.model.dstu.resource.SequencingLab
resource.Slot=ca.uhn.fhir.model.dstu.resource.Slot
resource.Specimen=ca.uhn.fhir.model.dstu.resource.Specimen
resource.Substance=ca.uhn.fhir.model.dstu.resource.Substance
resource.Supply=ca.uhn.fhir.model.dstu.resource.Supply
resource.Test=ca.uhn.fhir.model.dstu.resource.Test
resource.User=ca.uhn.fhir.model.dstu.resource.User
resource.ValueSet=ca.uhn.fhir.model.dstu.resource.ValueSet
datatype.Address=ca.uhn.fhir.model.dstu.composite.AddressDt
datatype.Attachment=ca.uhn.fhir.model.dstu.composite.AttachmentDt
datatype.CodeableConcept=ca.uhn.fhir.model.dstu.composite.CodeableConceptDt
datatype.Coding=ca.uhn.fhir.model.dstu.composite.CodingDt
datatype.Contact=ca.uhn.fhir.model.dstu.composite.ContactDt
datatype.HumanName=ca.uhn.fhir.model.dstu.composite.HumanNameDt
datatype.Identifier=ca.uhn.fhir.model.dstu.composite.IdentifierDt
datatype.Period=ca.uhn.fhir.model.dstu.composite.PeriodDt
datatype.Quantity=ca.uhn.fhir.model.dstu.composite.QuantityDt
datatype.Range=ca.uhn.fhir.model.dstu.composite.RangeDt
datatype.Ratio=ca.uhn.fhir.model.dstu.composite.RatioDt
datatype.ResourceReference=ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt
datatype.SampledData=ca.uhn.fhir.model.dstu.composite.SampledDataDt
datatype.Schedule=ca.uhn.fhir.model.dstu.composite.ScheduleDt
datatype.base64Binary=ca.uhn.fhir.model.primitive.Base64BinaryDt
datatype.boolean=ca.uhn.fhir.model.primitive.BooleanDt
datatype.code=ca.uhn.fhir.model.primitive.CodeDt
datatype.date=ca.uhn.fhir.model.primitive.DateDt
datatype.dateTime=ca.uhn.fhir.model.primitive.DateTimeDt
datatype.decimal=ca.uhn.fhir.model.primitive.DecimalDt
datatype.id=ca.uhn.fhir.model.primitive.IdDt
datatype.idref=ca.uhn.fhir.model.primitive.IdrefDt
datatype.instant=ca.uhn.fhir.model.primitive.InstantDt
datatype.integer=ca.uhn.fhir.model.primitive.IntegerDt
datatype.oid=ca.uhn.fhir.model.primitive.OidDt
datatype.string=ca.uhn.fhir.model.primitive.StringDt
datatype.uri=ca.uhn.fhir.model.primitive.UriDt
datatype.xhtml=ca.uhn.fhir.model.primitive.XhtmlDt

View File

@ -72,13 +72,13 @@ public class XmlParserTest {
Binary patient = new Binary();
patient.setContentType("foo");
patient.setContent(new byte[] {1,2,3,4});
patient.setContent(new byte[] { 1, 2, 3, 4 });
String val = ourCtx.newXmlParser().encodeResourceToString(patient);
assertEquals("<Binary xmlns=\"http://hl7.org/fhir\" contentType=\"foo\">AQIDBA==</Binary>", val);
}
@Test
public void testEncodeBoundCode() {
@ -94,13 +94,13 @@ public class XmlParserTest {
@Test
public void testEncodeBundle() throws InterruptedException {
Bundle b= new Bundle();
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
Bundle b = new Bundle();
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
InstantDt pub = InstantDt.withCurrentTime();
b.setPublished(pub);
Thread.sleep(2);
Patient p1 = new Patient();
p1.addName().addFamily("Family1");
BundleEntry entry = b.addEntry();
@ -114,11 +114,11 @@ public class XmlParserTest {
entry.setLinkAlternate(new StringDt("http://foo/bar"));
entry.setLinkSearch(new StringDt("http://foo/bar/search"));
entry.setResource(p2);
BundleEntry deletedEntry = b.addEntry();
deletedEntry.setId(new IdDt("Patient/3"));
deletedEntry.setDeleted(InstantDt.withCurrentTime());
String bundleString = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(bundleString);
@ -126,14 +126,12 @@ public class XmlParserTest {
strings.addAll(Arrays.asList("<published>", pub.getValueAsString(), "</published>"));
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</entry>"));
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>","</entry>"));
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
strings.addAll(Arrays.asList("<at:deleted-entry", "ref=\"Patient/3", "/>"));
assertThat(bundleString, StringContainsInOrder.stringContainsInOrder(strings));
assertThat(bundleString, not(containsString("at:by")));
}
}
@Test
public void testEncodeBundleCategory() {
@ -157,7 +155,7 @@ public class XmlParserTest {
assertNull(b.getEntries().get(0).getResource());
}
@Test
public void testEncodeBundleResultCount() {
@ -171,13 +169,12 @@ public class XmlParserTest {
}
@Test
public void testEncodeContainedAndIncludedResources() {
DiagnosticReport rpt = new DiagnosticReport();
rpt.getName().setText("Report");
Specimen spm = new Specimen();
spm.addIdentifier().setLabel("Report1ContainedSpecimen1");
rpt.addSpecimen().setResource(spm);
@ -186,11 +183,9 @@ public class XmlParserTest {
String str = p.encodeResourceToString(rpt);
ourLog.info(str);
}
@Test
public void testEncodeContainedResources() {
@ -232,8 +227,7 @@ public class XmlParserTest {
assertEquals("line1", ref.getLineFirstRep().getValue());
}
@Test
public void testEncodeDeclaredExtensionWithResourceContent() {
IParser parser = ourCtx.newXmlParser();
@ -294,7 +288,7 @@ public class XmlParserTest {
Patient patient = new Patient();
patient.getText().getDiv().setValueAsString("<div>\n <i> hello <pre>\n LINE1\n LINE2</pre></i>\n\n\n\n</div>");
patient.addName().addFamily("Family").addGiven("Given");
//@formatter:off
String encoded = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(patient);
ourLog.info(encoded);
@ -324,7 +318,7 @@ public class XmlParserTest {
+ " </name>\n"
+ "</Patient>";
//@formatter:on
// Whitespace should be preserved and not reformatted in narrative blocks
assertEquals(expected, encoded);
@ -335,13 +329,12 @@ public class XmlParserTest {
Query q = new Query();
ExtensionDt parameter = q.addParameter();
parameter.setUrl("http://foo").setValue(new StringDt("bar"));
String val = ourCtx.newXmlParser().encodeResourceToString(q);
ourLog.info(val);
assertEquals("<Query xmlns=\"http://hl7.org/fhir\"><parameter url=\"http://foo\"><valueString value=\"bar\"/></parameter></Query>", val);
}
@Test
@ -408,7 +401,6 @@ public class XmlParserTest {
}
@Test
public void testExtensionOnPrimitive() throws Exception {
@ -433,9 +425,6 @@ public class XmlParserTest {
}
@Test
public void testExtensions() throws DataFormatException {
@ -456,7 +445,7 @@ public class XmlParserTest {
assertThat(str, StringContains.containsString("<modifierExtension url=\"http://example.com/dontuse#importantDates\"><valueDateTime value=\"2010-01-02\"/></modifierExtension>"));
assertThat(str, StringContains.containsString("<modifierExtension url=\"http://example.com/dontuse#importantDates\"><valueDateTime value=\"2014-01-26T11:11:11\"/></modifierExtension>"));
assertThat(str, StringContains.containsString("<name><family value=\"Smith\"/></name>"));
}
@Test
@ -541,7 +530,6 @@ public class XmlParserTest {
assertTrue(d.toString(), d.identical());
}
@Test
public void testLoadAndEncodeUndeclaredExtensions() throws ConfigurationException, DataFormatException, SAXException, IOException {
IParser p = ourCtx.newXmlParser();
@ -607,7 +595,7 @@ public class XmlParserTest {
ourLog.info(result);
}
// @Test
@Test
public void testParseFeedWithListResource() throws ConfigurationException, DataFormatException, IOException {
// Use new context here to ensure List isn't already loaded
@ -616,10 +604,11 @@ public class XmlParserTest {
String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/feed-with-list.xml"));
Bundle bundle = p.parseBundle(string);
ListResource res = (ListResource) bundle.toListOfResources().get(2);
ListResource res = (ListResource) bundle.toListOfResources().get(2);
assertEquals("cid:patient@bundle", res.getSubject().getReference().getValue());
}
@Test
public void testLoadPatient() throws ConfigurationException, DataFormatException, IOException {
@ -673,7 +662,6 @@ public class XmlParserTest {
}
@Test
public void testMoreExtensions() throws Exception {
@ -717,8 +705,7 @@ public class XmlParserTest {
assertThat(enc, containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension></extension>"));
assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
}
@Test
public void testNarrativeGeneration() throws DataFormatException {
@ -747,37 +734,36 @@ public class XmlParserTest {
Observation A = new Observation();
A.getName().setText("A");
Observation B = new Observation();
B.getName().setText("B");
A.addRelated().setTarget(new ResourceReferenceDt(B));
Observation C = new Observation();
C.getName().setText("C");
B.addRelated().setTarget(new ResourceReferenceDt(C));
String str = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(A);
ourLog.info(str);
assertThat(str, stringContainsInOrder(Arrays.asList("<text value=\"B\"/>", "<text value=\"C\"/>", "<text value=\"A\"/>")));
assertThat(str, stringContainsInOrder(Arrays.asList("<contained>", "</contained>")));
// Only one (outer) contained block
int idx0 = str.indexOf("<contained>");
int idx1 = str.indexOf("<contained>",idx0+1);
int idx1 = str.indexOf("<contained>", idx0 + 1);
assertNotEquals(-1, idx0);
assertEquals(-1, idx1);
Observation obs = ourCtx.newXmlParser().parseResource(Observation.class, str);
assertEquals("A",obs.getName().getText().getValue());
assertEquals("A", obs.getName().getText().getValue());
Observation obsB = (Observation) obs.getRelatedFirstRep().getTarget().getResource();
assertEquals("B",obsB.getName().getText().getValue());
assertEquals("B", obsB.getName().getText().getValue());
Observation obsC = (Observation) obsB.getRelatedFirstRep().getTarget().getResource();
assertEquals("C",obsC.getName().getText().getValue());
assertEquals("C", obsC.getName().getText().getValue());
}
@Test
@ -785,7 +771,7 @@ public class XmlParserTest {
Binary val = ourCtx.newXmlParser().parseResource(Binary.class, "<Binary xmlns=\"http://hl7.org/fhir\" contentType=\"foo\">AQIDBA==</Binary>");
assertEquals("foo", val.getContentType());
assertArrayEquals(new byte[] {1,2,3,4}, val.getContent());
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, val.getContent());
}
@ -860,7 +846,7 @@ public class XmlParserTest {
assertEquals(1, bundle.getCategories().size());
assertEquals("http://hl7.org/fhir/tag", bundle.getCategories().get(0).getScheme());
assertEquals("FHIR Core Valuesets", bundle.getTitle().getValue());
assertEquals("http://hl7.org/implement/standards/fhir/valuesets.xml", bundle.getLinkSelf().getValue());
assertEquals("2014-02-10T04:11:24.435+00:00", bundle.getUpdated().getValueAsString());
@ -893,7 +879,7 @@ public class XmlParserTest {
resource = (ValueSet) entry.getResource();
assertEquals("256a5231-a2bb-49bd-9fea-f349d428b70d", resource.getId().getIdPart());
assertEquals("12345", resource.getId().getVersionIdPart());
assertEquals("12345", ((IdDt)resource.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION_ID)).getVersionIdPart());
assertEquals("12345", ((IdDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION_ID)).getVersionIdPart());
}
@ -927,17 +913,17 @@ public class XmlParserTest {
assertEquals("http://foo/Patient/1/_history/2", entry.getLinkSelf().getValue());
assertEquals("1", entry.getResource().getId().getIdPart());
assertEquals("2", entry.getResource().getId().getVersionIdPart());
assertEquals("2", ((IdDt)entry.getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION_ID)).getVersionIdPart());
assertEquals("2", ((IdDt) entry.getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION_ID)).getVersionIdPart());
assertEquals("John Doe", entry.getDeletedByName().getValue());
assertEquals("jdoe@example.org", entry.getDeletedByEmail().getValue());
assertEquals("Removed comment spam", entry.getDeletedComment().getValue());
assertEquals(new InstantDt("2013-02-10T04:11:24.435+00:00"), entry.getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.DELETED_AT));
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(bundle));
String encoded = ourCtx.newXmlParser().encodeBundleToString(bundle);
assertEquals(msg,encoded);
assertEquals(msg, encoded);
}
@Test
@ -953,7 +939,7 @@ public class XmlParserTest {
assertEquals("3216379", bundle.getEntries().get(0).getResource().getId().getIdPart());
}
@Test
public void testParseBundleWithMixedReturnTypes() {
InputStreamReader str = new InputStreamReader(getClass().getResourceAsStream("/mixed-return-bundle.xml"));
@ -978,15 +964,14 @@ public class XmlParserTest {
}
@Test
public void testParseEncodeNarrative() {
String input = "<Patient xmlns=\"http://hl7.org/fhir\"><text><status value=\"generated\"/><div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> Donald null <b>DUCK </b></div><table class=\"hapiPropertyTable\"><tbody><tr><td>Identifier</td><td>7000135</td></tr><tr><td>Address</td><td><span>10 Duxon Street </span><br/><span>VICTORIA </span><span>BC </span><span>Can </span></td></tr><tr><td>Date of birth</td><td><span>01 June 1980</span></td></tr></tbody></table></div></text><identifier><use value=\"official\"/><label value=\"University Health Network MRN 7000135\"/><system value=\"urn:oid:2.16.840.1.113883.3.239.18.148\"/><value value=\"7000135\"/><assigner><reference value=\"Organization/1.3.6.1.4.1.12201\"/></assigner></identifier><name><family value=\"Duck\"/><given value=\"Donald\"/></name><telecom><system value=\"phone\"/><use value=\"home\"/></telecom><telecom><system value=\"phone\"/><use value=\"work\"/></telecom><telecom><system value=\"phone\"/><use value=\"mobile\"/></telecom><telecom><system value=\"email\"/><use value=\"home\"/></telecom><gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\"/><code value=\"M\"/></coding></gender><birthDate value=\"1980-06-01T00:00:00\"/><address><use value=\"home\"/><line value=\"10 Duxon Street\"/><city value=\"VICTORIA\"/><state value=\"BC\"/><zip value=\"V8N 1Y4\"/><country value=\"Can\"/></address><managingOrganization><reference value=\"Organization/1.3.6.1.4.1.12201\"/></managingOrganization></Patient>";
IResource res = ourCtx.newXmlParser().parseResource(input);
String output = ourCtx.newXmlParser().encodeResourceToString(res);
// Should occur exactly twice (once for the resource, once for the DIV
assertThat(output, (StringContainsInOrder.stringContainsInOrder(Arrays.asList("Patient xmlns", "div xmlns"))));
assertThat(output, not(StringContainsInOrder.stringContainsInOrder(Arrays.asList("b xmlns"))));
@ -1000,8 +985,7 @@ public class XmlParserTest {
}
/**
* This sample has extra elements in <searchParam> that are not actually a
* part of the spec any more..
* This sample has extra elements in <searchParam> that are not actually a part of the spec any more..
*/
@Test
public void testParseFuroreMetadataWithExtraElements() throws IOException {
@ -1017,33 +1001,23 @@ public class XmlParserTest {
public void testParseLanguage() {
String input = "<Patient xmlns=\"http://hl7.org/fhir\"><language value=\"zh-CN\"/><text><status value=\"generated\"/><div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> 海生 <b>王 </b></div><table class=\"hapiPropertyTable\"><tbody><tr><td>Identifier</td><td>URNo</td></tr><tr><td>Address</td><td><span>99 Houston Road </span><br/><span>BENTLEIGH </span><span>Victoria </span></td></tr><tr><td>Date of birth</td><td><span>01 January 1997</span></td></tr></tbody></table></div></text><identifier><use value=\"usual\"/><label value=\"URNo\"/><value value=\"89532\"/></identifier><name><text value=\"王海生\"/><family value=\"\"/><given value=\"海生\"/></name><telecom><system value=\"phone\"/><value value=\"9899 9878\"/><use value=\"home\"/></telecom><telecom><system value=\"email\"/><value value=\"zimmerman@datacorp.com.au\"/><use value=\"home\"/></telecom><gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\"/><code value=\"M\"/><display value=\"Male\"/></coding><text value=\"Male\"/></gender><birthDate value=\"1997-01-01\"/><address><use value=\"home\"/><text value=\"99 Houston Road, BENTLEIGH, 3204\"/><line value=\"99 Houston Road\"/><city value=\"BENTLEIGH\"/><state value=\"Victoria\"/><zip value=\"3204\"/><period><start value=\"2006-06-16\"/></period></address><active value=\"true\"/></Patient>";
Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, input);
assertEquals("zh-CN", pt.getLanguage().getValue());
}
@Test
public void testParseQuery() {
String msg = "<Query xmlns=\"http://hl7.org/fhir\">\n" +
" <text>\n" +
" <status value=\"generated\"/>\n" +
" <div xmlns=\"http://www.w3.org/1999/xhtml\">[Put rendering here]</div>\n" +
" </text>\n" +
"\n" +
" <!-- this is an extermely simple query - a request to execute the query 'example' on the\n" +
" responder -->\n" +
" <identifier value=\"urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376\"/>\n" +
" <parameter url=\"http://hl7.org/fhir/query#_query\">\n" +
" <valueString value=\"example\"/>\n" +
" </parameter>\n" +
"</Query>";
String msg = "<Query xmlns=\"http://hl7.org/fhir\">\n" + " <text>\n" + " <status value=\"generated\"/>\n" + " <div xmlns=\"http://www.w3.org/1999/xhtml\">[Put rendering here]</div>\n" + " </text>\n" + "\n"
+ " <!-- this is an extermely simple query - a request to execute the query 'example' on the\n" + " responder -->\n" + " <identifier value=\"urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376\"/>\n" + " <parameter url=\"http://hl7.org/fhir/query#_query\">\n"
+ " <valueString value=\"example\"/>\n" + " </parameter>\n" + "</Query>";
Query query = ourCtx.newXmlParser().parseResource(Query.class, msg);
assertEquals("urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376", query.getIdentifier().getValueAsString());
assertEquals("http://hl7.org/fhir/query#_query", query.getParameterFirstRep().getUrlAsString());
assertEquals("example", query.getParameterFirstRep().getValueAsPrimitive().getValueAsString());
}
@Test
public void testParseWithXmlHeader() throws ConfigurationException, DataFormatException {
IParser p = ourCtx.newXmlParser();
@ -1121,7 +1095,7 @@ public class XmlParserTest {
@Test
public void testTagList() {
//@formatter:off
String tagListStr = "<taglist xmlns=\"http://hl7.org/fhir\"> \n" +
" <category term=\"term0\" label=\"label0\" scheme=\"scheme0\" /> \n" +
@ -1129,7 +1103,7 @@ public class XmlParserTest {
" <category term=\"term2\" label=\"label2\" /> \n" +
"</taglist>";
//@formatter:on
TagList tagList = ourCtx.newXmlParser().parseTagList(tagListStr);
assertEquals(3, tagList.size());
assertEquals("term0", tagList.get(0).getTerm());
@ -1141,7 +1115,7 @@ public class XmlParserTest {
assertEquals("term2", tagList.get(2).getTerm());
assertEquals("label2", tagList.get(2).getLabel());
assertEquals(null, tagList.get(2).getScheme());
/*
* Encode
*/
@ -1153,10 +1127,10 @@ public class XmlParserTest {
"<category term=\"term2\" label=\"label2\"/>" +
"</taglist>";
//@formatter:on
String encoded = ourCtx.newXmlParser().encodeTagListToString(tagList);
assertEquals(expected,encoded);
assertEquals(expected, encoded);
}
@Test

View File

@ -12,7 +12,7 @@
<dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.6-SNAPSHOT/hapi-fhir-testpage-overlay-0.6-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependency-type>consumes</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">

View File

@ -130,7 +130,7 @@ public class TinderStructuresMojo extends AbstractMojo {
pp.combineContentMaps(rp);
pp.combineContentMaps(dtp);
pp.writeAll(new File(directoryBase, "resource"), null, packageName);
pp.writeAll(new File(directoryBase, "resource"), resDirectoryBase, packageName);
}
@ -139,7 +139,7 @@ public class TinderStructuresMojo extends AbstractMojo {
dtp.combineContentMaps(pp);
dtp.combineContentMaps(rp);
dtp.writeAll(new File(directoryBase, "composite"), null, packageName);
dtp.writeAll(new File(directoryBase, "composite"), resDirectoryBase, packageName);
}
ourLog.info("Writing ValueSet Enums...");

View File

@ -371,9 +371,9 @@ public abstract class BaseStructureParser {
}
if (next instanceof Resource) {
myNameToResourceClass.put(next.getElementName(), thePackageBase + '.' + elementName);
myNameToResourceClass.put(next.getElementName(), thePackageBase + ".resource." + elementName);
} else if (next instanceof Composite) {
myNameToDatatypeClass.put(next.getElementName(), thePackageBase + '.' + elementName);
myNameToDatatypeClass.put(next.getElementName(), thePackageBase + ".composite." + elementName + "Dt");
} else {
throw new IllegalStateException(next.getClass().toString());
}

View File

@ -9,18 +9,15 @@ import java.util.List;
import org.apache.maven.plugin.MojoFailureException;
import ch.qos.logback.classic.ClassicConstants;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.tinder.model.BaseRootType;
import ca.uhn.fhir.tinder.model.Composite;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.tinder.model.BaseRootType;
import ca.uhn.fhir.tinder.model.Composite;
public class DatatypeGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetParser {
@Override

View File

@ -6,7 +6,7 @@
<dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.6-SNAPSHOT/hapi-fhir-testpage-overlay-0.6-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependency-type>consumes</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">