From 2edc7eadab64d171ddc1b7c971ff36b9eb55ce67 Mon Sep 17 00:00:00 2001
From: jamesagnew
> List> toBaseExtensionList(final List theList) { List> retVal = new ArrayList >(theList.size()); @@ -636,7 +674,7 @@ public class XmlParser extends BaseParser implements IParser { return retVal; } - private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, BaseResourceReferenceDt theRef) throws XMLStreamException { + private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, IReference theRef) throws XMLStreamException { String reference = determineReferenceText(theRef); if (StringUtils.isNotBlank(reference)) { @@ -651,11 +689,10 @@ public class XmlParser extends BaseParser implements IParser { } } - private void encodeResourceToStreamWriterInDstu2Format(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theElement, XMLStreamWriter theEventWriter, - BaseRuntimeElementCompositeDefinition> resDef, boolean theIncludedResource) throws XMLStreamException, DataFormatException { + private void encodeResourceToStreamWriterInDstu2Format(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theElement, XMLStreamWriter theEventWriter, BaseRuntimeElementCompositeDefinition> resDef, boolean theIncludedResource) throws XMLStreamException, DataFormatException { /* - * DSTU2 requires extensions to come in a specific spot within the encoded content - This is a bit of a messy way to make that happen, but hopefully this won't matter as much once we use the - * HL7 structures + * DSTU2 requires extensions to come in a specific spot within the encoded content - This is a bit of a messy + * way to make that happen, but hopefully this won't matter as much once we use the HL7 structures */ List preExtensionChildren = new ArrayList (); @@ -708,14 +745,14 @@ public class XmlParser extends BaseParser implements IParser { if (theResource instanceof IResource) { // HAPI structs IResource iResource = (IResource) theResource; - if (StringUtils.isNotBlank(iResource.getId().getValue())) { + if (StringUtils.isNotBlank(iResource.getId().getIdPart())) { resourceId = iResource.getId().getIdPart(); } } else { // HL7 structs IAnyResource resource = (IAnyResource) theResource; - if (StringUtils.isNotBlank(resource.getId())) { - resourceId = resource.getId(); + if (StringUtils.isNotBlank(resource.getId().getIdPart())) { + resourceId = resource.getId().getIdPart(); } } @@ -736,8 +773,9 @@ public class XmlParser extends BaseParser implements IParser { theEventWriter.writeDefaultNamespace(FHIR_NS); if (theResource instanceof IAnyResource) { - + // HL7.org Structures + writeOptionalTagWithValue(theEventWriter, "id", theResourceId); encodeCompositeElementToStreamWriter(theResource, theResource, theEventWriter, resDef, theContainedResource); } else { @@ -850,8 +888,7 @@ public class XmlParser extends BaseParser implements IParser { } } - private void encodeUndeclaredExtensions(IBaseResource theResource, XMLStreamWriter theWriter, List extends IBaseExtension>> theExtensions, String tagName, boolean theIncludedResource) - throws XMLStreamException, DataFormatException { + private void encodeUndeclaredExtensions(IBaseResource theResource, XMLStreamWriter theWriter, List extends IBaseExtension>> theExtensions, String tagName, boolean theIncludedResource) throws XMLStreamException, DataFormatException { for (IBaseExtension> next : theExtensions) { if (next == null) { continue; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java index 447cb3e2647..bc0e8d1b5fd 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java @@ -40,6 +40,7 @@ import org.hl7.fhir.instance.model.IBase; import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseParameters; +import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; @@ -266,7 +267,7 @@ public class GenericClient extends BaseClient implements IGenericClient { return myLastRequest; } - protected String getPreferredId(IResource theResource, String theId) { + protected String getPreferredId(IBaseResource theResource, String theId) { if (isNotBlank(theId)) { return theId; } @@ -574,7 +575,7 @@ public class GenericClient extends BaseClient implements IGenericClient { return resp; } - protected IResource parseResourceBody(String theResourceBody) { + protected IBaseResource parseResourceBody(String theResourceBody) { EncodingEnum encoding = null; for (int i = 0; i < theResourceBody.length() && encoding == null; i++) { switch (theResourceBody.charAt(i)) { @@ -625,7 +626,7 @@ public class GenericClient extends BaseClient implements IGenericClient { private CriterionList myCriterionList; private String myId; - private IResource myResource; + private IBaseResource myResource; private String myResourceBody; private String mySearchUrl; @@ -1597,8 +1598,8 @@ public class GenericClient extends BaseClient implements IGenericClient { private class UpdateInternal extends BaseClientExecutable implements IUpdate, IUpdateTyped, IUpdateExecutable, IUpdateWithQuery, IUpdateWithQueryTyped { private CriterionList myCriterionList; - private IdDt myId; - private IResource myResource; + private IIdType myId; + private IBaseResource myResource; private String myResourceBody; private String mySearchUrl; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java index 59ff899af92..9fd7a32a297 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java @@ -26,9 +26,13 @@ import java.io.IOException; import java.io.Reader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; -import ca.uhn.fhir.model.api.Include; import org.apache.commons.io.IOUtils; import org.hl7.fhir.instance.model.IBaseResource; @@ -36,6 +40,7 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum; @@ -123,7 +128,8 @@ public abstract class BaseMethodBinding implements IClientResponseHandler return myParameters; } - public Set getRequestIncludesFromParams(Object[] params) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Set getRequestIncludesFromParams(Object[] params) { if (params == null || params.length == 0) return null; int index = 0; @@ -148,7 +154,7 @@ public abstract class BaseMethodBinding implements IClientResponseHandler Set includes = new HashSet (); for (Object o : (Iterable)params[index]) { if (o instanceof Include) { - includes.add((Include) o); + includes.add(o); } } return includes; @@ -215,7 +221,7 @@ public abstract class BaseMethodBinding implements IClientResponseHandler return parser; } - protected Object[] createParametersForServerRequest(Request theRequest, IResource theResource) { + protected Object[] createParametersForServerRequest(Request theRequest, IBaseResource theResource) { Object[] params = new Object[getParameters().size()]; for (int i = 0; i < getParameters().size(); i++) { IParameter param = getParameters().get(i); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBinding.java index 288095ab83a..73a1db2f730 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseOutcomeReturningMethodBinding.java @@ -37,6 +37,7 @@ import org.hl7.fhir.instance.model.IBaseResource; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.TagList; @@ -143,16 +144,18 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding enumeration = theRequest.getServletRequest().getHeaders(Constants.HEADER_CATEGORY); enumeration.hasMoreElements();) { - String nextTagComplete = enumeration.nextElement(); - MethodUtil.parseTagValue(tagList, nextTagComplete); - } - if (tagList.isEmpty() == false) { - resource.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList); + if (theServer.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) { + TagList tagList = new TagList(); + for (Enumeration enumeration = theRequest.getServletRequest().getHeaders(Constants.HEADER_CATEGORY); enumeration.hasMoreElements();) { + String nextTagComplete = enumeration.nextElement(); + MethodUtil.parseTagValue(tagList, nextTagComplete); + } + if (tagList.isEmpty() == false) { + ((IResource)resource).getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList); + } } } else { resource = null; @@ -268,21 +271,21 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding wantedResourceType = requestContainsResourceType(); - IResource retVal; + IBaseResource retVal; if (wantedResourceType != null) { - retVal = (IResource) parser.parseResource(wantedResourceType, requestReader); + retVal = parser.parseResource(wantedResourceType, requestReader); } else { retVal = parser.parseResource(requestReader); } - + retVal.setId(theRequest.getId()); - + return retVal; } @@ -294,10 +297,9 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding requestContainsResourceType() { return null; @@ -307,7 +309,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding > theIfNoneExistParams) { + public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody, String theId, FhirContext theContext, Map > theIfNoneExistParams) { HttpPostClientInvocation retVal = createCreateInvocation(theResource, theResourceBody, theId, theContext); retVal.setIfNoneExistParams(theIfNoneExistParams); return retVal; } - public static HttpPostClientInvocation createCreateInvocation(IResource theResource, String theResourceBody, String theId, FhirContext theContext, String theIfNoneExistUrl) { + public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, String theResourceBody, String theId, FhirContext theContext, String theIfNoneExistUrl) { HttpPostClientInvocation retVal = createCreateInvocation(theResource, theResourceBody, theId, theContext); retVal.setIfNoneExistString(theIfNoneExistUrl); return retVal; } - public static HttpPutClientInvocation createUpdateInvocation(IResource theResource, String theResourceBody, IdDt theId, FhirContext theContext) { + public static HttpPutClientInvocation createUpdateInvocation(IBaseResource theResource, String theResourceBody, IIdType theId, FhirContext theContext) { String resourceName = theContext.getResourceDefinition(theResource).getName(); StringBuilder urlBuilder = new StringBuilder(); urlBuilder.append(resourceName); @@ -194,13 +196,13 @@ public class MethodUtil { } } - addTagsToPostOrPut(theResource, retVal); + addTagsToPostOrPut(theContext, theResource, retVal); // addContentTypeHeaderBasedOnDetectedType(retVal, theResourceBody); return retVal; } - public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IResource theResource, String theResourceBody, Map > theMatchParams) { + public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource, String theResourceBody, Map > theMatchParams) { StringBuilder b = new StringBuilder(); String resourceType = theContext.getResourceDefinition(theResource).getName(); @@ -221,7 +223,6 @@ public class MethodUtil { } } - HttpPutClientInvocation retVal; if (StringUtils.isBlank(theResourceBody)) { retVal = new HttpPutClientInvocation(theContext, theResource, b.toString()); @@ -229,12 +230,12 @@ public class MethodUtil { retVal = new HttpPutClientInvocation(theContext, theResourceBody, false, b.toString()); } - addTagsToPostOrPut(theResource, retVal); + addTagsToPostOrPut(theContext, theResource, retVal); return retVal; } - public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IResource theResource, String theResourceBody, String theMatchUrl) { + public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource, String theResourceBody, String theMatchUrl) { HttpPutClientInvocation retVal; if (StringUtils.isBlank(theResourceBody)) { retVal = new HttpPutClientInvocation(theContext, theResource, theMatchUrl); @@ -242,7 +243,7 @@ public class MethodUtil { retVal = new HttpPutClientInvocation(theContext, theResourceBody, false, theMatchUrl); } - addTagsToPostOrPut(theResource, retVal); + addTagsToPostOrPut(theContext, theResource, retVal); return retVal; } @@ -250,10 +251,10 @@ public class MethodUtil { public static EncodingEnum detectEncoding(String theBody) { for (int i = 0; i < theBody.length(); i++) { switch (theBody.charAt(i)) { - case '<': - return EncodingEnum.XML; - case '{': - return EncodingEnum.JSON; + case '<': + return EncodingEnum.XML; + case '{': + return EncodingEnum.JSON; } } return EncodingEnum.XML; @@ -406,7 +407,7 @@ public class MethodUtil { param = new ConditionalParamBinder(theRestfulOperationTypeEnum); } else if (nextAnnotation instanceof OperationParam) { Operation op = theMethod.getAnnotation(Operation.class); - param = new OperationParamBinder(op.name(), (OperationParam)nextAnnotation); + param = new OperationParamBinder(op.name(), (OperationParam) nextAnnotation); } else { continue; } @@ -519,26 +520,26 @@ public class MethodUtil { public static IQueryParameterAnd> parseQueryParams(RuntimeSearchParam theParamDef, String theUnqualifiedParamName, List theParameters) { QueryParameterAndBinder binder = null; switch (theParamDef.getParamType()) { - case COMPOSITE: - throw new UnsupportedOperationException(); - case DATE: - binder = new QueryParameterAndBinder(DateAndListParam.class, Collections. >emptyList()); - break; - case NUMBER: - binder = new QueryParameterAndBinder(NumberAndListParam.class, Collections. >emptyList()); - break; - case QUANTITY: - binder = new QueryParameterAndBinder(QuantityAndListParam.class, Collections. >emptyList()); - break; - case REFERENCE: - binder = new QueryParameterAndBinder(ReferenceAndListParam.class, Collections. >emptyList()); - break; - case STRING: - binder = new QueryParameterAndBinder(StringAndListParam.class, Collections. >emptyList()); - break; - case TOKEN: - binder = new QueryParameterAndBinder(TokenAndListParam.class, Collections. >emptyList()); - break; + case COMPOSITE: + throw new UnsupportedOperationException(); + case DATE: + binder = new QueryParameterAndBinder(DateAndListParam.class, Collections. > emptyList()); + break; + case NUMBER: + binder = new QueryParameterAndBinder(NumberAndListParam.class, Collections. > emptyList()); + break; + case QUANTITY: + binder = new QueryParameterAndBinder(QuantityAndListParam.class, Collections. > emptyList()); + break; + case REFERENCE: + binder = new QueryParameterAndBinder(ReferenceAndListParam.class, Collections. > emptyList()); + break; + case STRING: + binder = new QueryParameterAndBinder(StringAndListParam.class, Collections. > emptyList()); + break; + case TOKEN: + binder = new QueryParameterAndBinder(TokenAndListParam.class, Collections. > emptyList()); + break; } return binder.parse(theUnqualifiedParamName, theParameters); @@ -657,7 +658,7 @@ public class MethodUtil { if (reader != null) { IParser parser = ct.newParser(theContext); - IResource outcome = parser.parseResource(reader); + IBaseResource outcome = parser.parseResource(reader); if (outcome instanceof BaseOperationOutcome) { retVal.setOperationOutcome((BaseOperationOutcome) outcome); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ElementUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ElementUtil.java index 1531f71d81e..aa4eb689ed8 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ElementUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ElementUtil.java @@ -23,6 +23,8 @@ package ca.uhn.fhir.util; import java.util.ArrayList; import java.util.List; +import org.hl7.fhir.instance.model.IBase; + import ca.uhn.fhir.model.api.ICompositeElement; import ca.uhn.fhir.model.api.IElement; @@ -41,7 +43,7 @@ public class ElementUtil { } } else if (next instanceof String && (!((String)next).isEmpty())) { return false; - } else if (next != null && !((IElement) next).isEmpty()) { + } else if (next != null && !((IBase) next).isEmpty()) { return false; } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java index 823266bc205..f3d5a40984c 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java @@ -22,6 +22,7 @@ package ca.uhn.fhir.util; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.TreeSet; @@ -29,6 +30,7 @@ import java.util.TreeSet; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.IBase; import org.hl7.fhir.instance.model.IBaseResource; +import org.hl7.fhir.instance.model.api.IReference; import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; @@ -39,7 +41,6 @@ import ca.uhn.fhir.context.RuntimeChildChoiceDefinition; import ca.uhn.fhir.context.RuntimeChildDirectResource; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.model.api.ExtensionDt; -import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions; import ca.uhn.fhir.model.base.composite.BaseContainedDt; @@ -56,8 +57,7 @@ public class FhirTerser { myContext = theContext; } - private void addUndeclaredExtensions(IBase theElement, BaseRuntimeElementDefinition> theDefinition, BaseRuntimeChildDefinition theChildDefinition, - IModelVisitor theCallback) { + private void addUndeclaredExtensions(IBase theElement, BaseRuntimeElementDefinition> theDefinition, BaseRuntimeChildDefinition theChildDefinition, IModelVisitor theCallback) { if (theElement instanceof ISupportsUndeclaredExtensions) { ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement; for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) { @@ -68,14 +68,17 @@ public class FhirTerser { } /** - * Returns a list containing all child elements (including the resource itself) which are non-empty and are either of the exact type specified, or are a subclass of that type. + * Returns a list containing all child elements (including the resource itself) which are non-empty and are + * either of the exact type specified, or are a subclass of that type. * - * For example, specifying a type of {@link StringDt} would return all non-empty string instances within the message. Specifying a type of {@link IResource} would return the resource itself, as - * well as any contained resources. + * For example, specifying a type of {@link StringDt} would return all non-empty string instances within the + * message. Specifying a type of {@link IResource} would return the resource itself, as well as any contained + * resources. *
*- * Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, but will not descend into linked resources (e.g. - * {@link BaseResourceReferenceDt#getResource()}) or embedded resources (e.g. Bundle.entry.resource) + * Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, + * but will not descend into linked resources (e.g. {@link BaseResourceReferenceDt#getResource()}) or embedded + * resources (e.g. Bundle.entry.resource) *
* * @param theResource @@ -102,8 +105,7 @@ public class FhirTerser { @SuppressWarnings("unchecked") @Override - public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition> theDefinition, - ExtensionDt theNextExt) { + public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition> theDefinition, ExtensionDt theNextExt) { if (theType.isAssignableFrom(theNextExt.getClass())) { retVal.add((T) theNextExt); } @@ -115,39 +117,39 @@ public class FhirTerser { return retVal; } - publicList getAllResourceReferences(final IBaseResource theResource) { - final ArrayList retVal = new ArrayList (); - BaseRuntimeElementCompositeDefinition> def = myContext.getResourceDefinition(theResource); - visit(theResource, null, def, new IModelVisitor() { - @SuppressWarnings("unchecked") - @Override - public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition> theDefinition) { - if (theElement == null || theElement.isEmpty()) { - return; - } - String name = null; - if (theChildDefinition != null) { - name = theChildDefinition.getElementName(); - } - if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) { - retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt)theElement)); - } - } + public List getAllResourceReferences(final IBaseResource theResource) { + final ArrayList retVal = new ArrayList (); + BaseRuntimeElementCompositeDefinition> def = myContext.getResourceDefinition(theResource); + visit(theResource, null, def, new IModelVisitor() { + @Override + public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition> theDefinition) { + if (theElement == null || theElement.isEmpty()) { + return; + } + String name = null; + if (theChildDefinition != null) { + name = theChildDefinition.getElementName(); + } + if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) { + retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theElement)); + } + } - @SuppressWarnings("unchecked") - @Override - public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition> theDefinition, - ExtensionDt theNextExt) { - String name = null; - if (theChildDefinition != null) { - name = theChildDefinition.getElementName(); - } - if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) { - retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt)theNextExt.getValue())); - } - } - }); - return retVal; } private BaseRuntimeChildDefinition getDefinition(BaseRuntimeElementCompositeDefinition> theCurrentDef, List theSubList) { + @Override + public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition> theDefinition, ExtensionDt theNextExt) { + String name = null; + if (theChildDefinition != null) { + name = theChildDefinition.getElementName(); + } + if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) { + retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theNextExt.getValue())); + } + } + }); + return retVal; + } + + private BaseRuntimeChildDefinition getDefinition(BaseRuntimeElementCompositeDefinition> theCurrentDef, List theSubList) { BaseRuntimeChildDefinition nextDef = theCurrentDef.getChildByNameOrThrowDataFormatException(theSubList.get(0)); if (theSubList.size() == 1) { @@ -229,17 +231,16 @@ public class FhirTerser { // } switch (theDefinition.getChildType()) { -// case RESOURCE: -// // Don't descend into embedded resources -// break; + case ID_DATATYPE: + case PRIMITIVE_XHTML_HL7ORG: case PRIMITIVE_XHTML: case PRIMITIVE_DATATYPE: // These are primitive types break; case RESOURCE_REF: - BaseResourceReferenceDt resRefDt = (BaseResourceReferenceDt) theElement; + IReference resRefDt = (IReference) theElement; if (resRefDt.getReference().getValue() == null && resRefDt.getResource() != null) { - IResource theResource = resRefDt.getResource(); + IBaseResource theResource = resRefDt.getResource(); if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) { BaseRuntimeElementCompositeDefinition> def = myContext.getResourceDefinition(theResource); visit(theResource, null, def, theCallback); @@ -248,7 +249,7 @@ public class FhirTerser { break; case RESOURCE: case RESOURCE_BLOCK: - case COMPOSITE_DATATYPE: { + case COMPOSITE_DATATYPE: { BaseRuntimeElementCompositeDefinition> childDef = (BaseRuntimeElementCompositeDefinition>) theDefinition; for (BaseRuntimeChildDefinition nextChild : childDef.getChildrenAndExtension()) { List extends IBase> values = nextChild.getAccessor().getValues(theElement); @@ -281,7 +282,7 @@ public class FhirTerser { } throw new DataFormatException(b.toString()); } - + if (nextChild instanceof RuntimeChildDirectResource) { // Don't descend into embedded resources theCallback.acceptElement(nextValue, nextChild, childElementDef); @@ -305,16 +306,147 @@ public class FhirTerser { case UNDECL_EXT: { throw new IllegalStateException("state should not happen: " + theDefinition.getChildType()); } + case CONTAINED_RESOURCE_LIST: + if (theElement != null) { + BaseRuntimeElementDefinition> def = myContext.getElementDefinition(theElement.getClass()); + visit(theElement, null, def, theCallback); + } + break; } } + private void visit(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition> theDefinition, IModelVisitor2 theCallback, List theContainingElementPath, List theChildDefinitionPath, + List > theElementDefinitionPath) { + if (theChildDefinition != null) { + theChildDefinitionPath.add(theChildDefinition); + } + theContainingElementPath.add(theElement); + theElementDefinitionPath.add(theDefinition); + + theCallback.acceptElement(theElement, Collections.unmodifiableList(theContainingElementPath), Collections.unmodifiableList(theChildDefinitionPath), Collections.unmodifiableList(theElementDefinitionPath)); + + /* + * Visit undeclared extensions + */ + if (theElement instanceof ISupportsUndeclaredExtensions) { + ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement; + for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) { + theContainingElementPath.add(nextExt); + theCallback.acceptUndeclaredExtension(nextExt, theContainingElementPath, theChildDefinitionPath, theElementDefinitionPath); + theContainingElementPath.remove(theContainingElementPath.size() - 1); + } + } + + /* + * Now visit the children of the given element + */ + switch (theDefinition.getChildType()) { + case ID_DATATYPE: + case PRIMITIVE_XHTML_HL7ORG: + case PRIMITIVE_XHTML: + case PRIMITIVE_DATATYPE: + // These are primitive types, so we don't need to visit their children + break; + case RESOURCE_REF: + IReference resRefDt = (IReference) theElement; + if (resRefDt.getReference().getValue() == null && resRefDt.getResource() != null) { + IBaseResource theResource = resRefDt.getResource(); + if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) { + BaseRuntimeElementCompositeDefinition> def = myContext.getResourceDefinition(theResource); + visit(theResource, null, def, theCallback, theContainingElementPath, theChildDefinitionPath, theElementDefinitionPath); + } + } + break; + case RESOURCE: + case RESOURCE_BLOCK: + case COMPOSITE_DATATYPE: { + BaseRuntimeElementCompositeDefinition> childDef = (BaseRuntimeElementCompositeDefinition>) theDefinition; + for (BaseRuntimeChildDefinition nextChild : childDef.getChildrenAndExtension()) { + List extends IBase> values = nextChild.getAccessor().getValues(theElement); + if (values != null) { + for (IBase nextValue : values) { + if (nextValue == null) { + continue; + } + if (nextValue.isEmpty()) { + continue; + } + BaseRuntimeElementDefinition> childElementDef; + childElementDef = nextChild.getChildElementDefinitionByDatatype(nextValue.getClass()); + + if (childElementDef == null) { + StringBuilder b = new StringBuilder(); + b.append("Found value of type["); + b.append(nextValue.getClass().getSimpleName()); + b.append("] which is not valid for field["); + b.append(nextChild.getElementName()); + b.append("] in "); + b.append(childDef.getName()); + b.append(" - Valid types: "); + for (Iterator iter = new TreeSet (nextChild.getValidChildNames()).iterator(); iter.hasNext();) { + BaseRuntimeElementDefinition> childByName = nextChild.getChildByName(iter.next()); + b.append(childByName.getImplementingClass().getSimpleName()); + if (iter.hasNext()) { + b.append(", "); + } + } + throw new DataFormatException(b.toString()); + } + + if (nextChild instanceof RuntimeChildDirectResource) { + // Don't descend into embedded resources + theContainingElementPath.add(nextValue); + theChildDefinitionPath.add(nextChild); + theElementDefinitionPath.add(myContext.getElementDefinition(nextValue.getClass())); + theCallback.acceptElement(nextValue, Collections.unmodifiableList(theContainingElementPath), Collections.unmodifiableList(theChildDefinitionPath), Collections.unmodifiableList(theElementDefinitionPath)); + theChildDefinitionPath.remove(theChildDefinitionPath.size() - 1); + theContainingElementPath.remove(theContainingElementPath.size() - 1); + theElementDefinitionPath.remove(theElementDefinitionPath.size() - 1); + } else { + visit(nextValue, nextChild, childElementDef, theCallback, theContainingElementPath, theChildDefinitionPath, theElementDefinitionPath); + } + } + } + } + break; + } + case CONTAINED_RESOURCES: { + BaseContainedDt value = (BaseContainedDt) theElement; + for (IResource next : value.getContainedResources()) { + BaseRuntimeElementCompositeDefinition> def = myContext.getResourceDefinition(next); + visit(next, null, def, theCallback, theContainingElementPath, theChildDefinitionPath, theElementDefinitionPath); + } + break; + } + case EXTENSION_DECLARED: + case UNDECL_EXT: { + throw new IllegalStateException("state should not happen: " + theDefinition.getChildType()); + } + case CONTAINED_RESOURCE_LIST: { + if (theElement != null) { + BaseRuntimeElementDefinition> def = myContext.getElementDefinition(theElement.getClass()); + visit(theElement, null, def, theCallback, theContainingElementPath, theChildDefinitionPath, theElementDefinitionPath); + } + break; + } + } + + if (theChildDefinition != null) { + theChildDefinitionPath.remove(theChildDefinitionPath.size() - 1); + } + theContainingElementPath.remove(theContainingElementPath.size() - 1); + theElementDefinitionPath.remove(theElementDefinitionPath.size() - 1); + } + /** * Visit all elements in a given resource * * - * Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, but will not descend into linked resources (e.g. - * {@link BaseResourceReferenceDt#getResource()}) or embedded resources (e.g. Bundle.entry.resource) + * Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, + * but will not descend into linked resources (e.g. {@link BaseResourceReferenceDt#getResource()}) or embedded + * resources (e.g. Bundle.entry.resource) *
+ * * @param theResource * The resource to visit * @param theVisitor @@ -325,15 +457,36 @@ public class FhirTerser { visit(theResource, null, def, theVisitor); } + /** + * Visit all elements in a given resource + * + * THIS ALTERNATE METHOD IS STILL EXPERIMENTAL + * + *+ * Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, + * but will not descend into linked resources (e.g. {@link BaseResourceReferenceDt#getResource()}) or embedded + * resources (e.g. Bundle.entry.resource) + *
+ * + * @param theResource + * The resource to visit + * @param theVisitor + * The visitor + */ + void visit(IBaseResource theResource, IModelVisitor2 theVisitor) { + BaseRuntimeElementCompositeDefinition> def = myContext.getResourceDefinition(theResource); + visit(theResource, null, def, theVisitor, new ArrayList(), new ArrayList (), new ArrayList >()); + } + public Object getSingleValueOrNull(IBase theTarget, String thePath) { Validate.notNull(theTarget, "theTarget must not be null"); Validate.notBlank(thePath, "thePath must not be empty"); - + BaseRuntimeElementDefinition> def = myContext.getElementDefinition(theTarget.getClass()); if (!(def instanceof BaseRuntimeElementCompositeDefinition)) { throw new IllegalArgumentException("Target is not a composite type: " + theTarget.getClass().getName()); } - + BaseRuntimeElementCompositeDefinition> currentDef = (BaseRuntimeElementCompositeDefinition>) def; Object currentObj = theTarget; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/IModelVisitor2.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/IModelVisitor2.java new file mode 100644 index 00000000000..ccfdbb8f712 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/IModelVisitor2.java @@ -0,0 +1,49 @@ +package ca.uhn.fhir.util; + +/* + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2015 University Health Network + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import java.util.List; + +import org.hl7.fhir.instance.model.IBase; +import org.hl7.fhir.instance.model.IBaseResource; +import org.hl7.fhir.instance.model.api.IBaseExtension; + +import ca.uhn.fhir.context.BaseRuntimeChildDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementDefinition; + +/** + * @see FhirTerser#visit(IBaseResource, IModelVisitor2) + */ +public interface IModelVisitor2 { + + /** + * @param theElement The element being visited + * @param theContainingElementPath The elements in the path leading up to the actual element being accepted. The first element in this path will be the outer resource being visited, and the last element will be the saem object as the object passed as theElement
+ */ + boolean acceptElement(IBase theElement, ListtheContainingElementPath, List theChildDefinitionPath, List > theElementDefinitionPath); + + /** + */ + boolean acceptUndeclaredExtension(IBaseExtension> theNextExt, List theContainingElementPath, List theChildDefinitionPath, List > theElementDefinitionPath); + + + +} diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/IBaseResource.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/IBaseResource.java index 2d9ffaf41cf..e0cad744a75 100644 --- a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/IBaseResource.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/IBaseResource.java @@ -1,5 +1,7 @@ package org.hl7.fhir.instance.model; +import org.hl7.fhir.instance.model.api.IIdType; + /* * #%L * HAPI FHIR - Core Library @@ -29,5 +31,11 @@ package org.hl7.fhir.instance.model; * ca.uhn.fhir.model.dstu.resource.Patient
) */ public interface IBaseResource extends IBase { - // nothing here yet + + IIdType getId(); + + IBaseResource setId(String theId); + + IBaseResource setId(IIdType theId); + } diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java index 764bec73488..4c6db01650f 100644 --- a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IAnyResource.java @@ -24,7 +24,7 @@ import org.hl7.fhir.instance.model.IBaseResource; public interface IAnyResource extends IBaseResource { - String getId(); + IIdType getId(); IAnyResource setId(String theId); diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/IBaseResource.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseEnumeration.java similarity index 57% rename from hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/IBaseResource.java rename to hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseEnumeration.java index 2d9ffaf41cf..217be78bf98 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/IBaseResource.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseEnumeration.java @@ -1,4 +1,6 @@ -package org.hl7.fhir.instance.model; +package org.hl7.fhir.instance.model.api; + +import org.hl7.fhir.instance.model.IPrimitiveType; /* * #%L @@ -20,14 +22,8 @@ package org.hl7.fhir.instance.model; * #L% */ -/** - * For now, this is a simple marker interface indicating that a class is a resource type. - * There are two concrete types of implementations of this interrface. The first are - * HL7.org's Resource structures (e.g. - *org.hl7.fhir.instance.model.Patient
) and - * the second are HAPI's Resource structures, e.g. - *ca.uhn.fhir.model.dstu.resource.Patient
) - */ -public interface IBaseResource extends IBase { - // nothing here yet +public interface IBaseEnumeration> extends IPrimitiveType { + + // Marker interface + } diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseXhtml.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseXhtml.java new file mode 100644 index 00000000000..0b113db2c68 --- /dev/null +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IBaseXhtml.java @@ -0,0 +1,7 @@ +package org.hl7.fhir.instance.model.api; + +import org.hl7.fhir.instance.model.IPrimitiveType; + +public interface IBaseXhtml extends IPrimitiveType { + +} diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IIdType.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IIdType.java index 6e704aea7b3..649d9d2437c 100644 --- a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IIdType.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IIdType.java @@ -25,4 +25,34 @@ public interface IIdType { boolean isEmpty(); + boolean isLocal(); + + /** + * Returns the value of this ID. Note that this value may be a fully qualified URL, a relative/partial URL, or a simple ID. Use {@link #getIdPart()} to get just the ID portion. + * + * @see #getIdPart() + */ + String getValue(); + + /** + * Returns only the logical ID part of this ID. For example, given the ID + * "http://example,.com/fhir/Patient/123/_history/456", this method would + * return "123". + */ + String getIdPart(); + + boolean hasIdPart(); + + String getBaseUrl(); + + IIdType toUnqualifiedVersionless(); + + IIdType toVersionless(); + + IIdType setValue(String theString); + + boolean hasVersionIdPart(); + + String getVersionIdPart(); + } diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/INarrative.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/INarrative.java index ea3fab02975..554235319ea 100644 --- a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/INarrative.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/INarrative.java @@ -26,4 +26,10 @@ public interface INarrative extends ICompositeType { boolean isEmpty(); + // TODO: use less broad exception type here + public void setDivAsString(String theString) throws Exception; + + // TODO: use less broad exception type here + public String getDivAsString() throws Exception; + } diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IReference.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IReference.java index 0926349fe02..8ce216dcfd3 100644 --- a/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IReference.java +++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/instance/model/api/IReference.java @@ -21,16 +21,20 @@ package org.hl7.fhir.instance.model.api; */ import org.hl7.fhir.instance.model.IBase; +import org.hl7.fhir.instance.model.IBaseResource; +import org.hl7.fhir.instance.model.IPrimitiveType; public interface IReference extends IBase { - IAnyResource getResource(); + IBaseResource getResource(); - void setResource(IAnyResource theResource); + void setResource(IBaseResource theResource); - String getReference(); + IIdType getReference(); IReference setReference(String theReference); IBase setDisplay(String theValue); + + IPrimitiveType getDisplayElement(); } diff --git a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java index da7969555f6..54aa208ed0d 100644 --- a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java +++ b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/model/dstu2/resource/BaseResource.java @@ -122,12 +122,13 @@ public abstract class BaseResource extends BaseElement implements IResource { myId = theId; } - public void setId(String theId) { + public BaseResource setId(String theId) { if (theId == null) { myId = null; } else { myId = new IdDt(theId); } + return this; } @Override diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java index b15707f5f15..831215fd597 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserDstu2Test.java @@ -5,11 +5,15 @@ import static org.junit.Assert.*; import java.io.StringReader; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.UUID; import org.apache.commons.io.IOUtils; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.XMLUnit; +import org.hamcrest.text.StringContainsInOrder; +import org.hl7.fhir.instance.model.IBaseResource; import org.junit.BeforeClass; import org.junit.Test; @@ -26,6 +30,7 @@ import ca.uhn.fhir.model.dstu2.composite.CodingDt; import ca.uhn.fhir.model.dstu2.composite.ContainedDt; import ca.uhn.fhir.model.dstu2.composite.DurationDt; import ca.uhn.fhir.model.dstu2.composite.HumanNameDt; +import ca.uhn.fhir.model.dstu2.composite.IdentifierDt; import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt; import ca.uhn.fhir.model.dstu2.resource.AllergyIntolerance; import ca.uhn.fhir.model.dstu2.resource.Binary; @@ -36,6 +41,7 @@ import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription; import ca.uhn.fhir.model.dstu2.resource.Observation; import ca.uhn.fhir.model.dstu2.resource.Organization; import ca.uhn.fhir.model.dstu2.resource.Patient; +import ca.uhn.fhir.model.dstu2.valueset.DocumentReferenceStatusEnum; import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum; import ca.uhn.fhir.model.primitive.DateDt; import ca.uhn.fhir.model.primitive.DateTimeDt; @@ -54,6 +60,204 @@ public class XmlParserDstu2Test { XMLUnit.setIgnoreWhitespace(true); } + @Test + public void testEncodeBinaryWithNoContentType() { + Binary b = new Binary(); + b.setContent(new byte[] {1,2,3,4}); + + String output = ourCtx.newXmlParser().encodeResourceToString(b); + ourLog.info(output); + + assertEquals(" ", output); + } + + + @Test + public void testEncodeNonContained() { + // Create an organization + Organization org = new Organization(); + org.setId("Organization/65546"); + org.getNameElement().setValue("Contained Test Organization"); + + // Create a patient + Patient patient = new Patient(); + patient.setId("Patient/1333"); + patient.addIdentifier().setSystem("urn:mrns").setValue("253345"); + patient.getManagingOrganization().setResource(org); + + // Create a list containing both resources. In a server method, you might just + // return this list, but here we will create a bundle to encode. + List resources = new ArrayList (); + resources.add(org); + resources.add(patient); + + // Create a bundle with both + ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle(); + b.addEntry().setResource(org); + b.addEntry().setResource(patient); + + // Encode the buntdle + String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b); + ourLog.info(encoded); + assertThat(encoded, not(containsString(" "))); + assertThat(encoded, stringContainsInOrder(" ", " ")); + assertThat(encoded, containsString("")); + assertThat(encoded, stringContainsInOrder(" ", " ")); + + encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient); + ourLog.info(encoded); + assertThat(encoded, not(containsString(""))); + assertThat(encoded, containsString(" ")); + + + } + + @Test + public void testParseNarrative() throws Exception { + //@formatter:off + String htmlNoNs = " AAABBBCCC"; + String htmlNs = htmlNoNs.replace("", ""); + String res= "\n" + + " "; + //@formatter:on + + Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res); + assertEquals(htmlNoNs, p.getText().getDiv().getValueAsString()); + } + + /** + * Thanks to Alexander Kley! + */ + @Test + public void testParseContainedBinaryResource() { + byte[] bin = new byte[] { 0, 1, 2, 3, 4 }; + final Binary binary = new Binary(); + binary.setContentType("PatientConsent").setContent(bin); + // binary.setId(UUID.randomUUID().toString()); + + ca.uhn.fhir.model.dstu2.resource.DocumentManifest manifest = new ca.uhn.fhir.model.dstu2.resource.DocumentManifest(); + // manifest.setId(UUID.randomUUID().toString()); + CodeableConceptDt cc = new CodeableConceptDt(); + cc.addCoding().setSystem("mySystem").setCode("PatientDocument"); + manifest.setType(cc); + manifest.setMasterIdentifier(new IdentifierDt().setSystem("mySystem").setValue(UUID.randomUUID().toString())); + manifest.addContent().setP(new ResourceReferenceDt(binary)); + manifest.setStatus(DocumentReferenceStatusEnum.CURRENT); + + String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(manifest); + ourLog.info(encoded); + assertThat(encoded, StringContainsInOrder.stringContainsInOrder(Arrays.asList("contained>", "\n" + + " \n" + + " " + htmlNs + "\n" + + " \n" + + ""))); + + ca.uhn.fhir.model.dstu2.resource.DocumentManifest actual = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.DocumentManifest.class, encoded); + assertEquals(1, actual.getContained().getContainedResources().size()); + assertEquals(1, actual.getContent().size()); + assertNotNull(((ResourceReferenceDt)actual.getContent().get(0).getP()).getResource()); + + } + + @Test + public void testEncodeAndParseContained() { + IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true); + + // Create an organization, note that the organization does not have an ID + Organization org = new Organization(); + org.getNameElement().setValue("Contained Test Organization"); + + // Create a patient + Patient patient = new Patient(); + patient.setId("Patient/1333"); + patient.addIdentifier().setSystem("urn:mrns").setValue("253345"); + + // Put the organization as a reference in the patient resource + patient.getManagingOrganization().setResource(org); + + String encoded = xmlParser.encodeResourceToString(patient); + ourLog.info(encoded); + assertThat(encoded, containsString(" ")); + assertThat(encoded, containsString(" ")); + + // Create a bundle with just the patient resource + ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle(); + b.addEntry().setResource(patient); + + // Encode the bundle + encoded = xmlParser.encodeResourceToString(b); + ourLog.info(encoded); + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " "))); + assertThat(encoded, containsString("", " ")); + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " "))); + assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", " ", "")))); + + // Re-parse the bundle + patient = (Patient) xmlParser.parseResource(xmlParser.encodeResourceToString(patient)); + assertEquals("#1", patient.getManagingOrganization().getReference().getValue()); + + assertNotNull(patient.getManagingOrganization().getResource()); + org = (Organization) patient.getManagingOrganization().getResource(); + assertEquals("#1", org.getId().getValue()); + assertEquals("Contained Test Organization", org.getName()); + + // And re-encode a second time + encoded = xmlParser.encodeResourceToString(patient); + ourLog.info(encoded); + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " ", ""))); + assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); + assertThat(encoded, containsString(" ")); + + // And re-encode once more, with the references cleared + patient.getContained().getContainedResources().clear(); + patient.getManagingOrganization().setReference((String)null); + encoded = xmlParser.encodeResourceToString(patient); + ourLog.info(encoded); + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " ", ""))); + assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); + assertThat(encoded, containsString(" ")); + + // And re-encode once more, with the references cleared and a manually set local ID + patient.getContained().getContainedResources().clear(); + patient.getManagingOrganization().setReference((String)null); + patient.getManagingOrganization().getResource().setId(("#333")); + encoded = xmlParser.encodeResourceToString(patient); + ourLog.info(encoded); + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " ", ""))); + assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); + + } + + + @Test + public void testEncodeContainedWithNarrativeIsSuppresed() throws Exception { + IParser parser = ourCtx.newXmlParser().setPrettyPrint(true); + + // Create an organization, note that the organization does not have an ID + Organization org = new Organization(); + org.getNameElement().setValue("Contained Test Organization"); + org.getText().setDiv(" FOOBAR"); + + // Create a patient + Patient patient = new Patient(); + patient.setId("Patient/1333"); + patient.addIdentifier().setSystem("urn:mrns").setValue("253345"); + patient.getText().setDiv("BARFOO"); + patient.getManagingOrganization().setResource(org); + + String encoded = parser.encodeResourceToString(patient); + ourLog.info(encoded); + + assertThat(encoded, stringContainsInOrder("", " BARFOO", "", " ", " ", " strings = t.getAllPopulatedChildElementsOfType(b, StringDt.class); + + assertEquals(1, strings.size()); + assertThat(strings, containsInAnyOrder(new StringDt("BUNDLE"))); + + } + + @Test + public void testGetAllPopulatedChildElementsOfTypeDescendsIntoContained() { + Patient p = new Patient(); + p.addName().addFamily("PATIENT"); + + Organization o = new Organization(); + o.getNameElement().setValue("ORGANIZATION"); + p.getContained().getContainedResources().add(o); + + FhirTerser t = ourCtx.newTerser(); + List strings = t.getAllPopulatedChildElementsOfType(p, StringDt.class); + + assertEquals(2, strings.size()); + assertThat(strings, containsInAnyOrder(new StringDt("PATIENT"), new StringDt("ORGANIZATION"))); + + } + + @Test + public void testVisitWithModelVisitor2() { + IModelVisitor2 visitor = mock(IModelVisitor2.class); + + ArgumentCaptor element = ArgumentCaptor.forClass(IBase.class); + ArgumentCaptor > containingElementPath = ArgumentCaptor.forClass(getListClass(IBase.class)); + ArgumentCaptor
> childDefinitionPath = ArgumentCaptor.forClass(getListClass(BaseRuntimeChildDefinition.class)); + ArgumentCaptor
>> elementDefinitionPath = ArgumentCaptor.forClass(getListClass2()); + when(visitor.acceptElement(element.capture(), containingElementPath.capture(), childDefinitionPath.capture(), elementDefinitionPath.capture())).thenReturn(true); + + Patient p = new Patient(); + p.addLink().getTypeElement().setValue("CODE"); + ourCtx.newTerser().visit(p, visitor); + + assertEquals(3, element.getAllValues().size()); + assertSame(p, element.getAllValues().get(0)); + assertSame(p.getLinkFirstRep(), element.getAllValues().get(1)); + assertSame(p.getLinkFirstRep().getTypeElement(), element.getAllValues().get(2)); + + assertEquals(3, containingElementPath.getAllValues().size()); +// assertEquals(0, containingElementPath.getAllValues().get(0).size()); +// assertEquals(1, containingElementPath.getAllValues().get(1).size()); +// assertEquals(2, containingElementPath.getAllValues().get(2).size()); + + } + + /** + * See + * http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type + */ + private static
Class > getListClass(Class
theClass) { + return new ClassGetter >() {}.get(); + } + + /** + * See + * http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type + */ + private static Class
>> getListClass2() { + return new ClassGetter
>>() {}.get(); + } + + /** + * See + * http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type + */ + private static abstract class ClassGetter
{ + @SuppressWarnings("unchecked") + public final Class get() { + final ParameterizedType superclass = (ParameterizedType) + getClass().getGenericSuperclass(); + Type type = superclass.getActualTypeArguments()[0]; + if (type instanceof ParameterizedType) { + return (Class ) ((ParameterizedType) type).getOwnerType(); + } + return (Class )type; + } + } + +} diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/util/FhirTerserTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/util/FhirTerserTest.java deleted file mode 100644 index d15bc047614..00000000000 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/util/FhirTerserTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package ca.uhn.fhir.util; - -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - -import java.util.List; - -import org.junit.Test; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.model.dstu2.resource.Bundle; -import ca.uhn.fhir.model.dstu2.resource.Organization; -import ca.uhn.fhir.model.dstu2.resource.Patient; -import ca.uhn.fhir.model.primitive.StringDt; - -public class FhirTerserTest { - - private static FhirContext ourCtx = new FhirContext(); - - @Test - public void testGetAllPopulatedChildElementsOfTypeDoesntDescendIntoEmbedded() { - Patient p = new Patient(); - p.addName().addFamily("PATIENT"); - - Bundle b = new Bundle(); - b.addEntry().setResource(p); - b.addLink().setRelation("BUNDLE"); - - FhirTerser t = ourCtx.newTerser(); - List strings = t.getAllPopulatedChildElementsOfType(b, StringDt.class); - - assertEquals(1, strings.size()); - assertThat(strings, containsInAnyOrder(new StringDt("BUNDLE"))); - - } - - @Test - public void testGetAllPopulatedChildElementsOfTypeDescendsIntoContained() { - Patient p = new Patient(); - p.addName().addFamily("PATIENT"); - - Organization o = new Organization(); - o.getNameElement().setValue("ORGANIZATION"); - p.getContained().getContainedResources().add(o); - - FhirTerser t = ourCtx.newTerser(); - List strings = t.getAllPopulatedChildElementsOfType(p, StringDt.class); - - assertEquals(2, strings.size()); - assertThat(strings, containsInAnyOrder(new StringDt("PATIENT"), new StringDt("ORGANIZATION"))); - - } - -} diff --git a/hapi-fhir-structures-hl7org-dstu2/.classpath b/hapi-fhir-structures-hl7org-dstu2/.classpath index acfe2cc4f2a..3e385a31988 100644 --- a/hapi-fhir-structures-hl7org-dstu2/.classpath +++ b/hapi-fhir-structures-hl7org-dstu2/.classpath @@ -19,11 +19,11 @@ + - diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml index fdfed0215db..d531858443a 100644 --- a/hapi-fhir-structures-hl7org-dstu2/pom.xml +++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml @@ -18,7 +18,7 @@ ca.uhn.hapi.fhir hapi-fhir-base -0.9-SNAPSHOT +1.0-SNAPSHOT diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/DomainResource.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/DomainResource.java index b80cd8cf9fc..90e1051277c 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/DomainResource.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/DomainResource.java @@ -40,11 +40,12 @@ import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.api.IBaseHasExtensions; import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions; +import org.hl7.fhir.instance.model.api.IDomainResource; /** * A resource that includes narrative, extensions, and contained resources. */ @ResourceDef(name="DomainResource", profile="http://hl7.org/fhir/Profile/DomainResource") -public abstract class DomainResource extends Resource implements IBaseHasExtensions, IBaseHasModifierExtensions { +public abstract class DomainResource extends Resource implements IBaseHasExtensions, IBaseHasModifierExtensions, IDomainResource { /** * A human-readable narrative that contains a summary of the resource, and may be used to represent the content of the resource to a human. The narrative need not encode all the structured data, but is required to contain sufficient detail to make it "clinically safe" for a human to just read the narrative. Resource definitions may define what content should be represented in the narrative to ensure clinical safety. diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Enumeration.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Enumeration.java index c0ed0894587..351a4c53d36 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Enumeration.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Enumeration.java @@ -2,6 +2,7 @@ package org.hl7.fhir.instance.model; import org.hl7.fhir.instance.model.annotations.DatatypeDef; import org.hl7.fhir.instance.model.api.IBaseEnumFactory; +import org.hl7.fhir.instance.model.api.IBaseEnumeration; /* Copyright (c) 2011+, HL7, Inc @@ -37,7 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. * */ @DatatypeDef(name="enumeration") -public class Enumeration > extends PrimitiveType { +public class Enumeration > extends PrimitiveType implements IBaseEnumeration { private static final long serialVersionUID = 1L; private EnumFactory myEnumFactory; diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/IdType.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/IdType.java index d193f4c064a..78663154302 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/IdType.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/IdType.java @@ -28,8 +28,7 @@ POSSIBILITY OF SUCH DAMAGE. */ package org.hl7.fhir.instance.model; -import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.apache.commons.lang3.StringUtils.*; import java.math.BigDecimal; @@ -38,13 +37,9 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.hl7.fhir.instance.model.annotations.DatatypeDef; -import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IIdType; -import ca.uhn.fhir.model.api.IPrimitiveDatatype; -import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.annotation.SimpleSetter; -import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.UriDt; import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.rest.server.Constants; @@ -545,32 +540,12 @@ public class IdType extends UriType implements IIdType { return isBlank(getValue()); } - public void applyTo(IBaseResource theResouce) { - if (theResouce == null) { - throw new NullPointerException("theResource can not be null"); - } else if (theResouce instanceof IResource) { - ((IResource) theResouce).setId(new IdType(getValue())); - } else if (theResouce instanceof IAnyResource) { - ((IAnyResource) theResouce).setId(getIdPart()); - } else { - throw new IllegalArgumentException("Unknown resource class type, does not implement IResource or extend Resource"); - } + @Override + public IdType copy() { + return new IdType(getValue()); } - /** - * Retrieves the ID from the given resource instance - */ - public static IdType of(IBaseResource theResouce) { - if (theResouce == null) { - throw new NullPointerException("theResource can not be null"); - } else if (theResouce instanceof IResource) { - return ((IResource) theResouce).getId(); - } else if (theResouce instanceof IAnyResource) { - // TODO: implement - throw new UnsupportedOperationException(); - } else { - throw new IllegalArgumentException("Unknown resource class type, does not implement IResource or extend Resource"); - } - } - -} + + + +} \ No newline at end of file diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Narrative.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Narrative.java index 3babedb4c29..430e1a0d98b 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Narrative.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Narrative.java @@ -31,17 +31,16 @@ package org.hl7.fhir.instance.model; // Generated on Wed, Feb 18, 2015 12:09-0500 for FHIR v0.4.0 -import java.util.*; +import java.util.List; import org.apache.commons.lang3.StringUtils; +import org.hl7.fhir.instance.model.annotations.Child; +import org.hl7.fhir.instance.model.annotations.DatatypeDef; +import org.hl7.fhir.instance.model.annotations.Description; +import org.hl7.fhir.instance.model.api.INarrative; import org.hl7.fhir.utilities.xhtml.XhtmlComposer; import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.hl7.fhir.utilities.xhtml.XhtmlParser; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.instance.model.annotations.Child; -import org.hl7.fhir.instance.model.annotations.Description; -import org.hl7.fhir.instance.model.annotations.DatatypeDef; -import org.hl7.fhir.instance.model.api.INarrative; /** * A human-readable formatted text, including images. */ @@ -158,8 +157,8 @@ public class Narrative extends Element implements INarrative { /** * The actual narrative content, a stripped down version of XHTML. */ -// @Child(name="div", type={}, order=1, min=1, max=1) -// @Description(shortDefinition="Limited xhtml content", formalDefinition="The actual narrative content, a stripped down version of XHTML." ) + @Child(name="div", type={}, order=1, min=1, max=1) + @Description(shortDefinition="Limited xhtml content", formalDefinition="The actual narrative content, a stripped down version of XHTML." ) protected XhtmlNode div; private static final long serialVersionUID = 1463852859L; diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Patient.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Patient.java index 3c9594264b0..8b394fc74e0 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Patient.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Patient.java @@ -31,14 +31,15 @@ package org.hl7.fhir.instance.model; // Generated on Wed, Feb 18, 2015 12:09-0500 for FHIR v0.4.0 -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.instance.model.annotations.ResourceDef; -import org.hl7.fhir.instance.model.annotations.SearchParamDefinition; import org.hl7.fhir.instance.model.annotations.Block; import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Description; +import org.hl7.fhir.instance.model.annotations.ResourceDef; +import org.hl7.fhir.instance.model.annotations.SearchParamDefinition; /** * Demographics and other administrative information about a person or animal receiving care or other health-related services. */ diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Reference.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Reference.java index 64b9fa2083a..c62141905e8 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Reference.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Reference.java @@ -65,7 +65,9 @@ public class Reference extends Type implements IReference, ICompositeType { * Constructor */ public Reference(StringType theReference) { - this.reference = theReference; + if (theReference != null) { + this.reference = new IdType(theReference.getValue()); + } } /** @@ -73,21 +75,21 @@ public class Reference extends Type implements IReference, ICompositeType { */ public Reference(String theReference) { if (StringUtils.isNotBlank(theReference)) { - this.reference = new StringType(theReference); + this.reference = new IdType(theReference); } } /** * This is not a part of the "wire format" resource, but can be changed/accessed by parsers */ - private transient IAnyResource resource; + private transient IBaseResource resource; /** * Retrieves the actual resource referenced by this reference. Note that the resource itself is not * a part of the FHIR "wire format" and is never transmitted or receieved inline, but this property * may be changed/accessed by parsers. */ - public IAnyResource getResource() { + public IBaseResource getResource() { return resource; } @@ -96,7 +98,7 @@ public class Reference extends Type implements IReference, ICompositeType { * a part of the FHIR "wire format" and is never transmitted or receieved inline, but this property * may be changed/accessed by parsers. */ - public void setResource(IAnyResource theResource) { + public void setResource(IBaseResource theResource) { resource = theResource; } @@ -105,7 +107,7 @@ public class Reference extends Type implements IReference, ICompositeType { */ @Child(name = "reference", type = {StringType.class}, order = 0, min = 0, max = 1) @Description(shortDefinition="Relative, internal or absolute URL reference", formalDefinition="A reference to a location at which the other resource is found. The reference may be a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources." ) - protected StringType reference; + protected IdType reference; /** * Plain text narrative that identifies the resource in addition to the resource reference. @@ -119,12 +121,12 @@ public class Reference extends Type implements IReference, ICompositeType { /** * @return {@link #reference} (A reference to a location at which the other resource is found. The reference may be a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.). This is the underlying object with id, value and extensions. The accessor "getReference" gives direct access to the value */ - public StringType getReferenceElement() { + public IdType getReferenceElement() { if (this.reference == null) if (Configuration.errorOnAutoCreate()) throw new Error("Attempt to auto-create Reference.reference"); else if (Configuration.doAutoCreate()) - this.reference = new StringType(); // bb + this.reference = new IdType(); // bb return this.reference; } @@ -139,7 +141,7 @@ public class Reference extends Type implements IReference, ICompositeType { /** * @param value {@link #reference} (A reference to a location at which the other resource is found. The reference may be a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources.). This is the underlying object with id, value and extensions. The accessor "getReference" gives direct access to the value */ - public Reference setReferenceElement(StringType value) { + public Reference setReferenceElement(IdType value) { this.reference = value; return this; } @@ -147,8 +149,8 @@ public class Reference extends Type implements IReference, ICompositeType { /** * @return A reference to a location at which the other resource is found. The reference may be a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources. */ - public String getReference() { - return this.reference == null ? null : this.reference.getValue(); + public IdType getReference() { + return getReferenceElement(); } /** @@ -159,7 +161,7 @@ public class Reference extends Type implements IReference, ICompositeType { this.reference = null; else { if (this.reference == null) - this.reference = new StringType(); + this.reference = new IdType(); this.reference.setValue(value); } return this; @@ -253,7 +255,7 @@ public class Reference extends Type implements IReference, ICompositeType { } public boolean isEmpty() { - return super.isEmpty() && (reference == null || reference.isEmpty()) && (display == null || display.isEmpty()) + return super.isEmpty() && (reference == null || reference.isEmpty()) && (display == null || display.isEmpty()) && resource == null ; } diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Resource.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Resource.java index bcfa6fe669c..ac592f2fbcd 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Resource.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/instance/model/Resource.java @@ -31,15 +31,14 @@ package org.hl7.fhir.instance.model; // Generated on Wed, Feb 18, 2015 12:09-0500 for FHIR v0.4.0 -import java.util.*; +import java.util.List; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.instance.model.annotations.ResourceDef; -import org.hl7.fhir.instance.model.annotations.SearchParamDefinition; -import org.hl7.fhir.instance.model.annotations.Block; import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Description; +import org.hl7.fhir.instance.model.annotations.ResourceDef; import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.utilities.Utilities; /** * Base Resource for everything. */ @@ -111,8 +110,8 @@ public abstract class Resource extends Base implements IAnyResource { /** * @return The logical id of the resource, as used in the url for the resoure. Once assigned, this value never changes. */ - public String getId() { - return this.id == null ? null : this.id.getValue(); + public IdType getId() { + return getIdElement(); // this.id == null ? null : this.id.getValue(); } /** @@ -129,6 +128,14 @@ public abstract class Resource extends Base implements IAnyResource { return this; } + /** + * @param value The logical id of the resource, as used in the url for the resoure. Once assigned, this value never changes. + */ + public Resource setId(IIdType value) { + this.id = (IdType) value; + return this; + } + /** * @return {@link #meta} (The metadata about the resource. This is content that is maintained by the infrastructure. Changes to the content may not always be associated with version changes to the resource.) */ diff --git a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java index 52a8e8588b0..e528b9ba835 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java @@ -33,8 +33,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -//@DatatypeDef() -public class XhtmlNode { +import org.hl7.fhir.instance.model.IPrimitiveType; +import org.hl7.fhir.instance.model.annotations.DatatypeDef; +import org.hl7.fhir.instance.model.api.IBaseXhtml; + +@DatatypeDef(name="xhtml") +public class XhtmlNode implements IBaseXhtml { public static final String NBSP = Character.toString((char)0xa0); @@ -280,7 +284,40 @@ public class XhtmlNode { return e1.equalsDeep(e2); } - public String getValueAsString() throws Exception { - return new XhtmlComposer().compose(this); + public String getValueAsString() { + try { + return new XhtmlComposer().compose(this); + } catch (Exception e) { + // TODO: composer shouldn't throw exception like this + throw new RuntimeException(e); + } + } + + @Override + public void setValueAsString(String theValue) throws IllegalArgumentException { + try { + // TODO: this is ugly + XhtmlNode fragment = new XhtmlParser().parseFragment(theValue); + this.Attributes = fragment.Attributes; + this.childNodes = fragment.childNodes; + this.content = fragment.content; + this.name = fragment.name; + this.nodeType= fragment.nodeType; + } catch (Exception e) { + // TODO: composer shouldn't throw exception like this + throw new RuntimeException(e); + } + + } + + @Override + public String getValue() { + return getValueAsString(); + } + + @Override + public IPrimitiveType setValue(String theValue) throws IllegalArgumentException { + setValueAsString(theValue); + return this; } } diff --git a/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/model/ModelInheritanceTest.java b/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/model/ModelInheritanceTest.java index 85340e98add..304da0046c3 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/model/ModelInheritanceTest.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/model/ModelInheritanceTest.java @@ -12,6 +12,7 @@ import org.hl7.fhir.instance.model.Coding; import org.hl7.fhir.instance.model.DecimalType; import org.hl7.fhir.instance.model.DomainResource; import org.hl7.fhir.instance.model.Element; +import org.hl7.fhir.instance.model.Enumeration; import org.hl7.fhir.instance.model.Extension; import org.hl7.fhir.instance.model.IBase; import org.hl7.fhir.instance.model.ICompositeType; @@ -36,16 +37,20 @@ import org.hl7.fhir.instance.model.api.IBaseBooleanDatatype; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseDatatype; import org.hl7.fhir.instance.model.api.IBaseDecimalDatatype; +import org.hl7.fhir.instance.model.api.IBaseEnumeration; import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.IBaseHasExtensions; import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions; import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype; +import org.hl7.fhir.instance.model.api.IBaseXhtml; import org.hl7.fhir.instance.model.api.ICoding; import org.hl7.fhir.instance.model.api.IDatatypeElement; +import org.hl7.fhir.instance.model.api.IDomainResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IMetaType; import org.hl7.fhir.instance.model.api.INarrative; import org.hl7.fhir.instance.model.api.IReference; +import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.junit.Test; public class ModelInheritanceTest { @@ -78,6 +83,11 @@ public class ModelInheritanceTest { assertTrue(ICompositeType.class.isAssignableFrom(Address.class)); } + @Test + public void testXhtml() { + assertTrue(IBaseXhtml.class.isAssignableFrom(XhtmlNode.class)); + } + @Test public void testBackboneElement() { assertTrue(IBackboneElement.class.isAssignableFrom(BackboneElement.class)); @@ -122,6 +132,7 @@ public class ModelInheritanceTest { public void testDomainResource() { assertTrue(IBaseHasExtensions.class.isAssignableFrom(DomainResource.class)); assertTrue(IBaseHasModifierExtensions.class.isAssignableFrom(DomainResource.class)); + assertTrue(IDomainResource.class.isAssignableFrom(DomainResource.class)); } @Test @@ -129,6 +140,11 @@ public class ModelInheritanceTest { assertTrue(IBaseHasExtensions.class.isAssignableFrom(Element.class)); } + @Test + public void testEnumeration() { + assertTrue(IBaseEnumeration.class.isAssignableFrom(Enumeration.class)); + } + /** * Should be "implements IBaseExtension " */ diff --git a/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java b/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java index b34a4c45c7f..361a3697619 100644 --- a/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java +++ b/hapi-fhir-structures-hl7org-dstu2/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java @@ -77,27 +77,20 @@ public class XmlParserTest { @BeforeClass public static void beforeClass2() { - System.setProperty("file.encoding", "ISO-8859-1"); + System.setProperty("file.encoding", "ISO-8859-1"); } - - @Test - public void testProfileWithBoundCode() throws IOException { - String content = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/DMIXAuditException.xml"), "UTF-8"); - ourCtx.newXmlParser().parseResource(Profile.class, content); - } - + @Test public void testEncodeBinaryWithNoContentType() { Binary b = new Binary(); - b.setContent(new byte[] {1,2,3,4}); - + b.setContent(new byte[] { 1, 2, 3, 4 }); + String output = ourCtx.newXmlParser().encodeResourceToString(b); ourLog.info(output); - + assertEquals(" ", output); } - - + @Test public void testEncodeNonContained() { // Create an organization @@ -110,18 +103,18 @@ public class XmlParserTest { patient.setId("Patient/1333"); patient.addIdentifier().setSystem("urn:mrns").setValue("253345"); patient.getManagingOrganization().setResource(org); - + // Create a list containing both resources. In a server method, you might just // return this list, but here we will create a bundle to encode. List resources = new ArrayList (); resources.add(org); - resources.add(patient); - + resources.add(patient); + // Create a bundle with both Bundle b = new Bundle(); b.addEntry().setResource(org); b.addEntry().setResource(patient); - + // Encode the buntdle String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b); ourLog.info(encoded); @@ -129,13 +122,29 @@ public class XmlParserTest { assertThat(encoded, stringContainsInOrder(" ", " ")); assertThat(encoded, containsString("")); assertThat(encoded, stringContainsInOrder(" ", " ")); - + encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient); ourLog.info(encoded); assertThat(encoded, not(containsString(""))); assertThat(encoded, containsString(" ")); + + } + + @Test + public void testParseNarrative() throws Exception { + //@formatter:off + String htmlNoNs = " AAABBBCCC"; + String htmlNs = htmlNoNs.replace("", ""); + String res= "\n" + + " "; + //@formatter:on - + Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res); + assertEquals(htmlNoNs, p.getText().getDivAsString()); } @Test @@ -150,22 +159,25 @@ public class XmlParserTest { // Create a patient Patient patient = new Patient(); patient.setId("Patient/1333"); - patient.addIdentifier().setSystem("urn:mrns").setValue( "253345"); + patient.addIdentifier().setSystem("urn:mrns").setValue("253345"); patient.getText().setDivAsString("\n" + + " \n" + + " " + htmlNs + "\n" + + " \n" + + "BARFOO"); patient.getManagingOrganization().setResource(org); - + String encoded = parser.encodeResourceToString(patient); ourLog.info(encoded); + + assertThat(encoded, stringContainsInOrder("", " "; //@formatter:on @@ -698,11 +704,13 @@ public class XmlParserTest { Patient patient = ourCtx.newXmlParser().parseResource(Patient.class, msg); assertEquals(NarrativeStatus.GENERATED, patient.getText().getStatus()); - assertEquals("BARFOO", "", " ", " ", " ")); assertThat(encoded, containsString(" ")); - + // Create a bundle with just the patient resource Bundle b = new Bundle(); b.addEntry().setResource(patient); - - // Encode the buntdle + + // Encode the bundle encoded = xmlParser.encodeResourceToString(b); ourLog.info(encoded); - assertThat(encoded, stringContainsInOrder(Arrays.asList(" ","id=\"1\"", " "))); + assertThat(encoded, stringContainsInOrder(Arrays.asList("", " "))); assertThat(encoded, containsString("", " ")); assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " "))); assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", " ", "")))); - + // Re-parse the bundle patient = (Patient) xmlParser.parseResource(xmlParser.encodeResourceToString(patient)); - assertEquals("#1", patient.getManagingOrganization().getReference()); - + assertEquals("#1", patient.getManagingOrganization().getReference().getValue()); + assertNotNull(patient.getManagingOrganization().getResource()); org = (Organization) patient.getManagingOrganization().getResource(); - assertEquals("#1", org.getId()); + assertEquals("#1", org.getId().getValue()); assertEquals("Contained Test Organization", org.getName()); - + // And re-encode a second time encoded = xmlParser.encodeResourceToString(patient); ourLog.info(encoded); - assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " "))); - assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " ", ""))); + assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); assertThat(encoded, containsString(" ")); // And re-encode once more, with the references cleared @@ -216,8 +228,8 @@ public class XmlParserTest { patient.getManagingOrganization().setReference(null); encoded = xmlParser.encodeResourceToString(patient); ourLog.info(encoded); - assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " "))); - assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " ", ""))); + assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); assertThat(encoded, containsString(" ")); // And re-encode once more, with the references cleared and a manually set local ID @@ -226,59 +238,55 @@ public class XmlParserTest { patient.getManagingOrganization().getResource().setId(("#333")); encoded = xmlParser.encodeResourceToString(patient); ourLog.info(encoded); - assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " "))); - assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); - + assertThat(encoded, stringContainsInOrder(Arrays.asList(" ", " ", " ", ""))); + assertThat(encoded, not(stringContainsInOrder(Arrays.asList(" ", " ")))); + } - - + /** * Thanks to Alexander Kley! */ @Test public void testParseContainedBinaryResource() { - byte[] bin = new byte[] {0,1,2,3,4}; - final Binary binary = new Binary(); - binary.setContentType("PatientConsent").setContent( bin); -// binary.setId(UUID.randomUUID().toString()); - - DocumentManifest manifest = new DocumentManifest(); -// manifest.setId(UUID.randomUUID().toString()); - CodeableConcept cc = new CodeableConcept(); - cc.addCoding().setSystem("mySystem").setCode( "PatientDocument"); + byte[] bin = new byte[] { 0, 1, 2, 3, 4 }; + final Binary binary = new Binary(); + binary.setContentType("PatientConsent").setContent(bin); + // binary.setId(UUID.randomUUID().toString()); + + DocumentManifest manifest = new DocumentManifest(); + // manifest.setId(UUID.randomUUID().toString()); + CodeableConcept cc = new CodeableConcept(); + cc.addCoding().setSystem("mySystem").setCode("PatientDocument"); manifest.setType(cc); - manifest.setMasterIdentifier(new Identifier().setSystem("mySystem").setValue( UUID.randomUUID().toString())); - manifest.addContent().setResource(binary); - manifest.setStatus(DocumentReferenceStatus.CURRENT); - - String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(manifest); - ourLog.info(encoded); - assertThat(encoded, StringContainsInOrder.stringContainsInOrder(Arrays.asList("contained>"," "))); - - DocumentManifest actual = ourCtx.newXmlParser().parseResource(DocumentManifest.class, encoded); - assertEquals(1, actual.getContained().size()); - assertEquals(1, actual.getContent().size()); - assertNotNull(actual.getContent().get(0).getResource()); - + manifest.setMasterIdentifier(new Identifier().setSystem("mySystem").setValue(UUID.randomUUID().toString())); + manifest.addContent().setResource(binary); + manifest.setStatus(DocumentReferenceStatus.CURRENT); + + String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(manifest); + ourLog.info(encoded); + assertThat(encoded, StringContainsInOrder.stringContainsInOrder(Arrays.asList("contained>", " "))); + + DocumentManifest actual = ourCtx.newXmlParser().parseResource(DocumentManifest.class, encoded); + assertEquals(1, actual.getContained().size()); + assertEquals(1, actual.getContent().size()); + assertNotNull(actual.getContent().get(0).getResource()); + } - - + @Test public void testComposition() { - + Composition comp = new Composition(); comp.setId("1"); - + ourCtx.newXmlParser().encodeResourceToString(comp); ourCtx.newXmlParser().encodeResourceToString(comp); ourCtx.newXmlParser().encodeResourceToString(comp); ourCtx.newXmlParser().encodeResourceToString(comp); - -// comp. - + + // comp. + } - - @Test public void testEncodeBinaryResource() { @@ -288,7 +296,7 @@ public class XmlParserTest { patient.setContent(new byte[] { 1, 2, 3, 4 }); String val = ourCtx.newXmlParser().encodeResourceToString(patient); - assertEquals(" AQIDBA== ", val); + assertEquals("", val); } @@ -310,7 +318,7 @@ public class XmlParserTest { @Test public void testEncodeBundle() throws InterruptedException { Bundle b = new Bundle(); - b.getMeta().addTag().setSystem("http://hl7.org/fhir/tag").setCode( "http://hl7.org/fhir/tag/message").setDisplay("Message"); + b.getMeta().addTag().setSystem("http://hl7.org/fhir/tag").setCode("http://hl7.org/fhir/tag/message").setDisplay("Message"); InstantType pub = InstantType.withCurrentTime(); b.getMeta().setLastUpdatedElement(pub); @@ -346,7 +354,7 @@ public class XmlParserTest { Bundle b = new Bundle(); BundleEntryComponent e = b.addEntry(); e.setResource(new Patient()); - e.getResource().getMeta().addTag().setSystem("scheme").setCode( "term").setDisplay( "label"); + e.getResource().getMeta().addTag().setSystem("scheme").setCode("term").setDisplay("label"); String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b); ourLog.info(val); @@ -363,7 +371,6 @@ public class XmlParserTest { } - @Test public void testEncodeEscapedChars() { @@ -409,7 +416,7 @@ public class XmlParserTest { DiagnosticReport rpt = new DiagnosticReport(); Specimen spm = new Specimen(); - spm.addIdentifier().setSystem("urn").setValue( "123"); + spm.addIdentifier().setSystem("urn").setValue("123"); rpt.getText().setDivAsString("AAA"); rpt.addSpecimen().setResource(spm); @@ -472,7 +479,7 @@ public class XmlParserTest { Patient patient = new Patient(); patient.addAddress().setUse(AddressUse.HOME); - patient.addExtension().setUrl("urn:foo").setValue( new Reference("Organization/123")); + patient.addExtension().setUrl("urn:foo").setValue(new Reference("Organization/123")); String val = parser.encodeResourceToString(patient); ourLog.info(val); @@ -483,7 +490,7 @@ public class XmlParserTest { List ext = actual.getExtension(); assertEquals(1, ext.size()); Reference ref = (Reference) ext.get(0).getValue(); - assertEquals("Organization/123", ref.getReference()); + assertEquals("Organization/123", ref.getReference().getValue()); } @@ -565,7 +572,6 @@ public class XmlParserTest { } - @Test public void testEncodeResourceRef() throws DataFormatException { @@ -618,7 +624,7 @@ public class XmlParserTest { HumanName name = patient.addName(); name.addFamily("Shmoe"); HumanName given = name.addGiven("Joe"); - Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue( new StringType("Hello")); + Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("Hello")); given.getExtension().add(ext2); String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient); ourLog.info(output); @@ -629,7 +635,7 @@ public class XmlParserTest { Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, new StringReader(enc)); assertEquals(1, parsed.getName().get(0).getExtension().size()); Extension ext = parsed.getName().get(0).getExtension().get(0); - assertEquals("Hello", ((IPrimitiveType>)ext.getValue()).getValue()); + assertEquals("Hello", ((IPrimitiveType>) ext.getValue()).getValue()); } @@ -642,7 +648,7 @@ public class XmlParserTest { StringType family = name.addFamilyElement(); family.setValue("Shmoe"); - Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue( new StringType("Hello")); + Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("Hello")); family.getExtension().add(ext2); String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient); ourLog.info(output); @@ -653,7 +659,7 @@ public class XmlParserTest { Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, new StringReader(enc)); assertEquals(1, parsed.getName().get(0).getFamily().get(0).getExtension().size()); Extension ext = parsed.getName().get(0).getFamily().get(0).getExtension().get(0); - assertEquals("Hello", ((IPrimitiveType>)ext.getValue()).getValue()); + assertEquals("Hello", ((IPrimitiveType>) ext.getValue()).getValue()); } @@ -690,7 +696,7 @@ public class XmlParserTest { + " " + " " + " " - + " " + + " " + " " + " John Cardinal: 444333333", patient.getText().getDiv().getValueAsString()); + assertEquals("John Cardinal: 444333333", patient.getText().getDiv().getValueAsString()); assertEquals("PRP1660", patient.getIdentifier().get(0).getValue()); String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); - + + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient)); + Diff d = new Diff(new StringReader(msg), new StringReader(encoded)); assertTrue(d.toString(), d.identical()); @@ -801,12 +809,12 @@ public class XmlParserTest { Patient resource = (Patient) p.parseResource(msg); assertEquals("IdentifierLabel", resource.getIdentifier().get(0).getLabel()); - assertEquals("Foo1Value", ((IPrimitiveType>)resource.getExtension().get(0).getValue()).getValueAsString()); - assertEquals("Foo1Value2", ((IPrimitiveType>)resource.getExtension().get(1).getValue()).getValueAsString()); - assertEquals("Foo2Value1", ((IPrimitiveType>)resource.getModifierExtension().get(0).getValue()).getValueAsString()); + assertEquals("Foo1Value", ((IPrimitiveType>) resource.getExtension().get(0).getValue()).getValueAsString()); + assertEquals("Foo1Value2", ((IPrimitiveType>) resource.getExtension().get(1).getValue()).getValueAsString()); + assertEquals("Foo2Value1", ((IPrimitiveType>) resource.getModifierExtension().get(0).getValue()).getValueAsString()); - assertEquals("2013-01-01", ((IPrimitiveType>)resource.getExtension().get(2).getExtension().get(0).getValue()).getValueAsString()); - assertEquals("2013-01-02", ((IPrimitiveType>)resource.getExtension().get(2).getExtension().get(1).getExtension().get(0).getValue()).getValueAsString()); + assertEquals("2013-01-01", ((IPrimitiveType>) resource.getExtension().get(2).getExtension().get(0).getValue()).getValueAsString()); + assertEquals("2013-01-02", ((IPrimitiveType>) resource.getExtension().get(2).getExtension().get(1).getExtension().get(0).getValue()).getValueAsString()); String encoded = p.encodeResourceToString(resource); ourLog.info(encoded); @@ -815,51 +823,9 @@ public class XmlParserTest { assertTrue(d.toString(), d.identical()); } - @Test - public void testLoadObservation() throws ConfigurationException, DataFormatException, IOException { - - IParser p = ourCtx.newXmlParser(); - - String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/observation-example-eeg.xml"), Charset.forName("UTF-8")); - IBaseResource resource = p.parseResource(string); - - String result = p.encodeResourceToString(resource); - ourLog.info(result); - } + - @Test - public void testLoadPatient() throws ConfigurationException, DataFormatException, IOException { - - IParser p = ourCtx.newXmlParser(); - - String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/patient-example-dicom.xml"), Charset.forName("UTF-8")); - IBaseResource resource = p.parseResource(string); - - String result = p.encodeResourceToString(resource); - ourLog.info(result); - - // Nothing - - string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/patient-example-us-extensions.xml"), Charset.forName("UTF-8")); - resource = p.parseResource(string); - - result = p.encodeResourceToString(resource); - ourLog.info(result); - - } - - @Test - public void testLoadQuestionnaire() throws ConfigurationException, DataFormatException, IOException { - - IParser p = ourCtx.newXmlParser(); - - String string = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/questionnaire-example.xml"), Charset.forName("UTF-8")); - IBaseResource resource = p.parseResource(string); - - String result = p.encodeResourceToString(resource); - ourLog.info(result); - } @Test public void testReEncode() throws SAXException, IOException { @@ -920,12 +886,10 @@ public class XmlParserTest { String enc = ourCtx.newXmlParser().encodeResourceToString(patient); assertThat(enc, containsString("")); assertThat(enc, containsString(" ")); - assertThat( - enc, - containsString(" ")); + assertThat(enc, containsString(" ")); assertThat(enc, containsString(" ")); assertThat(enc, containsString(" ")); - + /* * Now parse this back */ @@ -964,7 +928,8 @@ public class XmlParserTest { } - @Test + + // Narrative generation not currently supported for HL7org structures public void testNarrativeGeneration() throws DataFormatException, IOException { Patient patient = new Patient(); @@ -998,8 +963,9 @@ public class XmlParserTest { @Override public void setFhirContext(FhirContext theFhirContext) { // nothing - }}; - + } + }; + FhirContext context = new FhirContext(); context.setNarrativeGenerator(gen); IParser p = context.newXmlParser(); @@ -1075,7 +1041,6 @@ public class XmlParserTest { } - @Test public void testParseBundleWithMixedReturnTypes() { InputStreamReader str = new InputStreamReader(getClass().getResourceAsStream("/mixed-return-bundle.xml")); @@ -1141,7 +1106,6 @@ public class XmlParserTest { assertEquals("zh-CN", pt.getLanguage()); } - @Test public void testParseWithXmlHeader() throws ConfigurationException, DataFormatException { IParser p = ourCtx.newXmlParser(); @@ -1217,7 +1181,6 @@ public class XmlParserTest { } - @BeforeClass public static void beforeClass() { XMLUnit.setIgnoreAttributeOrder(true); diff --git a/hapi-fhir-structures-hl7org-dstu2/src/test/resources/example-patient-general.json b/hapi-fhir-structures-hl7org-dstu2/src/test/resources/example-patient-general.json new file mode 100644 index 00000000000..69e05527191 --- /dev/null +++ b/hapi-fhir-structures-hl7org-dstu2/src/test/resources/example-patient-general.json @@ -0,0 +1,149 @@ +{ + "resourceType":"Patient", + "extension":[ + { + "url":"urn:patientext:att", + "valueAttachment":{ + "contentType":"aaaa", + "data":"AAAA" + } + }, + { + "url":"urn:patientext:moreext", + "extension":[ + { + "url":"urn:patientext:moreext:1", + "valueString":"str1" + }, + { + "url":"urn:patientext:moreext:2", + "valueString":"str2" + } + ] + } + ], + "modifierExtension":[ + { + "url":"urn:modext", + "valueDate":"2011-01-02" + } + ], + "text":{ + "status":"generated", + "div":" \n" + }, + "identifier":[ + { + "use":"usual", + "label":"MRN", + "system":"urn:oid:1.2.36.146.595.217.0.1", + "value":"12345", + "period":{ + "start":"2001-05-06" + }, + "assigner":{ + "display":"Acme Healthcare" + } + } + ], + "name":[ + { + "use":"official", + "family":[ + "Chalmers" + ], + "given":[ + "Peter", + "James" + ] + }, + { + "use":"usual", + "given":[ + "Jim" + ] + } + ], + "telecom":[ + { + "use":"home" + }, + { + "system":"phone", + "value":"(03) 5555 6473", + "use":"work" + } + ], + "gender":{ + "coding":[ + { + "system":"http://hl7.org/fhir/v3/AdministrativeGender", + "code":"M", + "display":"Male" + } + ] + }, + "birthDate":"1974-12-25", + "deceasedBoolean":false, + "address":[ + { + "use":"home", + "line":[ + "534 Erewhon St" + ], + "city":"PleasantVille", + "state":"Vic", + "zip":"3999" + }, + { + "use":"old", + "line":[ + "SecondAddress" + ] + } + ], + "contact":[ + { + "relationship":[ + { + "coding":[ + { + "system":"http://hl7.org/fhir/patient-contact-relationship", + "code":"partner" + } + ] + } + ], + "name":{ + "family":[ + "du", + "Marché" + ], + "_family":[ + { + "extension":[ + { + "url":"http://hl7.org/fhir/Profile/iso-21090#qualifier", + "valueCode":"VV" + } + ] + }, + null + ], + "given":[ + "Bénédicte" + ] + }, + "telecom":[ + { + "system":"phone", + "value":"+33 (237) 998327" + } + ] + } + ], + "managingOrganization":{ + "reference":"Organization/1" + }, + "active":true +} \ No newline at end of file\n \n
\n\n \nName \nPeter James Chalmers (\"Jim\") \n\n \nAddress \n534 Erewhon, Pleasantville, Vic, 3999 \n\n \nContacts \nHome: unknown. Work: (03) 5555 6473 \n\n \n \nId \nMRN: 12345 (Acme Healthcare) \n