diff --git a/hapi-fhir-base/src/changes/changes.xml b/hapi-fhir-base/src/changes/changes.xml index f9096de8597..4ce51862bce 100644 --- a/hapi-fhir-base/src/changes/changes.xml +++ b/hapi-fhir-base/src/changes/changes.xml @@ -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! + + Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health + for reporting! + diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java index f36a47f3d02..bcabe19d393 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java @@ -72,12 +72,14 @@ public class FhirContext { private volatile INarrativeGenerator myNarrativeGenerator; private volatile IRestfulClientFactory myRestfulClientFactory; private volatile RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition; + private Map myNameToResourceType; + private static final List> 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 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) clazz); } @@ -298,6 +303,8 @@ public class FhirContext { myClassToElementDefinition = classToElementDefinition; myIdToResourceDefinition = idToElementDefinition; + myNameToResourceType = scanner.getNameToResourceType(); + return classToElementDefinition; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java index 0708b81cd13..bbda02ef310 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java @@ -82,6 +82,8 @@ class ModelScanner { // myNameToDatatypeDefinitions = new HashMap(); + private Map myNameToResourceType = new HashMap(); + private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition; private Set> myScanAlso = new HashSet>(); @@ -106,10 +108,18 @@ class ModelScanner { return myClassToElementDefinitions; } + public Map getIdToResourceDefinition() { + return myIdToResourceDefinition; + } + public Map getNameToResourceDefinitions() { return (myNameToResourceDefinitions); } + public Map 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 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 nextClass = (Class) 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 resClass = (Class) theClass; @@ -253,8 +273,7 @@ class ModelScanner { Class> resClass = (Class>) 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 blockClass = (Class) 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 theClass, Set elementNames, TreeMap theOrderToElementDef, - TreeMap theOrderToExtensionDef) { + private void scanCompositeElementForChildren(Class theClass, Set elementNames, TreeMap theOrderToElementDef, TreeMap 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 et = (Class) 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) nextElementType); @@ -492,8 +508,7 @@ class ModelScanner { List> refTypesList = new ArrayList>(); for (Class 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) 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 blockDef = (Class) 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 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 getIdToResourceDefinition() { - return myIdToResourceDefinition; - } - private static Class getGenericCollectionTypeOfCodedField(Field next) { Class type; ParameterizedType collectionType = (ParameterizedType) next.getGenericType(); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java index e926c150567..58f1563b8f4 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java @@ -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"); } diff --git a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/model/dstu/fhirversion.properties b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/model/dstu/fhirversion.properties new file mode 100644 index 00000000000..32d2399a55e --- /dev/null +++ b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/model/dstu/fhirversion.properties @@ -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 diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java index f0602b6077d..7b5cc24fd23 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java @@ -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("AQIDBA==", 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("", pub.getValueAsString(), "")); strings.add(""); strings.addAll(Arrays.asList("", "1", "")); - strings.addAll(Arrays.asList("", "2", "", "","")); + strings.addAll(Arrays.asList("", "2", "", "", "")); strings.addAll(Arrays.asList("")); 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("
\n hello
\n  LINE1\n  LINE2
\n\n\n\n
"); 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 { + " \n" + ""; //@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("", 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("")); assertThat(str, StringContains.containsString("")); assertThat(str, StringContains.containsString("")); - + } @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("")); assertThat(enc, containsString("")); } - - + @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("", "", ""))); assertThat(str, stringContainsInOrder(Arrays.asList("", ""))); - + // Only one (outer) contained block int idx0 = str.indexOf(""); - int idx1 = str.indexOf("",idx0+1); + int idx1 = str.indexOf("", 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, "AQIDBA=="); 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 = "
Donald null DUCK
Identifier7000135
Address10 Duxon Street
VICTORIA BC Can
Date of birth01 June 1980
"; 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 that are not actually a - * part of the spec any more.. + * This sample has extra elements in 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 = "
海生
IdentifierURNo
Address99 Houston Road
BENTLEIGH Victoria
Date of birth01 January 1997
"; Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, input); - + assertEquals("zh-CN", pt.getLanguage().getValue()); } @Test public void testParseQuery() { - String msg = "\n" + - " \n" + - " \n" + - "
[Put rendering here]
\n" + - "
\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "
"; + String msg = "\n" + " \n" + " \n" + "
[Put rendering here]
\n" + "
\n" + "\n" + + " \n" + " \n" + " \n" + + " \n" + " \n" + "
"; 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 = " \n" + " \n" + @@ -1129,7 +1103,7 @@ public class XmlParserTest { " \n" + ""; //@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 { "" + ""; //@formatter:on - + String encoded = ourCtx.newXmlParser().encodeTagListToString(tagList); - assertEquals(expected,encoded); - + assertEquals(expected, encoded); + } @Test diff --git a/hapi-fhir-jpaserver-uhnfhirtest/.settings/org.eclipse.wst.common.component b/hapi-fhir-jpaserver-uhnfhirtest/.settings/org.eclipse.wst.common.component index c94187882b4..ee477891317 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/.settings/org.eclipse.wst.common.component +++ b/hapi-fhir-jpaserver-uhnfhirtest/.settings/org.eclipse.wst.common.component @@ -12,7 +12,7 @@ uses - + consumes diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderStructuresMojo.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderStructuresMojo.java index 0b21895347c..268a5e884ea 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderStructuresMojo.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderStructuresMojo.java @@ -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..."); diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java index a4114100989..e0ff32e29a0 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java @@ -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()); } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java index dc07512b002..11f9f272c39 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java @@ -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 diff --git a/restful-server-example/.settings/org.eclipse.wst.common.component b/restful-server-example/.settings/org.eclipse.wst.common.component index 263e87f0f0d..e2cd387d6d8 100644 --- a/restful-server-example/.settings/org.eclipse.wst.common.component +++ b/restful-server-example/.settings/org.eclipse.wst.common.component @@ -6,7 +6,7 @@ uses - + consumes