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 8e5cf80464b..b2979fb9d15 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 @@ -76,11 +76,12 @@ public class FhirContext { private volatile Map myIdToResourceDefinition = Collections.emptyMap(); private HapiLocalizer myLocalizer = new HapiLocalizer(); private volatile Map myNameToElementDefinition = Collections.emptyMap(); - private Map myNameToResourceType; + private Map> myNameToResourceType; private volatile INarrativeGenerator myNarrativeGenerator; private volatile IRestfulClientFactory myRestfulClientFactory; private volatile RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition; private final IFhirVersion myVersion; + private Map>> myVersionToNameToResourceType = Collections.emptyMap(); /** * Default constructor. In most cases this is the right constructor to use. @@ -124,16 +125,8 @@ public class FhirContext { scanResourceTypes(toElementList(theResourceTypes)); } - @SuppressWarnings("unchecked") - private List> toElementList(Collection> theResourceTypes) { - if (theResourceTypes == null) { - return null; - } - List> resTypes = new ArrayList>(); - for (Class next : theResourceTypes) { - resTypes.add((Class) next); - } - return resTypes; + private String createUnknownResourceNameError(String theResourceName, FhirVersionEnum theVersion) { + return getLocalizer().getMessage(FhirContext.class, "unknownResourceName", theResourceName, theVersion); } /** @@ -189,6 +182,32 @@ public class FhirContext { return retVal; } + public RuntimeResourceDefinition getResourceDefinition(FhirVersionEnum theVersion, String theResourceName) { + Validate.notNull(theVersion, "theVersion can not be null"); + + if (theVersion.equals(myVersion.getVersion())) { + return getResourceDefinition(theResourceName); + } + + Map> nameToType = myVersionToNameToResourceType.get(theVersion); + if (nameToType == null) { + nameToType = new HashMap>(); + ModelScanner.scanVersionPropertyFile(null, nameToType, theVersion); + + Map>> newVersionToNameToResourceType = new HashMap>>(); + newVersionToNameToResourceType.putAll(myVersionToNameToResourceType); + newVersionToNameToResourceType.put(theVersion, nameToType); + myVersionToNameToResourceType = newVersionToNameToResourceType; + } + + Class resourceType = nameToType.get(theResourceName.toLowerCase()); + if (resourceType==null) { + throw new DataFormatException(createUnknownResourceNameError(theResourceName, theVersion)); + } + + return getResourceDefinition(resourceType); + } + /** * Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed * for extending the core library. @@ -218,23 +237,12 @@ public class FhirContext { RuntimeResourceDefinition retVal = myNameToElementDefinition.get(resourceName); if (retVal == null) { - try { - String className = myNameToResourceType.get(resourceName.toLowerCase()); - if (className == null) { - // Binary is added to the fhirversion.properties file now so it's not a special case here -// if ("binary".equals(resourceName.toLowerCase())) { -// // Binary is not generated so it's not in the list of potential resources -// className = Binary.class.getName(); -// } else { - throw new DataFormatException("Unknown resource name[" + resourceName + "]"); -// } - } - Class clazz = Class.forName(className); - if (IResource.class.isAssignableFrom(clazz)) { - retVal = scanResourceType((Class) clazz); - } - } catch (ClassNotFoundException e) { - throw new DataFormatException("Unknown resource name[" + resourceName + "]"); + Class clazz = myNameToResourceType.get(resourceName.toLowerCase()); + if (clazz == null) { + throw new DataFormatException(createUnknownResourceNameError(resourceName, myVersion.getVersion())); + } + if (IResource.class.isAssignableFrom(clazz)) { + retVal = scanResourceType((Class) clazz); } } @@ -358,13 +366,6 @@ public class FhirContext { return new XmlParser(this); } - private RuntimeResourceDefinition scanResourceType(Class theResourceType) { - ArrayList> resourceTypes = new ArrayList>(); - resourceTypes.add(theResourceType); - Map, BaseRuntimeElementDefinition> defs = scanResourceTypes(resourceTypes); - return (RuntimeResourceDefinition) defs.get(theResourceType); - } - private BaseRuntimeElementDefinition scanDatatype(Class theResourceType) { ArrayList> resourceTypes = new ArrayList>(); resourceTypes.add(theResourceType); @@ -372,8 +373,15 @@ public class FhirContext { return defs.get(theResourceType); } + private RuntimeResourceDefinition scanResourceType(Class theResourceType) { + ArrayList> resourceTypes = new ArrayList>(); + resourceTypes.add(theResourceType); + Map, BaseRuntimeElementDefinition> defs = scanResourceTypes(resourceTypes); + return (RuntimeResourceDefinition) defs.get(theResourceType); + } + private Map, BaseRuntimeElementDefinition> scanResourceTypes(Collection> theResourceTypes) { - ModelScanner scanner = new ModelScanner(this, myClassToElementDefinition, theResourceTypes); + ModelScanner scanner = new ModelScanner(this, myVersion.getVersion(), myClassToElementDefinition, theResourceTypes); if (myRuntimeChildUndeclaredExtensionDefinition == null) { myRuntimeChildUndeclaredExtensionDefinition = scanner.getRuntimeChildUndeclaredExtensionDefinition(); } @@ -414,6 +422,39 @@ public class FhirContext { myNarrativeGenerator = theNarrativeGenerator; } + @SuppressWarnings("unchecked") + private List> toElementList(Collection> theResourceTypes) { + if (theResourceTypes == null) { + return null; + } + List> resTypes = new ArrayList>(); + for (Class next : theResourceTypes) { + resTypes.add((Class) next); + } + return resTypes; + } + + /** + * Creates and returns a new FhirContext with version {@link FhirVersionEnum#DEV} + */ + public static FhirContext forDev() { + return new FhirContext(FhirVersionEnum.DEV); + } + + /** + * Creates and returns a new FhirContext with version {@link FhirVersionEnum#DSTU1} + */ + public static FhirContext forDstu1() { + return new FhirContext(FhirVersionEnum.DSTU1); + } + + /** + * Creates and returns a new FhirContext with version {@link FhirVersionEnum#DSTU2} + */ + public static FhirContext forDstu2() { + return new FhirContext(FhirVersionEnum.DSTU2); + } + private static Collection> toCollection(Class theResourceType) { ArrayList> retVal = new ArrayList>(1); retVal.add(theResourceType); @@ -432,25 +473,4 @@ public class FhirContext { return retVal; } - /** - * Creates and returns a new FhirContext with version {@link FhirVersionEnum#DSTU1} - */ - public static FhirContext forDstu1() { - return new FhirContext(FhirVersionEnum.DSTU1); - } - - /** - * Creates and returns a new FhirContext with version {@link FhirVersionEnum#DEV} - */ - public static FhirContext forDev() { - return new FhirContext(FhirVersionEnum.DEV); - } - - /** - * Creates and returns a new FhirContext with version {@link FhirVersionEnum#DSTU2} - */ - public static FhirContext forDstu2() { - return new FhirContext(FhirVersionEnum.DSTU2); - } - } 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 34ed4720993..ae4aa404b18 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 @@ -88,37 +88,18 @@ class ModelScanner { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class); private Map, BaseRuntimeElementDefinition> myClassToElementDefinitions = new HashMap, BaseRuntimeElementDefinition>(); + private FhirContext myContext; private Map myIdToResourceDefinition = new HashMap(); private Map myNameToResourceDefinitions = new HashMap(); - - // private Map - // myNameToDatatypeDefinitions = new HashMap(); - - private Map myNameToResourceType = new HashMap(); - + private Map> myNameToResourceType = new HashMap>(); private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition; - private Set> myScanAlso = new HashSet>(); - private Set> myScanAlsoCodeTable = new HashSet>(); + private FhirVersionEnum myVersion; - private FhirContext myContext; - - ModelScanner(FhirContext theContext, Class theResourceTypes) throws ConfigurationException { - myContext = theContext; - Set> singleton = new HashSet>(); - singleton.add(theResourceTypes); - init(null, singleton); - } - - ModelScanner(FhirContext theContext, Collection> theResourceTypes) throws ConfigurationException { - myContext = theContext; - init(null, new HashSet>(theResourceTypes)); - } - - ModelScanner(FhirContext theContext, Map, BaseRuntimeElementDefinition> theExistingDefinitions, Collection> theResourceTypes) throws ConfigurationException { + ModelScanner(FhirContext theContext, FhirVersionEnum theVersion, Map, BaseRuntimeElementDefinition> theExistingDefinitions, Collection> theResourceTypes) throws ConfigurationException { myContext = theContext; + myVersion = theVersion; Set> toScan; if (theResourceTypes != null) { toScan = new HashSet>(theResourceTypes); @@ -128,26 +109,6 @@ class ModelScanner { init(theExistingDefinitions, toScan); } - public Map, BaseRuntimeElementDefinition> getClassToElementDefinitions() { - return myClassToElementDefinitions; - } - - public Map getIdToResourceDefinition() { - return myIdToResourceDefinition; - } - - public Map getNameToResourceDefinitions() { - return (myNameToResourceDefinitions); - } - - public Map getNameToResourceType() { - return myNameToResourceType; - } - - public RuntimeChildUndeclaredExtensionDefinition getRuntimeChildUndeclaredExtensionDefinition() { - return myRuntimeChildUndeclaredExtensionDefinition; - } - private void addScanAlso(Class theType) { if (theType.isInterface()) { return; @@ -186,46 +147,36 @@ class ModelScanner { } } - private void init(Map, BaseRuntimeElementDefinition> theExistingDefinitions, Set> toScan) { + public Map, BaseRuntimeElementDefinition> getClassToElementDefinitions() { + return myClassToElementDefinitions; + } + + public Map getIdToResourceDefinition() { + return myIdToResourceDefinition; + } + + public Map getNameToResourceDefinitions() { + return (myNameToResourceDefinitions); + } + + public Map> getNameToResourceType() { + return myNameToResourceType; + } + + public RuntimeChildUndeclaredExtensionDefinition getRuntimeChildUndeclaredExtensionDefinition() { + return myRuntimeChildUndeclaredExtensionDefinition; + } + + private void init(Map, BaseRuntimeElementDefinition> theExistingDefinitions, Set> theDatatypes) { if (theExistingDefinitions != null) { myClassToElementDefinitions.putAll(theExistingDefinitions); } int startSize = myClassToElementDefinitions.size(); long start = System.currentTimeMillis(); + Map> resourceTypes = myNameToResourceType; - InputStream str = myContext.getVersion().getFhirVersionPropertiesFile(); - Properties prop = new Properties(); - try { - prop.load(str); - 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); - if (!IElement.class.isAssignableFrom(nextClass)) { - ourLog.warn("Class is not assignable from " + IElement.class.getSimpleName() + ": " + nextValue); - continue; - } - - toScan.add(nextClass); - } catch (ClassNotFoundException e) { - ourLog.warn("Unknown class exception: " + nextValue, e); - } - } - } catch (IOException e) { - throw new ConfigurationException("Failed to load model property file from classpath: " + "/ca/uhn/fhir/model/dstu/model.properties"); - } + scanVersionPropertyFile(theDatatypes, resourceTypes, myVersion); // toScan.add(DateDt.class); // toScan.add(CodeDt.class); @@ -235,7 +186,7 @@ class ModelScanner { // toScan.add(QuantityDt.class); do { - for (Class nextClass : toScan) { + for (Class nextClass : theDatatypes) { scan(nextClass); } for (Iterator> iter = myScanAlso.iterator(); iter.hasNext();) { @@ -243,10 +194,10 @@ class ModelScanner { iter.remove(); } } - toScan.clear(); - toScan.addAll(myScanAlso); + theDatatypes.clear(); + theDatatypes.addAll(myScanAlso); myScanAlso.clear(); - } while (!toScan.isEmpty()); + } while (!theDatatypes.isEmpty()); for (Entry, BaseRuntimeElementDefinition> nextEntry : myClassToElementDefinitions.entrySet()) { if (theExistingDefinitions != null && theExistingDefinitions.containsKey(nextEntry.getKey())) { @@ -264,6 +215,47 @@ class ModelScanner { ourLog.info("Done scanning FHIR library, found {} model entries in {}ms", size, time); } + /** + * There are two implementations of all of the annotations (e.g. {@link Child} and + * {@link org.hl7.fhir.instance.model.annotations.Child}) since the HL7.org ones will eventually replace the HAPI + * ones. Annotations can't extend each other or implement interfaces or anything like that, so rather than duplicate + * all of the annotation processing code this method just creates an interface Proxy to simulate the HAPI + * annotations if the HL7.org ones are found instead. + */ + @SuppressWarnings("unchecked") + private T pullAnnotation(AnnotatedElement theTarget, Class theAnnotationType) { + T retVal = theTarget.getAnnotation(theAnnotationType); + if (retVal == null) { + String sourceClassName = theAnnotationType.getName(); + String candidateAltClassName = sourceClassName.replace("ca.uhn.fhir.model.api.annotation", "org.hl7.fhir.instance.model.annotations"); + + if (!sourceClassName.equals(candidateAltClassName)) { + try { + final Class altAnnotationClass = (Class) Class.forName(candidateAltClassName); + final Annotation altAnnotation = theTarget.getAnnotation(altAnnotationClass); + if (altAnnotation == null) { + return null; + } + + ourLog.debug("Forwarding annotation request for [{}] to class [{}]", sourceClassName, candidateAltClassName); + + InvocationHandler h = new InvocationHandler() { + @Override + public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable { + Method altMethod = altAnnotationClass.getMethod(theMethod.getName(), theMethod.getParameterTypes()); + return altMethod.invoke(altAnnotation, theArgs); + } + }; + retVal = (T) Proxy.newProxyInstance(theAnnotationType.getClassLoader(), new Class[] { theAnnotationType }, h); + + } catch (ClassNotFoundException e) { + return null; + } + } + } + return retVal; + } + private void scan(Class theClass) throws ConfigurationException { BaseRuntimeElementDefinition existingDef = myClassToElementDefinitions.get(theClass); if (existingDef != null) { @@ -300,7 +292,7 @@ class ModelScanner { if (IResourceBlock.class.isAssignableFrom(theClass)) { @SuppressWarnings("unchecked") Class blockClass = (Class) theClass; - scanBlock(blockClass, blockDefinition); + scanBlock(blockClass); } else { throw new ConfigurationException("Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": " + theClass.getCanonicalName()); } @@ -311,7 +303,7 @@ class ModelScanner { } } - private void scanBlock(Class theClass, Block theBlockDefinition) { + private void scanBlock(Class theClass) { ourLog.debug("Scanning resource block class: {}", theClass.getName()); String resourceName = theClass.getCanonicalName(); @@ -464,8 +456,8 @@ class ModelScanner { if (order != Child.ORDER_UNKNOWN) { order = order + baseElementOrder; } - int min = childAnnotation.min(); - int max = childAnnotation.max(); +// 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 with any given @@ -603,47 +595,6 @@ class ModelScanner { } } - /** - * There are two implementations of all of the annotations (e.g. {@link Child} and - * {@link org.hl7.fhir.instance.model.annotations.Child}) since the HL7.org ones will eventually replace the HAPI - * ones. Annotations can't extend each other or implement interfaces or anything like that, so rather than duplicate - * all of the annotation processing code this method just creates an interface Proxy to simulate the HAPI - * annotations if the HL7.org ones are found instead. - */ - @SuppressWarnings("unchecked") - private T pullAnnotation(AnnotatedElement theTarget, Class theAnnotationType) { - T retVal = theTarget.getAnnotation(theAnnotationType); - if (retVal == null) { - String sourceClassName = theAnnotationType.getName(); - String candidateAltClassName = sourceClassName.replace("ca.uhn.fhir.model.api.annotation", "org.hl7.fhir.instance.model.annotations"); - - if (!sourceClassName.equals(candidateAltClassName)) { - try { - final Class altAnnotationClass = (Class) Class.forName(candidateAltClassName); - final Annotation altAnnotation = theTarget.getAnnotation(altAnnotationClass); - if (altAnnotation == null) { - return null; - } - - ourLog.debug("Forwarding annotation request for [{}] to class [{}]", sourceClassName, candidateAltClassName); - - InvocationHandler h = new InvocationHandler() { - @Override - public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable { - Method altMethod = altAnnotationClass.getMethod(theMethod.getName(), theMethod.getParameterTypes()); - return altMethod.invoke(altAnnotation, theArgs); - } - }; - retVal = (T) Proxy.newProxyInstance(theAnnotationType.getClassLoader(), new Class[] { theAnnotationType }, h); - - } catch (ClassNotFoundException e) { - return null; - } - } - } - return retVal; - } - private String scanPrimitiveDatatype(Class> theClass, DatatypeDef theDatatypeDefinition) { ourLog.debug("Scanning resource class: {}", theClass.getName()); @@ -685,27 +636,8 @@ 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; - // } - // } - String resourceId = resourceDefinition.id(); - if (isBlank(resourceId)) { - // throw new ConfigurationException("Resource type @" + - // ResourceDef.class.getSimpleName() + - // " annotation contains no resource ID: " + - // theClass.getCanonicalName()); - } else { + if (!isBlank(resourceId)) { 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()); } @@ -714,7 +646,7 @@ class ModelScanner { RuntimeResourceDefinition resourceDef = new RuntimeResourceDefinition(myContext, resourceName, theClass, resourceDefinition); myClassToElementDefinitions.put(theClass, resourceDef); if (primaryNameProvider) { - if (resourceDef.getStructureVersion() == myContext.getVersion().getVersion()) { + if (resourceDef.getStructureVersion() == myVersion) { myNameToResourceDefinitions.put(resourceName, resourceDef); } } @@ -781,4 +713,53 @@ class ModelScanner { return type; } + static void scanVersionPropertyFile(Set> theDatatypes, Map> theResourceTypes, FhirVersionEnum version) { + InputStream str = version.getVersionImplementation().getFhirVersionPropertiesFile(); + Properties prop = new Properties(); + try { + prop.load(str); + for (Entry nextEntry : prop.entrySet()) { + String nextKey = nextEntry.getKey().toString(); + String nextValue = nextEntry.getValue().toString(); + + if (nextKey.startsWith("datatype.")) { + if (theDatatypes != null) { + try { + // Datatypes + @SuppressWarnings("unchecked") + Class nextClass = (Class) Class.forName(nextValue); + if (!IElement.class.isAssignableFrom(nextClass)) { + ourLog.warn("Class is not assignable from " + IElement.class.getSimpleName() + ": " + nextValue); + continue; + } + + theDatatypes.add(nextClass); + } catch (ClassNotFoundException e) { + ourLog.error("Unknown class[" + nextValue+ "] for data type definition: " + nextKey.substring("datatype.".length()), e); + } + } + } else if (nextKey.startsWith("resource.")) { + // Resources + String resName = nextKey.substring("resource.".length()).toLowerCase(); + try { + @SuppressWarnings("unchecked") + Class nextClass = (Class) Class.forName(nextValue); + if (!IBaseResource.class.isAssignableFrom(nextClass)) { + ourLog.warn("Class is not assignable from " + IBaseResource.class.getSimpleName() + ": " + nextValue); + continue; + } + + theResourceTypes.put(resName, nextClass); + } catch (ClassNotFoundException e) { + ourLog.error("Unknown class[" + nextValue+ "] for resource definition: " + nextKey.substring("resource.".length()), e); + } + } else { + ourLog.warn("Unexpected property in version property file: {}={}", nextKey, nextValue); + } + } + } catch (IOException e) { + throw new ConfigurationException("Failed to load model property file from classpath: " + "/ca/uhn/fhir/model/dstu/model.properties"); + } + } + } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java index 8525d23ac9b..672547c453f 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java @@ -20,7 +20,7 @@ package ca.uhn.fhir.parser; * #L% */ -import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.apache.commons.lang3.StringUtils.*; import java.io.IOException; import java.io.Reader; @@ -64,28 +64,6 @@ public abstract class BaseParser implements IParser { myContext = theContext; } - protected String fixContainedResourceId(String theValue) { - if (StringUtils.isNotBlank(theValue) && theValue.charAt(0) == '#') { - return theValue.substring(1); - } - return theValue; - } - - protected String determineResourceBaseUrl(String bundleBaseUrl, BundleEntry theEntry) { - IResource resource = theEntry.getResource(); - if (resource == null) { - return null; - } - - String resourceBaseUrl = null; - if (resource.getId() != null && resource.getId().hasBaseUrl()) { - if (!resource.getId().getBaseUrl().equals(bundleBaseUrl)) { - resourceBaseUrl = resource.getId().getBaseUrl(); - } - } - return resourceBaseUrl; - } - private void containResourcesForEncoding(ContainedResources theContained, IBaseResource theResource, IBaseResource theTarget) { Set allIds = new HashSet(); @@ -175,6 +153,40 @@ public abstract class BaseParser implements IParser { myContainedResources = contained; } + protected String determineReferenceText(BaseResourceReferenceDt theRef) { + String reference = theRef.getReference().getValue(); + if (isBlank(reference)) { + if (theRef.getResource() != null) { + IdDt containedId = getContainedResources().getResourceId(theRef.getResource()); + if (containedId != null && !containedId.isEmpty()) { + if (containedId.isLocal()) { + reference = containedId.getValue(); + } else { + reference = "#" + containedId.getValue(); + } + } else if (theRef.getResource().getId() != null && theRef.getResource().getId().hasIdPart()) { + reference = theRef.getResource().getId().getValue(); + } + } + } + return reference; + } + + protected String determineResourceBaseUrl(String bundleBaseUrl, BundleEntry theEntry) { + IResource resource = theEntry.getResource(); + if (resource == null) { + return null; + } + + String resourceBaseUrl = null; + if (resource.getId() != null && resource.getId().hasBaseUrl()) { + if (!resource.getId().getBaseUrl().equals(bundleBaseUrl)) { + resourceBaseUrl = resource.getId().getBaseUrl(); + } + } + return resourceBaseUrl; + } + @Override public String encodeBundleToString(Bundle theBundle) throws DataFormatException { if (theBundle == null) { @@ -212,6 +224,13 @@ public abstract class BaseParser implements IParser { return stringWriter.toString(); } + protected String fixContainedResourceId(String theValue) { + if (StringUtils.isNotBlank(theValue) && theValue.charAt(0) == '#') { + return theValue.substring(1); + } + return theValue; + } + ContainedResources getContainedResources() { return myContainedResources; } @@ -279,30 +298,11 @@ public abstract class BaseParser implements IParser { throw new DataFormatException(nextChild + " has no child of type " + theType); } - protected String determineReferenceText(BaseResourceReferenceDt theRef) { - String reference = theRef.getReference().getValue(); - if (isBlank(reference)) { - if (theRef.getResource() != null) { - IdDt containedId = getContainedResources().getResourceId(theRef.getResource()); - if (containedId != null && !containedId.isEmpty()) { - if (containedId.isLocal()) { - reference = containedId.getValue(); - } else { - reference = "#" + containedId.getValue(); - } - } else if (theRef.getResource().getId() != null && theRef.getResource().getId().hasIdPart()) { - reference = theRef.getResource().getId().getValue(); - } - } - } - return reference; - } - static class ContainedResources { private long myNextContainedId = 1; - private IdentityHashMap myResourceToId = new IdentityHashMap(); private List myResources = new ArrayList(); + private IdentityHashMap myResourceToId = new IdentityHashMap(); public void addContained(IBaseResource theResource) { if (myResourceToId.containsKey(theResource)) { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java index f16e0f370cd..8c19fa4b702 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java @@ -1104,7 +1104,7 @@ public class JsonParser extends BaseParser implements IParser { def = myContext.getResourceDefinition(resourceType); } - ParserState state = (ParserState) ParserState.getPreResourceInstance(def.getImplementingClass(), myContext, true); + ParserState state = ParserState.getPreResourceInstance(def.getImplementingClass(), myContext, true); state.enteringNewElement(null, def.getName()); parseChildren(object, state); @@ -1117,11 +1117,6 @@ public class JsonParser extends BaseParser implements IParser { return retVal; } - @Override - public T parseResource(Class theResourceType, String theMessageString) { - return parseResource(theResourceType, new StringReader(theMessageString)); - } - @Override public TagList parseTagList(Reader theReader) { JsonReader reader = Json.createReader(theReader); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java index fa89883b4d2..d9edc336c9b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java @@ -121,6 +121,34 @@ class ParserState { return myState.isPreResource(); } + private BaseContainedDt newContainedDt(IResource theTarget) { + + BaseContainedDt newChildInstance; + try { + newChildInstance = theTarget.getStructureFhirVersionEnum().getVersionImplementation().getContainedType().newInstance(); + } catch (InstantiationException e) { + throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); + } catch (IllegalAccessException e) { + throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); + } + return newChildInstance; + } + + private BaseResourceReferenceDt newResourceReferenceDt(IBase theFirstTarget, IResource theTarget) { + + BaseResourceReferenceDt newChildInstance; + try { + // if (theFirstTarget instanceof IResource) + IFhirVersion version = theTarget.getStructureFhirVersionEnum().getVersionImplementation(); + newChildInstance = version.getResourceReferenceType().newInstance(); + } catch (InstantiationException e) { + throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); + } catch (IllegalAccessException e) { + throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); + } + return newChildInstance; + } + private void pop() { myState = myState.myStack; myState.wereBack(); @@ -237,10 +265,10 @@ class ParserState { private static final int STATE_TERM = 1; private int myCatState = STATE_NONE; - private TagList myTagList; - private String myTerm; private String myLabel; private String myScheme; + private TagList myTagList; + private String myTerm; public AtomCategoryState(TagList theTagList) { super(null); @@ -932,6 +960,33 @@ class ParserState { } + public class BundleEntrySearchState extends BaseState { + + private BundleEntry myEntry; + + public BundleEntrySearchState(BundleEntry theEntry) { + super(null); + myEntry = theEntry; + } + + @Override + public void endingElement() throws DataFormatException { + pop(); + } + + @Override + public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { + if ("mode".equals(theLocalPart)) { + push(new PrimitiveState(getPreResourceState(), myEntry.getSearchMode())); + } else if ("score".equals(theLocalPart)) { + push(new PrimitiveState(getPreResourceState(), myEntry.getScore())); + } else { + throw new DataFormatException("Unexpected element in Bundle.entry.search: " + theLocalPart); + } + } + + } + public class BundleEntryState extends BaseState { private BundleEntry myEntry; @@ -1030,34 +1085,6 @@ class ParserState { } - - public class BundleEntrySearchState extends BaseState { - - private BundleEntry myEntry; - - public BundleEntrySearchState(BundleEntry theEntry) { - super(null); - myEntry = theEntry; - } - - @Override - public void endingElement() throws DataFormatException { - pop(); - } - - @Override - public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { - if ("mode".equals(theLocalPart)) { - push(new PrimitiveState(getPreResourceState(), myEntry.getSearchMode())); - } else if ("score".equals(theLocalPart)) { - push(new PrimitiveState(getPreResourceState(), myEntry.getScore())); - } else { - throw new DataFormatException("Unexpected element in Bundle.entry.search: " + theLocalPart); - } - } - - } - public class BundleEntryTransactionState extends BaseState { private BundleEntry myEntry; @@ -1084,15 +1111,15 @@ class ParserState { } } - + private class BundleLinkState extends BaseState { private BundleEntry myEntry; private String myHref; - private Bundle myInstance; - private String myRel; private boolean myInRelation = false; + private Bundle myInstance; private boolean myInUrl = false; + private String myRel; public BundleLinkState(Bundle theInstance) { super(null); @@ -1178,34 +1205,6 @@ class ParserState { pop(); } - @Override - public void wereBack() { - for (BundleEntry nextEntry : myInstance.getEntries()) { - IResource nextResource = nextEntry.getResource(); - - String bundleBaseUrl = myInstance.getLinkBase().getValue(); - String entryBaseUrl = nextEntry.getLinkBase().getValue(); - String version = ResourceMetadataKeyEnum.VERSION.get(nextResource); - String resourceName = myContext.getResourceDefinition(nextResource).getName(); - String bundleIdPart = nextResource.getId().getIdPart(); - if (isNotBlank(bundleIdPart)) { - if (isNotBlank(entryBaseUrl)) { - nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version)); - } else { - nextResource.setId(new IdDt(bundleBaseUrl, resourceName, bundleIdPart, version)); - } - } - } - - String bundleVersion = (String) myInstance.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION); - String baseUrl = myInstance.getLinkBase().getValue(); - String id = myInstance.getId().getIdPart(); - if (isNotBlank(id)) { - myInstance.setId(new IdDt(baseUrl, "Bundle", id, bundleVersion)); - } - - } - @Override public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { if ("id".equals(theLocalPart)) { @@ -1264,12 +1263,40 @@ class ParserState { return myInstance; } + @Override + public void wereBack() { + for (BundleEntry nextEntry : myInstance.getEntries()) { + IResource nextResource = nextEntry.getResource(); + + String bundleBaseUrl = myInstance.getLinkBase().getValue(); + String entryBaseUrl = nextEntry.getLinkBase().getValue(); + String version = ResourceMetadataKeyEnum.VERSION.get(nextResource); + String resourceName = myContext.getResourceDefinition(nextResource).getName(); + String bundleIdPart = nextResource.getId().getIdPart(); + if (isNotBlank(bundleIdPart)) { + if (isNotBlank(entryBaseUrl)) { + nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version)); + } else { + nextResource.setId(new IdDt(bundleBaseUrl, resourceName, bundleIdPart, version)); + } + } + } + + String bundleVersion = (String) myInstance.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION); + String baseUrl = myInstance.getLinkBase().getValue(); + String id = myInstance.getId().getIdPart(); + if (isNotBlank(id)) { + myInstance.setId(new IdDt(baseUrl, "Bundle", id, bundleVersion)); + } + + } + } private class ContainedResourcesState extends PreResourceState { public ContainedResourcesState(PreResourceState thePreResourcesState) { - super(thePreResourcesState); + super(thePreResourcesState, thePreResourcesState.myInstance.getStructureFhirVersionEnum()); } @Override @@ -1290,11 +1317,11 @@ class ParserState { } } IResource preResCurrentElement = (IResource) getPreResourceState().getCurrentElement(); - + @SuppressWarnings("unchecked") List containedResources = (List) preResCurrentElement.getContained().getContainedResources(); containedResources.add(res); - + } } @@ -1359,7 +1386,6 @@ class ParserState { } } - @Override public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr); @@ -1382,35 +1408,7 @@ class ParserState { } - private BaseResourceReferenceDt newResourceReferenceDt(IBase theFirstTarget, IResource theTarget) { - - BaseResourceReferenceDt newChildInstance; - try { -// if (theFirstTarget instanceof IResource) - IFhirVersion version = theTarget.getStructureFhirVersionEnum().getVersionImplementation(); - newChildInstance = version.getResourceReferenceType().newInstance(); - } catch (InstantiationException e) { - throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); - } catch (IllegalAccessException e) { - throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); - } - return newChildInstance; - } - - private BaseContainedDt newContainedDt(IResource theTarget) { - - BaseContainedDt newChildInstance; - try { - newChildInstance = theTarget.getStructureFhirVersionEnum().getVersionImplementation().getContainedType().newInstance(); - } catch (InstantiationException e) { - throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); - } catch (IllegalAccessException e) { - throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e); - } - return newChildInstance; - } - -private class ElementCompositeState extends BaseState { + private class ElementCompositeState extends BaseState { private BaseRuntimeElementCompositeDefinition myDefinition; private T2 myInstance; @@ -1578,7 +1576,7 @@ private class ElementCompositeState extends BaseState { BaseRuntimeElementCompositeDefinition compositeTarget = (BaseRuntimeElementCompositeDefinition) target; ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance(); myExtension.setValue(newChildInstance); - ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance); + ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance); push(newState); return; } @@ -1716,33 +1714,12 @@ private class ElementCompositeState extends BaseState { } - private class ResourceState extends ElementCompositeState - { - - public ResourceState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition theDef, IResource theInstance) { - super(thePreResourceState, theDef, theInstance); - } - - @Override - public void enteringNewElement(String theNamespace, String theChildName) throws DataFormatException { - if ("id".equals(theChildName)) { - push(new PrimitiveState(getPreResourceState(), getCurrentElement().getId())); - } else if ("meta".equals(theChildName)) { - push(new MetaElementState(getPreResourceState(), getCurrentElement().getResourceMetadata())); - }else { - super.enteringNewElement(theNamespace, theChildName); - } - } - - - } - - private class PreResourceState extends BaseState { private Map myContainedResources = new HashMap(); private BundleEntry myEntry; private IResource myInstance; + private FhirVersionEnum myParentVersion; private List myResourceReferences = new ArrayList(); private Class myResourceType; @@ -1750,6 +1727,11 @@ private class ElementCompositeState extends BaseState { super(null); myEntry = theEntry; myResourceType = theResourceType; + if (theResourceType != null) { + myParentVersion = myContext.getResourceDefinition(theResourceType).getStructureVersion(); + } else { + myParentVersion = myContext.getVersion().getVersion(); + } } /** @@ -1757,12 +1739,13 @@ private class ElementCompositeState extends BaseState { * May be null */ public PreResourceState(Class theResourceType) { - super(null); - myResourceType = theResourceType; + this(null, theResourceType); } - public PreResourceState(PreResourceState thePreResourcesState) { + public PreResourceState(PreResourceState thePreResourcesState, FhirVersionEnum theParentVersion) { super(thePreResourcesState); + Validate.notNull(theParentVersion); + myParentVersion = theParentVersion; } @Override @@ -1774,9 +1757,9 @@ private class ElementCompositeState extends BaseState { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { BaseRuntimeElementDefinition definition; if (myResourceType == null) { - definition = myContext.getResourceDefinition(theLocalPart); + definition = myContext.getResourceDefinition(myParentVersion, theLocalPart); if ((definition == null)) { - throw new DataFormatException("Element '" + theLocalPart + "' is not a resource, expected a resource at this position"); + throw new DataFormatException("Element '" + theLocalPart + "' is not a known resource type, expected a resource at this position"); } } else { definition = myContext.getResourceDefinition(myResourceType); @@ -1954,7 +1937,7 @@ private class ElementCompositeState extends BaseState { push(new SwallowChildrenWholeState(getPreResourceState())); return; } - + @Override protected IBase getCurrentElement() { return myInstance; @@ -2035,6 +2018,25 @@ private class ElementCompositeState extends BaseState { DISPLAY, INITIAL, REFERENCE } + private class ResourceState extends ElementCompositeState { + + public ResourceState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition theDef, IResource theInstance) { + super(thePreResourceState, theDef, theInstance); + } + + @Override + public void enteringNewElement(String theNamespace, String theChildName) throws DataFormatException { + if ("id".equals(theChildName)) { + push(new PrimitiveState(getPreResourceState(), getCurrentElement().getId())); + } else if ("meta".equals(theChildName)) { + push(new MetaElementState(getPreResourceState(), getCurrentElement().getResourceMetadata())); + } else { + super.enteringNewElement(theNamespace, theChildName); + } + } + + } + private class SwallowChildrenWholeState extends BaseState { private int myDepth; @@ -2095,11 +2097,11 @@ private class ElementCompositeState extends BaseState { private static final int SCHEME = 3; private static final int TERM = 1; + private String myLabel; + private String myScheme; private int mySubState = 0; private TagList myTagList; private String myTerm; - private String myLabel; - private String myScheme; public TagState(TagList theTagList) { super(null); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java index b1db69b0843..c426d8ae917 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java @@ -926,7 +926,6 @@ public class XmlParser extends BaseParser implements IParser { @Override public T parseResource(Class theResourceType, Reader theReader) { XMLEventReader streamReader = createStreamReader(theReader); - return parseResource(theResourceType, streamReader); } diff --git a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties index 90208a804d8..33f4f273073 100644 --- a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties +++ b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties @@ -1,6 +1,6 @@ # Core Library Messages - +ca.uhn.fhir.context.FhirContext.unknownResourceName=Unknown resource name "{0}" (this name is not known in FHIR version "{1}") ca.uhn.fhir.context.FhirContext.noStructures=Could not find any HAPI-FHIR structure JARs on the classpath. Note that as of HAPI-FHIR v0.8, a separate FHIR strcture JAR must be added to your classpath (or project pom.xml if you are using Maven) ca.uhn.fhir.context.FhirContext.noStructuresForSpecifiedVersion=Could not find the HAPI-FHIR structure JAR on the classpath for version {0}. Note that as of HAPI-FHIR v0.8, a separate FHIR strcture JAR must be added to your classpath (or project pom.xml if you are using Maven) diff --git a/hapi-fhir-base/testmindeps/src/test/java/ca/uhn/fhir/context/MultiVersionModelScannerTest.java b/hapi-fhir-base/testmindeps/src/test/java/ca/uhn/fhir/context/MultiVersionModelScannerTest.java new file mode 100644 index 00000000000..94c2e78679b --- /dev/null +++ b/hapi-fhir-base/testmindeps/src/test/java/ca/uhn/fhir/context/MultiVersionModelScannerTest.java @@ -0,0 +1,29 @@ +package ca.uhn.fhir.context; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class MultiVersionModelScannerTest { + + @Test + public void testScan() { + FhirContext ctx = FhirContext.forDstu1(); + + RuntimeResourceDefinition def; + def = ctx.getResourceDefinition(ca.uhn.fhir.model.dstu2.resource.Patient.class); + assertEquals(FhirVersionEnum.DSTU2, def.getStructureVersion()); + + def = ctx.getResourceDefinition(new ca.uhn.fhir.model.dstu2.resource.Patient()); + assertEquals(FhirVersionEnum.DSTU2, def.getStructureVersion()); + + def = ctx.getResourceDefinition("Patient"); + assertEquals(FhirVersionEnum.DSTU1, def.getStructureVersion()); + assertEquals(ca.uhn.fhir.model.dstu.resource.Patient.class, def.getImplementingClass()); + + def = ctx.getResourceDefinition(FhirVersionEnum.DSTU2, "Patient"); + assertEquals(FhirVersionEnum.DSTU2, def.getStructureVersion()); + assertEquals(ca.uhn.fhir.model.dstu2.resource.Patient.class, def.getImplementingClass()); + } + +} diff --git a/hapi-fhir-base/testmindeps/src/test/java/ca/uhn/fhir/parser/MultiVersionJsonParserTest.java b/hapi-fhir-base/testmindeps/src/test/java/ca/uhn/fhir/parser/MultiVersionJsonParserTest.java index c860490048c..a51236d25ff 100644 --- a/hapi-fhir-base/testmindeps/src/test/java/ca/uhn/fhir/parser/MultiVersionJsonParserTest.java +++ b/hapi-fhir-base/testmindeps/src/test/java/ca/uhn/fhir/parser/MultiVersionJsonParserTest.java @@ -19,7 +19,7 @@ public class MultiVersionJsonParserTest { p.addIdentifier("urn:sys", "001"); p.addUndeclaredExtension(false, "http://foo#ext", new QuantityDt(2.2)); - String str = FhirContext.forDev().newJsonParser().encodeResourceToString(p); + String str = FhirContext.forDstu2().newJsonParser().encodeResourceToString(p); ourLog.info(str); assertThat(str,StringContains.containsString("{\"resourceType\":\"Patient\",\"http://foo#ext\":[{\"valueQuantity\":{\"value\":2.2}}],\"identifier\":[{\"system\":\"urn:sys\",\"value\":\"001\"}]}")); diff --git a/hapi-fhir-jpaserver-base/.classpath b/hapi-fhir-jpaserver-base/.classpath index 9ebe1a6b158..f9148a1a7ac 100644 --- a/hapi-fhir-jpaserver-base/.classpath +++ b/hapi-fhir-jpaserver-base/.classpath @@ -27,7 +27,7 @@ - + diff --git a/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml b/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml index 5c9bd7532ab..4f92af543f1 100644 --- a/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,5 +1,5 @@ - + diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseFhirDao.java index ad0801b31d3..a8f1eb5d37b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseFhirDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseFhirDao.java @@ -83,7 +83,6 @@ import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum; -import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.parser.DataFormatException; @@ -537,8 +536,8 @@ public abstract class BaseFhirDao implements IDao { theEntity.setResourceType(toResourceName(theResource)); - List refs = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, ResourceReferenceDt.class); - for (ResourceReferenceDt nextRef : refs) { + List refs = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, BaseResourceReferenceDt.class); + for (BaseResourceReferenceDt nextRef : refs) { if (nextRef.getReference().isEmpty() == false) { if (nextRef.getReference().hasVersionIdPart()) { nextRef.setReference(nextRef.getReference().toUnqualifiedVersionless()); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDao.java index 909a483b4a6..a1fb0e90b81 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDao.java @@ -54,9 +54,9 @@ import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.TagList; +import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; import ca.uhn.fhir.model.dstu.resource.OperationOutcome; import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum; -import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.valueset.BundleEntryTransactionOperationEnum; @@ -249,8 +249,8 @@ public class FhirSystemDao extends BaseFhirDao implements IFhirSystemDao { } for (IResource nextResource : theResources) { - List allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, ResourceReferenceDt.class); - for (ResourceReferenceDt nextRef : allRefs) { + List allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, BaseResourceReferenceDt.class); + for (BaseResourceReferenceDt nextRef : allRefs) { IdDt nextId = nextRef.getReference(); if (idConversions.containsKey(nextId)) { IdDt newId = idConversions.get(nextId); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoTest.java index e14dc9c926d..ed19c594264 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoTest.java @@ -48,7 +48,7 @@ public class FhirSystemDaoTest { private static IFhirResourceDao ourPatientDao; private static IFhirSystemDao ourSystemDao; - //@Test + @Test public void testGetResourceCounts() { Observation obs = new Observation(); obs.getName().addCoding().setSystem("urn:system").setCode("testGetResourceCountsO01"); @@ -73,7 +73,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testHistory() throws Exception { Date start = new Date(); Thread.sleep(10); @@ -119,7 +119,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testPersistWithSimpleLink() { Patient patient = new Patient(); patient.setId(new IdDt("Patient/testPersistWithSimpleLinkP01")); @@ -173,7 +173,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testPersistWithUnknownId() { Observation obs = new Observation(); obs.getName().addCoding().setSystem("urn:system").setCode("testPersistWithSimpleLinkO01"); @@ -197,7 +197,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTagOperationss() throws Exception { TagList preSystemTl = ourSystemDao.getAllTags(); @@ -270,7 +270,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionCreateMatchUrlWithOneMatch() { String methodName = "testTransactionCreateMatchUrlWithOneMatch"; @@ -304,7 +304,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionCreateMatchUrlWithTwoMatch() { String methodName = "testTransactionCreateMatchUrlWithTwoMatch"; @@ -337,7 +337,7 @@ public class FhirSystemDaoTest { } } - //@Test + @Test public void testTransactionCreateMatchUrlWithZeroMatch() { String methodName = "testTransactionCreateMatchUrlWithZeroMatch"; @@ -365,7 +365,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionCreateNoMatchUrl() { String methodName = "testTransactionCreateNoMatchUrl"; @@ -382,7 +382,7 @@ public class FhirSystemDaoTest { assertThat(p.getId().getIdPart(), not(containsString("test"))); } - //@Test + @Test public void testTransactionDeleteMatchUrlWithOneMatch() { String methodName = "testTransactionDeleteMatchUrlWithOneMatch"; @@ -424,7 +424,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionDeleteMatchUrlWithTwoMatch() { String methodName = "testTransactionDeleteMatchUrlWithTwoMatch"; @@ -457,7 +457,7 @@ public class FhirSystemDaoTest { } } - //@Test + @Test public void testTransactionDeleteMatchUrlWithZeroMatch() { String methodName = "testTransactionDeleteMatchUrlWithZeroMatch"; @@ -531,7 +531,7 @@ public class FhirSystemDaoTest { } } - //@Test(expected = InvalidRequestException.class) + @Test(expected = InvalidRequestException.class) public void testTransactionFailsWithDuplicateIds() { Patient patient1 = new Patient(); patient1.setId(new IdDt("Patient/testTransactionFailsWithDusplicateIds")); @@ -544,7 +544,7 @@ public class FhirSystemDaoTest { ourSystemDao.transaction(Arrays.asList((IResource) patient1, patient2)); } - //@Test + @Test public void testTransactionFromBundle() throws Exception { InputStream bundleRes = FhirSystemDaoTest.class.getResourceAsStream("/bundle.json"); @@ -560,7 +560,7 @@ public class FhirSystemDaoTest { assertThat(id, not(equalToIgnoringCase(""))); } - //@Test + @Test public void testTransactionUpdateMatchUrlWithOneMatch() { String methodName = "testTransactionUpdateMatchUrlWithOneMatch"; @@ -596,7 +596,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionUpdateMatchUrlWithTwoMatch() { String methodName = "testTransactionUpdateMatchUrlWithTwoMatch"; @@ -629,7 +629,7 @@ public class FhirSystemDaoTest { } } - //@Test + @Test public void testTransactionUpdateMatchUrlWithZeroMatch() { String methodName = "testTransactionUpdateMatchUrlWithZeroMatch"; @@ -663,7 +663,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionUpdateMatchUrlWithZeroMatchAndNotPreExisting() { String methodName = "testTransactionUpdateMatchUrlWithZeroMatchAndNotPreExisting"; @@ -692,7 +692,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionUpdateNoMatchUrl() { String methodName = "testTransactionUpdateNoMatchUrl"; @@ -728,7 +728,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionUpdateNoOperationSpecified() throws Exception { List res = new ArrayList(); @@ -789,7 +789,7 @@ public class FhirSystemDaoTest { /** * Issue #55 */ - //@Test + @Test public void testTransactionWithCidIds() throws Exception { List res = new ArrayList(); @@ -821,7 +821,7 @@ public class FhirSystemDaoTest { } - //@Test + @Test public void testTransactionWithDelete() throws Exception { /* diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu1Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu1Test.java index eea3620433f..f5fd9f63bdc 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu1Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu1Test.java @@ -68,7 +68,7 @@ public class ResourceProviderDstu1Test { /** * Test for issue #60 */ - //@Test + @Test public void testStoreUtf8Characters() throws Exception { Organization org = new Organization(); org.setName("測試醫院"); @@ -91,7 +91,7 @@ public class ResourceProviderDstu1Test { } } - //@Test + @Test public void testSearchWithInclude() throws Exception { Organization org = new Organization(); org.addIdentifier().setSystem("urn:system").setValue( "testSearchWithInclude01"); @@ -121,7 +121,7 @@ public class ResourceProviderDstu1Test { } - //@Test + @Test public void testCountParam() throws Exception { // NB this does not get used- The paging provider has its own limits built in ourDaoConfig.setHardSearchLimit(100); @@ -147,7 +147,7 @@ public class ResourceProviderDstu1Test { /** * See issue #52 */ - //@Test + @Test public void testImagingStudyResources() throws Exception { IGenericClient client = ourClient; @@ -183,7 +183,7 @@ public class ResourceProviderDstu1Test { /** * See issue #52 */ - //@Test + @Test public void testDocumentReferenceResources() throws Exception { IGenericClient client = ourClient; @@ -201,7 +201,7 @@ public class ResourceProviderDstu1Test { /** * See issue #52 */ - //@Test + @Test public void testDiagnosticOrderResources() throws Exception { IGenericClient client = ourClient; @@ -234,7 +234,7 @@ public class ResourceProviderDstu1Test { } } - //@Test + @Test public void testCreateWithClientSuppliedId() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testCreateWithId01"); @@ -264,7 +264,7 @@ public class ResourceProviderDstu1Test { assertNotNull(history.getEntries().get(0).getResource()); } - //@Test + @Test public void testDeepChaining() { delete("Location", Location.SP_NAME, "testDeepChainingL1"); delete("Location", Location.SP_NAME, "testDeepChainingL2"); @@ -303,7 +303,7 @@ public class ResourceProviderDstu1Test { } - //@Test + @Test public void testSaveAndRetrieveExistingNarrative() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSaveAndRetrieveExistingNarrative01"); @@ -318,7 +318,7 @@ public class ResourceProviderDstu1Test { assertEquals("
HELLO WORLD
", actual.getText().getDiv().getValueAsString()); } - //@Test + @Test public void testSaveAndRetrieveWithContained() { Patient p1 = new Patient(); p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveWithContained01"); @@ -339,7 +339,7 @@ public class ResourceProviderDstu1Test { } - //@Test + @Test public void testSaveAndRetrieveWithoutNarrative() { Patient p1 = new Patient(); p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01"); @@ -350,7 +350,7 @@ public class ResourceProviderDstu1Test { assertThat(actual.getText().getDiv().getValueAsString(), containsString("IdentifiertestSearchByResourceChain01")); } - //@Test + @Test public void testSearchByIdentifier() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01"); deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier02"); @@ -370,7 +370,7 @@ public class ResourceProviderDstu1Test { assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart()); } - //@Test + @Test public void testSearchByIdentifierWithoutSystem() { deleteToken("Patient", Patient.SP_IDENTIFIER, "", "testSearchByIdentifierWithoutSystem01"); @@ -384,7 +384,7 @@ public class ResourceProviderDstu1Test { } - //@Test + @Test public void testSearchByResourceChain() { delete("Organization", Organization.SP_NAME, "testSearchByResourceChainName01"); deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByResourceChain01"); @@ -419,7 +419,7 @@ public class ResourceProviderDstu1Test { } - //@Test + @Test public void testTryToCreateResourceWithReferenceThatDoesntExist() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testTryToCreateResourceWithReferenceThatDoesntExist01"); @@ -437,7 +437,7 @@ public class ResourceProviderDstu1Test { } - //@Test + @Test public void testUpdateRejectsInvalidTypes() throws InterruptedException { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateRejectsInvalidTypes"); @@ -464,7 +464,7 @@ public class ResourceProviderDstu1Test { } - //@Test + @Test public void testUpdateWithClientSuppliedIdWhichDoesntExist() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExist"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java index 1779015e4b3..4cf68af978e 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java @@ -71,7 +71,7 @@ public class ResourceProviderDstu2Test { /** * Test for issue #60 */ - //@Test + @Test public void testStoreUtf8Characters() throws Exception { Organization org = new Organization(); org.setName("測試醫院"); @@ -97,7 +97,7 @@ public class ResourceProviderDstu2Test { /** * Test for issue #60 */ - //@Test + @Test public void testReadAllInstancesOfType() throws Exception { Patient pat; @@ -121,7 +121,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testSearchWithInclude() throws Exception { Organization org = new Organization(); org.addIdentifier().setSystem("urn:system:rpdstu2").setValue( "testSearchWithInclude01"); @@ -151,7 +151,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testCountParam() throws Exception { // NB this does not get used- The paging provider has its own limits built in ourDaoConfig.setHardSearchLimit(100); @@ -177,7 +177,7 @@ public class ResourceProviderDstu2Test { /** * See issue #52 */ - //@Test + @Test public void testImagingStudyResources() throws Exception { IGenericClient client = ourClient; @@ -216,7 +216,7 @@ public class ResourceProviderDstu2Test { /** * See issue #52 */ - //@Test + @Test public void testDocumentReferenceResources() throws Exception { IGenericClient client = ourClient; @@ -234,7 +234,7 @@ public class ResourceProviderDstu2Test { /** * See issue #52 */ - //@Test + @Test public void testDiagnosticOrderResources() throws Exception { IGenericClient client = ourClient; @@ -267,7 +267,7 @@ public class ResourceProviderDstu2Test { } } - //@Test + @Test public void testCreateWithClientSuppliedId() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system:rpdstu2", "testCreateWithId01"); @@ -297,7 +297,7 @@ public class ResourceProviderDstu2Test { assertNotNull(history.getEntries().get(0).getResource()); } - //@Test + @Test public void testDeepChaining() { delete("Location", Location.SP_NAME, "testDeepChainingL1"); delete("Location", Location.SP_NAME, "testDeepChainingL2"); @@ -336,7 +336,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testSaveAndRetrieveExistingNarrative() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSaveAndRetrieveExistingNarrative01"); @@ -351,7 +351,7 @@ public class ResourceProviderDstu2Test { assertEquals("
HELLO WORLD
", actual.getText().getDiv().getValueAsString()); } - //@Test + @Test public void testSaveAndRetrieveWithContained() { Patient p1 = new Patient(); p1.addIdentifier().setSystem("urn:system:rpdstu2").setValue("testSaveAndRetrieveWithContained01"); @@ -372,7 +372,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testSaveAndRetrieveWithoutNarrative() { Patient p1 = new Patient(); p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01"); @@ -383,7 +383,7 @@ public class ResourceProviderDstu2Test { assertThat(actual.getText().getDiv().getValueAsString(), containsString("IdentifiertestSearchByResourceChain01")); } - //@Test + @Test public void testSearchByIdentifier() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01"); deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier02"); @@ -404,7 +404,7 @@ public class ResourceProviderDstu2Test { assertEquals(BundleEntrySearchModeEnum.MATCH, actual.getEntries().get(0).getSearchMode().getValueAsEnum()); } - //@Test + @Test public void testSearchByIdentifierWithoutSystem() { deleteToken("Patient", Patient.SP_IDENTIFIER, "", "testSearchByIdentifierWithoutSystem01"); @@ -418,7 +418,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testSearchByResourceChain() { delete("Organization", Organization.SP_NAME, "testSearchByResourceChainName01"); deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByResourceChain01"); @@ -453,7 +453,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testTryToCreateResourceWithReferenceThatDoesntExist() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testTryToCreateResourceWithReferenceThatDoesntExist01"); @@ -471,7 +471,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testUpdateRejectsInvalidTypes() throws InterruptedException { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateRejectsInvalidTypes"); @@ -498,7 +498,7 @@ public class ResourceProviderDstu2Test { } - //@Test + @Test public void testUpdateWithClientSuppliedIdWhichDoesntExist() { deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java index a0efd8b7782..70068ecd9f4 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SystemProviderTest.java @@ -42,7 +42,7 @@ public class SystemProviderTest { public void testTransactionFromBundle() throws Exception { InputStream bundleRes = SystemProviderTest.class.getResourceAsStream("/test-server-seed-bundle.json"); - Bundle bundle = new FhirContext().newJsonParser().parseBundle(new InputStreamReader(bundleRes)); + Bundle bundle = FhirContext.forDstu1().newJsonParser().parseBundle(new InputStreamReader(bundleRes)); List res = bundle.toListOfResources(); ourClient.transaction().withResources(res).execute(); @@ -100,6 +100,7 @@ public class SystemProviderTest { ourCtx = restServer.getFhirContext(); + ourCtx.getRestfulClientFactory().setSocketTimeout(600 * 1000); ourClient = ourCtx.newRestfulGenericClient(serverBase); ourClient.setLogRequestAndResponse(true); } diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerTest.java index bd19fad8660..a4b05e77941 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/context/ModelScannerTest.java @@ -14,7 +14,7 @@ public class ModelScannerTest { /** This failed at one point */ @Test public void testCarePlan() throws DataFormatException { - new ModelScanner(new FhirContext(), CarePlan.class); + FhirContext.forDstu1().getResourceDefinition(CarePlan.class); } @Test @@ -34,8 +34,8 @@ public class ModelScannerTest { @Test public void testScanExtensionTypes() throws DataFormatException { - ModelScanner scanner = new ModelScanner(new FhirContext(),ResourceWithExtensionsA.class); - RuntimeResourceDefinition def = (RuntimeResourceDefinition) scanner.getClassToElementDefinitions().get(ResourceWithExtensionsA.class); + FhirContext ctx = FhirContext.forDstu1(); + RuntimeResourceDefinition def = ctx.getResourceDefinition(ResourceWithExtensionsA.class); assertEquals(RuntimeChildCompositeDatatypeDefinition.class, def.getChildByNameOrThrowDataFormatException("identifier").getClass());