More work on splitting out resources to different versions

This commit is contained in:
James Agnew 2015-02-13 14:17:44 -05:00
parent 35a2f852fe
commit 86e8103657
41 changed files with 1249 additions and 179 deletions

View File

@ -35,6 +35,7 @@ import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefinition { public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefinition {
@ -106,7 +107,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
} }
if (IBaseResource.class.isAssignableFrom(next)) { if (IBaseResource.class.isAssignableFrom(next)) {
Class<? extends IDatatype> refType = theContext.getVersion().getResourceReferenceType(); Class<? extends BaseResourceReferenceDt> refType = theContext.getVersion().getResourceReferenceType();
myDatatypeToElementDefinition.put(refType, nextDef); myDatatypeToElementDefinition.put(refType, nextDef);
alternateElementName = getElementName() + "Resource"; alternateElementName = getElementName() + "Resource";
myDatatypeToElementName.put(refType, alternateElementName); myDatatypeToElementName.put(refType, alternateElementName);

View File

@ -20,12 +20,13 @@ package ca.uhn.fhir.context;
* #L% * #L%
*/ */
import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.base.composite.BaseContainedDt;
public class RuntimeElemContainedResources extends BaseRuntimeElementDefinition<IDatatype> { public class RuntimeElemContainedResources extends BaseRuntimeElementDefinition<BaseContainedDt> {
public RuntimeElemContainedResources(Class<? extends IDatatype> theClass) { public RuntimeElemContainedResources(Class<? extends BaseContainedDt> theClass) {
super("contained", theClass); super("contained", theClass);
assert BaseContainedDt.class.isAssignableFrom(theClass);
} }
@Override @Override

View File

@ -26,6 +26,8 @@ import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.IServerConformanceProvider; import ca.uhn.fhir.rest.server.IServerConformanceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
@ -44,8 +46,8 @@ public interface IFhirVersion {
String getPathToSchemaDefinitions(); String getPathToSchemaDefinitions();
Class<? extends IDatatype> getResourceReferenceType(); Class<? extends BaseResourceReferenceDt> getResourceReferenceType();
Class<? extends IDatatype> getContainedType(); Class<? extends BaseContainedDt> getContainedType();
} }

View File

@ -1,6 +1,9 @@
package ca.uhn.fhir.model.base.composite; package ca.uhn.fhir.model.base.composite;
import java.util.List;
import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.IResource;
/* /*
* #%L * #%L
@ -24,4 +27,6 @@ import ca.uhn.fhir.model.api.IDatatype;
public abstract class BaseContainedDt implements IDatatype { public abstract class BaseContainedDt implements IDatatype {
public abstract List<? extends IResource> getContainedResources();
} }

View File

@ -2,7 +2,9 @@ package ca.uhn.fhir.model.base.composite;
import ca.uhn.fhir.model.api.BaseIdentifiableElement; import ca.uhn.fhir.model.api.BaseIdentifiableElement;
import ca.uhn.fhir.model.api.ICompositeDatatype; import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.BoundCodeDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
/* /*
* #%L * #%L
@ -24,6 +26,13 @@ import ca.uhn.fhir.model.api.IDatatype;
* #L% * #L%
*/ */
public abstract class BaseNarrativeDt extends BaseIdentifiableElement implements ICompositeDatatype { /**
* @param <T> The narrative status enum type
*/
public abstract class BaseNarrativeDt<T extends Enum<?>> extends BaseIdentifiableElement implements ICompositeDatatype {
public abstract BoundCodeDt<T> getStatus();
public abstract XhtmlDt getDiv();
} }

View File

@ -22,6 +22,9 @@ package ca.uhn.fhir.model.base.composite;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.List;
import javax.json.JsonValue;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
@ -32,6 +35,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.BaseIdentifiableElement; import ca.uhn.fhir.model.api.BaseIdentifiableElement;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.BaseClient; import ca.uhn.fhir.rest.client.BaseClient;
import ca.uhn.fhir.rest.client.api.IRestfulClient; import ca.uhn.fhir.rest.client.api.IRestfulClient;
@ -59,14 +63,15 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement {
setReference(theResource.getId()); setReference(theResource.getId());
} }
public abstract StringDt getDisplayElement();
public abstract IdDt getReference(); public abstract IdDt getReference();
/** /**
* Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This method will return the resource instance only if it has previously been loaded using * Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This method will return the resource instance only if it has previously been loaded using
* {@link #loadResource(IRestfulClient)} or it was contained within the resource containing this resource. * {@link #loadResource(IRestfulClient)} or it was contained within the resource containing this resource.
* *
* See the FHIR specification section on <a href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> * See the FHIR specification section on <a href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> for more information.
* for more information.
* *
* @see #loadResource(IRestfulClient) * @see #loadResource(IRestfulClient)
*/ */

View File

@ -1,12 +1,18 @@
package ca.uhn.fhir.model.base.resource; package ca.uhn.fhir.model.base.resource;
import ca.uhn.fhir.model.api.BaseResource;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
public abstract class BaseBinary extends BaseResource implements IResource { public interface BaseBinary extends IResource {
public abstract byte[] getContent(); byte[] getContent();
public abstract String getContentType(); String getContentAsBase64();
String getContentType();
void setContent(byte[] theContent);
void setContentAsBase64(String theContent);
void setContentType(String theContentType);
} }

View File

@ -20,13 +20,12 @@ package ca.uhn.fhir.model.base.resource;
* #L% * #L%
*/ */
import ca.uhn.fhir.model.api.BaseResource;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
//@ResourceDef(name="Conformance") //@ResourceDef(name="Conformance")
public abstract class BaseConformance extends BaseResource implements IResource { public interface BaseConformance extends IResource {
public abstract StringDt getDescriptionElement(); public abstract StringDt getDescriptionElement();

View File

@ -23,14 +23,13 @@ package ca.uhn.fhir.model.base.resource;
import java.util.List; import java.util.List;
import ca.uhn.fhir.model.api.BaseIdentifiableElement; import ca.uhn.fhir.model.api.BaseIdentifiableElement;
import ca.uhn.fhir.model.api.BaseResource;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.IResourceBlock; import ca.uhn.fhir.model.api.IResourceBlock;
import ca.uhn.fhir.model.base.composite.BaseCodingDt; import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.primitive.CodeDt; import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
public abstract class BaseOperationOutcome extends BaseResource implements IResource { public interface BaseOperationOutcome extends IResource {
public abstract BaseIssue addIssue(); public abstract BaseIssue addIssue();

View File

@ -20,9 +20,8 @@ package ca.uhn.fhir.model.base.resource;
* #L% * #L%
*/ */
import ca.uhn.fhir.model.api.BaseResource;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
public abstract class BaseSecurityEvent extends BaseResource implements IResource { public interface BaseSecurityEvent extends IResource {
} }

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.narrative;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -63,9 +63,7 @@ import org.thymeleaf.templateresolver.TemplateResolver;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt; import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGenerator { public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGenerator {
@ -94,8 +92,8 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
} }
@Override @Override
public NarrativeDt generateNarrative(IBaseResource theResource) { public void generateNarrative(IBaseResource theResource, BaseNarrativeDt<?> theNarrative) {
return generateNarrative( null, theResource); generateNarrative(null, theResource, theNarrative);
} }
@Override @Override
@ -110,7 +108,7 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
} }
@Override @Override
public NarrativeDt generateNarrative(String theProfile, IBaseResource theResource) { public void generateNarrative(String theProfile, IBaseResource theResource, BaseNarrativeDt<?> theNarrative) {
if (!myInitialized) { if (!myInitialized) {
initialize(); initialize();
} }
@ -129,7 +127,9 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
if (name == null) { if (name == null) {
if (myIgnoreMissingTemplates) { if (myIgnoreMissingTemplates) {
ourLog.debug("No narrative template available for profile: {}", theProfile); ourLog.debug("No narrative template available for profile: {}", theProfile);
return new NarrativeDt(new XhtmlDt("<div>No narrative template available for resource profile: " + theProfile + "</div>"), NarrativeStatusEnum.EMPTY); theNarrative.getDiv().setValueAsString("<div>No narrative template available for resource profile: " + theProfile + "</div>");
theNarrative.getStatus().setValueAsString("empty");
return;
} else { } else {
throw new DataFormatException("No narrative template for class " + theResource.getClass().getCanonicalName()); throw new DataFormatException("No narrative template for class " + theResource.getClass().getCanonicalName());
} }
@ -147,12 +147,15 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
ourLog.trace("Post-whitespace cleaning: ", result); ourLog.trace("Post-whitespace cleaning: ", result);
} }
XhtmlDt div = new XhtmlDt(result); theNarrative.getDiv().setValueAsString(result);
return new NarrativeDt(div, NarrativeStatusEnum.GENERATED); theNarrative.getStatus().setValueAsString("generated");
return;
} catch (Exception e) { } catch (Exception e) {
if (myIgnoreFailures) { if (myIgnoreFailures) {
ourLog.error("Failed to generate narrative", e); ourLog.error("Failed to generate narrative", e);
return new NarrativeDt(new XhtmlDt("<div>No narrative available - Error: " + e.getMessage() + "</div>"), NarrativeStatusEnum.EMPTY); theNarrative.getDiv().setValueAsString("<div>No narrative available - Error: " + e.getMessage() + "</div>");
theNarrative.getStatus().setValueAsString("empty");
return;
} else { } else {
throw new DataFormatException(e); throw new DataFormatException(e);
} }

View File

@ -23,14 +23,14 @@ package ca.uhn.fhir.narrative;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt; import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
public interface INarrativeGenerator { public interface INarrativeGenerator {
NarrativeDt generateNarrative(String theProfile, IBaseResource theResource) throws DataFormatException; void generateNarrative(String theProfile, IBaseResource theResource, BaseNarrativeDt<?> theNarrative) throws DataFormatException;
NarrativeDt generateNarrative(IBaseResource theResource); void generateNarrative(IBaseResource theResource, BaseNarrativeDt<?> theNarrative);
String generateTitle(IBaseResource theResource); String generateTitle(IBaseResource theResource);

View File

@ -51,7 +51,7 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
public abstract class BaseParser implements IParser { public abstract class BaseParser implements IParser {
@ -120,8 +120,8 @@ public abstract class BaseParser implements IParser {
} }
{ {
List<ResourceReferenceDt> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, ResourceReferenceDt.class); List<BaseResourceReferenceDt> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, BaseResourceReferenceDt.class);
for (ResourceReferenceDt next : allElements) { for (BaseResourceReferenceDt next : allElements) {
IResource resource = next.getResource(); IResource resource = next.getResource();
if (resource != null) { if (resource != null) {
if (resource.getId().isEmpty() || resource.getId().isLocal()) { if (resource.getId().isEmpty() || resource.getId().isLocal()) {
@ -279,7 +279,7 @@ public abstract class BaseParser implements IParser {
throw new DataFormatException(nextChild + " has no child of type " + theType); throw new DataFormatException(nextChild + " has no child of type " + theType);
} }
protected String determineReferenceText(ResourceReferenceDt theRef) { protected String determineReferenceText(BaseResourceReferenceDt theRef) {
String reference = theRef.getReference().getValue(); String reference = theRef.getReference().getValue();
if (isBlank(reference)) { if (isBlank(reference)) {
if (theRef.getResource() != null) { if (theRef.getResource() != null) {

View File

@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
@ -78,10 +80,10 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.dstu.composite.ContainedDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt; import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Binary; import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.DecimalDt; import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -387,7 +389,7 @@ public class JsonParser extends BaseParser implements IParser {
break; break;
} }
case RESOURCE_REF: { case RESOURCE_REF: {
ResourceReferenceDt referenceDt = (ResourceReferenceDt) theNextValue; BaseResourceReferenceDt referenceDt = (BaseResourceReferenceDt) theNextValue;
if (theChildName != null) { if (theChildName != null) {
theWriter.writeStartObject(theChildName); theWriter.writeStartObject(theChildName);
} else { } else {
@ -399,8 +401,8 @@ public class JsonParser extends BaseParser implements IParser {
if (StringUtils.isNotBlank(reference)) { if (StringUtils.isNotBlank(reference)) {
theWriter.write(XmlParser.RESREF_REFERENCE, reference); theWriter.write(XmlParser.RESREF_REFERENCE, reference);
} }
if (referenceDt.getDisplay().isEmpty() == false) { if (referenceDt.getDisplayElement().isEmpty() == false) {
theWriter.write(XmlParser.RESREF_DISPLAY, referenceDt.getDisplay().getValueAsString()); theWriter.write(XmlParser.RESREF_DISPLAY, referenceDt.getDisplayElement().getValueAsString());
} }
theWriter.writeEnd(); theWriter.writeEnd();
break; break;
@ -455,7 +457,8 @@ public class JsonParser extends BaseParser implements IParser {
INarrativeGenerator gen = myContext.getNarrativeGenerator(); INarrativeGenerator gen = myContext.getNarrativeGenerator();
if (gen != null) { if (gen != null) {
NarrativeDt narr = gen.generateNarrative(theResDef.getResourceProfile(), theResource); BaseNarrativeDt<?> narr = ((IResource)theResource).getText();
gen.generateNarrative(theResDef.getResourceProfile(), theResource, narr);
if (narr != null) { if (narr != null) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
String childName = nextChild.getChildNameByDatatype(child.getDatatype()); String childName = nextChild.getChildNameByDatatype(child.getDatatype());
@ -480,7 +483,7 @@ public class JsonParser extends BaseParser implements IParser {
int valueIdx = 0; int valueIdx = 0;
for (IBase nextValue : values) { for (IBase nextValue : values) {
if (nextValue == null || nextValue.isEmpty()) { if (nextValue == null || nextValue.isEmpty()) {
if (nextValue instanceof ContainedDt) { if (nextValue instanceof BaseContainedDt) {
if (theIsSubElementWithinResource || getContainedResources().isEmpty()) { if (theIsSubElementWithinResource || getContainedResources().isEmpty()) {
continue; continue;
} }
@ -646,8 +649,8 @@ public class JsonParser extends BaseParser implements IParser {
} }
} }
if (theResource instanceof Binary) { if (theResource instanceof BaseBinary) {
Binary bin = (Binary) theResource; BaseBinary bin = (BaseBinary) theResource;
theEventWriter.write("contentType", bin.getContentType()); theEventWriter.write("contentType", bin.getContentType());
theEventWriter.write("content", bin.getContentAsBase64()); theEventWriter.write("content", bin.getContentAsBase64());
} else { } else {

View File

@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -40,6 +42,7 @@ import org.hl7.fhir.instance.model.IPrimitiveType;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition; import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
@ -64,10 +67,10 @@ import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap; import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@ -718,8 +721,8 @@ class ParserState<T> {
} }
for (IResource next : resources) { for (IResource next : resources) {
List<ResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, ResourceReferenceDt.class); List<BaseResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, BaseResourceReferenceDt.class);
for (ResourceReferenceDt nextRef : refs) { for (BaseResourceReferenceDt nextRef : refs) {
if (nextRef.isEmpty() == false && nextRef.getReference() != null) { if (nextRef.isEmpty() == false && nextRef.getReference() != null) {
IResource target = idToResource.get(nextRef.getReference().getValue()); IResource target = idToResource.get(nextRef.getReference().getValue());
if (target != null) { if (target != null) {
@ -816,10 +819,10 @@ class ParserState<T> {
private static final int SUBSTATE_CONTENT = 2; private static final int SUBSTATE_CONTENT = 2;
private static final int SUBSTATE_CT = 1; private static final int SUBSTATE_CT = 1;
private String myData; private String myData;
private Binary myInstance; private BaseBinary myInstance;
private int mySubState = 0; private int mySubState = 0;
public BinaryResourceStateForDstu1(PreResourceState thePreResourceState, Binary theInstance) { public BinaryResourceStateForDstu1(PreResourceState thePreResourceState, BaseBinary theInstance) {
super(thePreResourceState); super(thePreResourceState);
myInstance = theInstance; myInstance = theInstance;
} }
@ -1286,7 +1289,10 @@ class ParserState<T> {
} }
} }
IResource preResCurrentElement = (IResource) getPreResourceState().getCurrentElement(); IResource preResCurrentElement = (IResource) getPreResourceState().getCurrentElement();
preResCurrentElement.getContained().getContainedResources().add(res);
@SuppressWarnings("unchecked")
List<IResource> containedResources = (List<IResource>) preResCurrentElement.getContained().getContainedResources();
containedResources.add(res);
} }
@ -1336,7 +1342,7 @@ class ParserState<T> {
return; return;
} }
case RESOURCE_REF: { case RESOURCE_REF: {
ResourceReferenceDt newChildInstance = new ResourceReferenceDt(); BaseResourceReferenceDt newChildInstance = newResourceReferenceDt();
myDefinition.getMutator().addValue(myParentInstance, newChildInstance); myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance); ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
push(newState); push(newState);
@ -1352,6 +1358,7 @@ class ParserState<T> {
} }
} }
@Override @Override
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) { public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr); RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr);
@ -1374,6 +1381,18 @@ class ParserState<T> {
} }
private BaseResourceReferenceDt newResourceReferenceDt() {
BaseResourceReferenceDt newChildInstance;
try {
newChildInstance = (BaseResourceReferenceDt) myContext.getVersion().getResourceReferenceType().newInstance();
} catch (InstantiationException e) {
throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e);
}
return newChildInstance;
}
private class ElementCompositeState<T2 extends IBase> extends BaseState { private class ElementCompositeState<T2 extends IBase> extends BaseState {
private BaseRuntimeElementCompositeDefinition<?> myDefinition; private BaseRuntimeElementCompositeDefinition<?> myDefinition;
@ -1447,7 +1466,7 @@ class ParserState<T> {
} }
case RESOURCE_REF: { case RESOURCE_REF: {
RuntimeResourceReferenceDefinition resourceRefTarget = (RuntimeResourceReferenceDefinition) target; RuntimeResourceReferenceDefinition resourceRefTarget = (RuntimeResourceReferenceDefinition) target;
ResourceReferenceDt newChildInstance = new ResourceReferenceDt(); BaseResourceReferenceDt newChildInstance = newResourceReferenceDt();
getPreResourceState().getResourceReferences().add(newChildInstance); getPreResourceState().getResourceReferences().add(newChildInstance);
child.getMutator().addValue(myInstance, newChildInstance); child.getMutator().addValue(myInstance, newChildInstance);
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance); ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
@ -1473,12 +1492,12 @@ class ParserState<T> {
case CONTAINED_RESOURCES: { case CONTAINED_RESOURCES: {
RuntimeElemContainedResources targetElem = (RuntimeElemContainedResources) target; RuntimeElemContainedResources targetElem = (RuntimeElemContainedResources) target;
List<? extends IBase> values = child.getAccessor().getValues(myInstance); List<? extends IBase> values = child.getAccessor().getValues(myInstance);
ContainedDt newDt; BaseContainedDt newDt;
if (values == null || values.isEmpty() || values.get(0) == null) { if (values == null || values.isEmpty() || values.get(0) == null) {
newDt = targetElem.newInstance(); newDt = targetElem.newInstance();
child.getMutator().addValue(myInstance, newDt); child.getMutator().addValue(myInstance, newDt);
} else { } else {
newDt = (ContainedDt) values.get(0); newDt = (BaseContainedDt) values.get(0);
} }
ContainedResourcesState state = new ContainedResourcesState(getPreResourceState()); ContainedResourcesState state = new ContainedResourcesState(getPreResourceState());
push(state); push(state);
@ -1555,7 +1574,7 @@ class ParserState<T> {
return; return;
} }
case RESOURCE_REF: { case RESOURCE_REF: {
ResourceReferenceDt newChildInstance = new ResourceReferenceDt(); BaseResourceReferenceDt newChildInstance = newResourceReferenceDt();
myExtension.setValue(newChildInstance); myExtension.setValue(newChildInstance);
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance); ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
push(newState); push(newState);
@ -1707,7 +1726,7 @@ class ParserState<T> {
private Map<String, IBaseResource> myContainedResources = new HashMap<String, IBaseResource>(); private Map<String, IBaseResource> myContainedResources = new HashMap<String, IBaseResource>();
private BundleEntry myEntry; private BundleEntry myEntry;
private IResource myInstance; private IResource myInstance;
private List<ResourceReferenceDt> myResourceReferences = new ArrayList<ResourceReferenceDt>(); private List<BaseResourceReferenceDt> myResourceReferences = new ArrayList<BaseResourceReferenceDt>();
private Class<? extends IBaseResource> myResourceType; private Class<? extends IBaseResource> myResourceType;
public PreResourceState(BundleEntry theEntry, Class<? extends IBaseResource> theResourceType) { public PreResourceState(BundleEntry theEntry, Class<? extends IBaseResource> theResourceType) {
@ -1760,7 +1779,7 @@ class ParserState<T> {
String resourceName = def.getName(); String resourceName = def.getName();
if ("Binary".equals(resourceName) && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) { if ("Binary".equals(resourceName) && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
push(new BinaryResourceStateForDstu1(getRootPreResourceState(), (Binary) myInstance)); push(new BinaryResourceStateForDstu1(getRootPreResourceState(), (BaseBinary) myInstance));
} else { } else {
push(new ResourceState(getRootPreResourceState(), def, myInstance)); push(new ResourceState(getRootPreResourceState(), def, myInstance));
} }
@ -1775,7 +1794,7 @@ class ParserState<T> {
return myInstance; return myInstance;
} }
public List<ResourceReferenceDt> getResourceReferences() { public List<BaseResourceReferenceDt> getResourceReferences() {
return myResourceReferences; return myResourceReferences;
} }
@ -1803,8 +1822,8 @@ class ParserState<T> {
@Override @Override
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) { public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement instanceof ResourceReferenceDt) { if (theElement instanceof BaseResourceReferenceDt) {
ResourceReferenceDt nextRef = (ResourceReferenceDt) theElement; BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
String ref = nextRef.getReference().getValue(); String ref = nextRef.getReference().getValue();
if (isNotBlank(ref)) { if (isNotBlank(ref)) {
if (ref.startsWith("#")) { if (ref.startsWith("#")) {
@ -1928,10 +1947,10 @@ class ParserState<T> {
private class ResourceReferenceState extends BaseState { private class ResourceReferenceState extends BaseState {
private ResourceReferenceDt myInstance; private BaseResourceReferenceDt myInstance;
private ResourceReferenceSubState mySubState; private ResourceReferenceSubState mySubState;
public ResourceReferenceState(PreResourceState thePreResourceState, ResourceReferenceDt theInstance) { public ResourceReferenceState(PreResourceState thePreResourceState, BaseResourceReferenceDt theInstance) {
super(thePreResourceState); super(thePreResourceState);
myInstance = theInstance; myInstance = theInstance;
mySubState = ResourceReferenceSubState.INITIAL; mySubState = ResourceReferenceSubState.INITIAL;
@ -1945,12 +1964,12 @@ class ParserState<T> {
switch (mySubState) { switch (mySubState) {
case DISPLAY: case DISPLAY:
myInstance.setDisplay(theValue); myInstance.getDisplayElement().setValue(theValue);
break; break;
case INITIAL: case INITIAL:
throw new DataFormatException("Unexpected attribute: " + theValue); throw new DataFormatException("Unexpected attribute: " + theValue);
case REFERENCE: case REFERENCE:
myInstance.setReference(theValue); myInstance.getReference().setValue(theValue);
break; break;
} }
} }

View File

@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
@ -72,10 +74,10 @@ import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu.composite.ContainedDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt; import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Binary; import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@ -463,7 +465,7 @@ public class XmlParser extends BaseParser implements IParser {
break; break;
} }
case RESOURCE_REF: { case RESOURCE_REF: {
ResourceReferenceDt ref = (ResourceReferenceDt) nextValue; BaseResourceReferenceDt ref = (BaseResourceReferenceDt) nextValue;
if (!ref.isEmpty()) { if (!ref.isEmpty()) {
theEventWriter.writeStartElement(childName); theEventWriter.writeStartElement(childName);
encodeResourceReferenceToStreamWriter(theEventWriter, ref); encodeResourceReferenceToStreamWriter(theEventWriter, ref);
@ -472,7 +474,7 @@ public class XmlParser extends BaseParser implements IParser {
break; break;
} }
case CONTAINED_RESOURCES: { case CONTAINED_RESOURCES: {
ContainedDt value = (ContainedDt) nextValue; BaseContainedDt value = (BaseContainedDt) nextValue;
/* /*
* Disable per #103 for (IResource next : value.getContainedResources()) { if * Disable per #103 for (IResource next : value.getContainedResources()) { if
* (getContainedResources().getResourceId(next) != null) { continue; } * (getContainedResources().getResourceId(next) != null) { continue; }
@ -511,11 +513,11 @@ public class XmlParser extends BaseParser implements IParser {
if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) { if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) {
INarrativeGenerator gen = myContext.getNarrativeGenerator(); INarrativeGenerator gen = myContext.getNarrativeGenerator();
if (theResource instanceof IResource) { if (theResource instanceof IResource) {
NarrativeDt narr = ((IResource) theResource).getText(); BaseNarrativeDt<?> narr = ((IResource) theResource).getText();
if (gen != null && narr.isEmpty()) { if (gen != null && narr.isEmpty()) {
narr = gen.generateNarrative(theResDef.getResourceProfile(), theResource); gen.generateNarrative(theResDef.getResourceProfile(), theResource, narr);
} }
if (narr != null) { if (narr.isEmpty()==false) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
String childName = nextChild.getChildNameByDatatype(child.getDatatype()); String childName = nextChild.getChildNameByDatatype(child.getDatatype());
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName); BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
@ -524,9 +526,10 @@ public class XmlParser extends BaseParser implements IParser {
} }
} else { } else {
Narrative narr1 = ((DomainResource) theResource).getText(); Narrative narr1 = ((DomainResource) theResource).getText();
NarrativeDt narr2 = null; BaseNarrativeDt<?> narr2 = null;
if (gen != null && narr1.isEmpty()) { if (gen != null && narr1.isEmpty()) {
narr2 = gen.generateNarrative(theResDef.getResourceProfile(), theResource); // TODO: need to implement this
gen.generateNarrative(theResDef.getResourceProfile(), theResource, null);
} }
if (narr2 != null) { if (narr2 != null) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
@ -544,7 +547,7 @@ public class XmlParser extends BaseParser implements IParser {
} }
for (IBase nextValue : values) { for (IBase nextValue : values) {
if ((nextValue == null || nextValue.isEmpty()) && !(nextValue instanceof ContainedDt)) { if ((nextValue == null || nextValue.isEmpty()) && !(nextValue instanceof BaseContainedDt)) {
continue; continue;
} }
Class<? extends IBase> type = nextValue.getClass(); Class<? extends IBase> type = nextValue.getClass();
@ -594,7 +597,7 @@ public class XmlParser extends BaseParser implements IParser {
} }
} }
private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, ResourceReferenceDt theRef) throws XMLStreamException { private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, BaseResourceReferenceDt theRef) throws XMLStreamException {
String reference = determineReferenceText(theRef); String reference = determineReferenceText(theRef);
if (StringUtils.isNotBlank(reference)) { if (StringUtils.isNotBlank(reference)) {
@ -602,9 +605,9 @@ public class XmlParser extends BaseParser implements IParser {
theEventWriter.writeAttribute("value", reference); theEventWriter.writeAttribute("value", reference);
theEventWriter.writeEndElement(); theEventWriter.writeEndElement();
} }
if (!(theRef.getDisplay().isEmpty())) { if (!(theRef.getDisplayElement().isEmpty())) {
theEventWriter.writeStartElement(RESREF_DISPLAY); theEventWriter.writeStartElement(RESREF_DISPLAY);
theEventWriter.writeAttribute("value", theRef.getDisplay().getValue()); theEventWriter.writeAttribute("value", theRef.getDisplayElement().getValue());
theEventWriter.writeEndElement(); theEventWriter.writeEndElement();
} }
} }
@ -718,8 +721,8 @@ public class XmlParser extends BaseParser implements IParser {
} }
if (theResource instanceof Binary) { if (theResource instanceof BaseBinary) {
Binary bin = (Binary) theResource; BaseBinary bin = (BaseBinary) theResource;
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) { if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
writeOptionalTagWithValue(theEventWriter, "contentType", bin.getContentType()); writeOptionalTagWithValue(theEventWriter, "contentType", bin.getContentType());
writeOptionalTagWithValue(theEventWriter, "content", bin.getContentAsBase64()); writeOptionalTagWithValue(theEventWriter, "content", bin.getContentAsBase64());

View File

@ -30,9 +30,7 @@ import org.hl7.fhir.instance.model.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Binary; import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.rest.annotation.ResourceParam; import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ResourceParameter; import ca.uhn.fhir.rest.param.ResourceParameter;
@ -65,7 +63,7 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
providerResourceType = ((IResourceProvider) theProvider).getResourceType(); providerResourceType = ((IResourceProvider) theProvider).getResourceType();
} }
if (providerResourceType.isAssignableFrom(Binary.class)) { if (providerResourceType.isAssignableFrom(BaseBinary.class)) {
myBinary = true; myBinary = true;
} }
@ -97,7 +95,12 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
if (myBinary) { if (myBinary) {
String ct = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE); String ct = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
byte[] contents = IOUtils.toByteArray(theRequest.getServletRequest().getInputStream()); byte[] contents = IOUtils.toByteArray(theRequest.getServletRequest().getInputStream());
return new Binary(ct, contents);
BaseBinary binary = (BaseBinary) getContext().getResourceDefinition("Binary").newInstance();
binary.setContentType(ct);
binary.setContent(contents);
return binary;
} else { } else {
return super.parseIncomingServerResource(theRequest); return super.parseIncomingServerResource(theRequest);
} }

View File

@ -36,7 +36,7 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Binary; import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum; import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum; import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -168,7 +168,10 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
@Override @Override
public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException { public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
byte[] contents = IOUtils.toByteArray(theResponseReader); byte[] contents = IOUtils.toByteArray(theResponseReader);
Binary resource = new Binary(theResponseMimeType, contents);
BaseBinary resource = (BaseBinary) getContext().getResourceDefinition("Binary").newInstance();
resource.setContentType(theResponseMimeType);
resource.setContent(contents);
switch (getMethodReturnType()) { switch (getMethodReturnType()) {
case BUNDLE: case BUNDLE:

View File

@ -43,7 +43,7 @@ import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.base.composite.BaseCodingDt; import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.CodeDt; import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@ -345,7 +345,7 @@ public class InternalCodingDt
* The set of possible coded values this coding was chosen from or constrained by * The set of possible coded values this coding was chosen from or constrained by
* </p> * </p>
*/ */
public ResourceReferenceDt getValueSet() { public BaseResourceReferenceDt getValueSet() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -357,7 +357,7 @@ public class InternalCodingDt
* The set of possible coded values this coding was chosen from or constrained by * The set of possible coded values this coding was chosen from or constrained by
* </p> * </p>
*/ */
public InternalCodingDt setValueSet(ResourceReferenceDt theValue) { public InternalCodingDt setValueSet(BaseResourceReferenceDt theValue) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.rest.server;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
@ -30,7 +30,6 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -52,7 +51,6 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
@ -68,10 +66,10 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue; import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
@ -1177,11 +1175,11 @@ public class RestfulServer extends HttpServlet {
ourLog.trace("No narrative generator specified"); ourLog.trace("No narrative generator specified");
} }
List<ResourceReferenceDt> references = theContext.newTerser().getAllPopulatedChildElementsOfType(next, ResourceReferenceDt.class); List<BaseResourceReferenceDt> references = theContext.newTerser().getAllPopulatedChildElementsOfType(next, BaseResourceReferenceDt.class);
do { do {
List<IResource> addedResourcesThisPass = new ArrayList<IResource>(); List<IResource> addedResourcesThisPass = new ArrayList<IResource>();
for (ResourceReferenceDt nextRef : references) { for (BaseResourceReferenceDt nextRef : references) {
IResource nextRes = nextRef.getResource(); IResource nextRes = nextRef.getResource();
if (nextRes != null) { if (nextRes != null) {
if (nextRes.getId().hasIdPart()) { if (nextRes.getId().hasIdPart()) {
@ -1206,9 +1204,9 @@ public class RestfulServer extends HttpServlet {
} }
// Linked resources may themselves have linked resources // Linked resources may themselves have linked resources
references = new ArrayList<ResourceReferenceDt>(); references = new ArrayList<BaseResourceReferenceDt>();
for (IResource iResource : addedResourcesThisPass) { for (IResource iResource : addedResourcesThisPass) {
List<ResourceReferenceDt> newReferences = theContext.newTerser().getAllPopulatedChildElementsOfType(iResource, ResourceReferenceDt.class); List<BaseResourceReferenceDt> newReferences = theContext.newTerser().getAllPopulatedChildElementsOfType(iResource, BaseResourceReferenceDt.class);
references.addAll(newReferences); references.addAll(newReferences);
} }
@ -1449,8 +1447,8 @@ public class RestfulServer extends HttpServlet {
} }
} }
if (theResource instanceof Binary) { if (theResource instanceof BaseBinary) {
Binary bin = (Binary) theResource; BaseBinary bin = (BaseBinary) theResource;
if (isNotBlank(bin.getContentType())) { if (isNotBlank(bin.getContentType())) {
theHttpResponse.setContentType(bin.getContentType()); theHttpResponse.setContentType(bin.getContentType());
} else { } else {

View File

@ -40,8 +40,8 @@ import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions; import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.model.dstu.composite.ContainedDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
@ -73,7 +73,7 @@ public class FhirTerser {
* </p> * </p>
* <p> * <p>
* Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, but will not decend into linked resources (e.g. * Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, but will not decend into linked resources (e.g.
* {@link ResourceReferenceDt#getResource()}) * {@link BaseResourceReferenceDt#getResource()})
* </p> * </p>
* *
* @param theResource * @param theResource
@ -196,7 +196,7 @@ public class FhirTerser {
// These are primitive types // These are primitive types
break; break;
case RESOURCE_REF: case RESOURCE_REF:
ResourceReferenceDt resRefDt = (ResourceReferenceDt) theElement; BaseResourceReferenceDt resRefDt = (BaseResourceReferenceDt) theElement;
if (resRefDt.getReference().getValue() == null && resRefDt.getResource() != null) { if (resRefDt.getReference().getValue() == null && resRefDt.getResource() != null) {
IResource theResource = resRefDt.getResource(); IResource theResource = resRefDt.getResource();
if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) { if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) {
@ -246,7 +246,7 @@ public class FhirTerser {
break; break;
} }
case CONTAINED_RESOURCES: { case CONTAINED_RESOURCES: {
ContainedDt value = (ContainedDt) theElement; BaseContainedDt value = (BaseContainedDt) theElement;
for (IResource next : value.getContainedResources()) { for (IResource next : value.getContainedResources()) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next); BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next);
visit(next, null, def, theCallback); visit(next, null, def, theCallback);

View File

@ -0,0 +1,162 @@
package ca.uhn.fhir.model.api;
/*
* #%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 org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.SearchParamDefinition;
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
import ca.uhn.fhir.model.dev.composite.ContainedDt;
import ca.uhn.fhir.model.dev.composite.NarrativeDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.util.ElementUtil;
public abstract class BaseResource extends BaseElement implements IResource {
/**
* Search parameter constant for <b>_language</b>
*/
@SearchParamDefinition(name="_language", path="", description="The language of the resource", type="string" )
public static final String SP_RES_LANGUAGE = "_language";
/**
* Search parameter constant for <b>_id</b>
*/
@SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" )
public static final String SP_RES_ID = "_id";
/**
* <b>Fluent Client</b> search parameter constant for <b>_id</b>
* <p>
* Description: <b>the _id of a resource</b><br>
* Type: <b>string</b><br>
* Path: <b>Resource._id</b><br>
* </p>
*/
public static final StringClientParam RES_ID = new StringClientParam(BaseResource.SP_RES_ID);
@Child(name = "contained", order = 2, min = 0, max = 1)
private ContainedDt myContained;
private IdDt myId;
@Child(name = "language", order = 0, min = 0, max = Child.MAX_UNLIMITED)
private CodeDt myLanguage;
private ResourceMetadataMap myResourceMetadata;
@Child(name = "text", order = 1, min = 0, max = 1)
private NarrativeDt myText;
@Override
public ContainedDt getContained() {
if (myContained == null) {
myContained = new ContainedDt();
}
return myContained;
}
public IdDt getId() {
if (myId == null) {
myId = new IdDt();
}
return myId;
}
@Override
public CodeDt getLanguage() {
if (myLanguage == null) {
myLanguage = new CodeDt();
}
return myLanguage;
}
@Override
public ResourceMetadataMap getResourceMetadata() {
if (myResourceMetadata == null) {
myResourceMetadata = new ResourceMetadataMap();
}
return myResourceMetadata;
}
@Override
public NarrativeDt getText() {
if (myText == null) {
myText = new NarrativeDt();
}
return myText;
}
public void setContained(ContainedDt theContained) {
myContained = theContained;
}
public void setId(IdDt theId) {
myId = theId;
}
public void setId(String theId) {
if (theId == null) {
myId = null;
} else {
myId = new IdDt(theId);
}
}
@Override
public void setLanguage(CodeDt theLanguage) {
myLanguage = theLanguage;
}
@Override
public void setResourceMetadata(ResourceMetadataMap theMap) {
Validate.notNull(theMap, "The Map must not be null");
myResourceMetadata = theMap;
}
public void setText(NarrativeDt theText) {
myText = theText;
}
@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("id", getId().toUnqualified());
return b.toString();
}
/**
* Intended to be called by extending classes {@link #isEmpty()} implementations, returns <code>true</code> if all
* content in this superclass instance is empty per the semantics of {@link #isEmpty()}.
*/
@Override
protected boolean isBaseEmpty() {
return super.isBaseEmpty() && ElementUtil.isEmpty(myLanguage, myText, myId);
}
}

View File

@ -29,6 +29,10 @@ import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.dev.composite.ContainedDt;
import ca.uhn.fhir.model.dev.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dev.resource.Profile; import ca.uhn.fhir.model.dev.resource.Profile;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
@ -86,5 +90,18 @@ public class FhirDev implements IFhirVersion {
public String getPathToSchemaDefinitions() { public String getPathToSchemaDefinitions() {
return "ca/uhn/fhir/model/dev/schema"; return "ca/uhn/fhir/model/dev/schema";
} }
@Override
public Class<? extends BaseResourceReferenceDt> getResourceReferenceType() {
return ResourceReferenceDt.class;
}
@Override
public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class;
}
} }

View File

@ -0,0 +1,53 @@
package ca.uhn.fhir.model.dev.composite;
/*
* #%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.ArrayList;
import java.util.List;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
@DatatypeDef(name = "contained")
public class ContainedDt extends BaseContainedDt {
@Child(name = "resource", type = IResource.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
private List<IResource> myContainedResources;
public List<IResource> getContainedResources() {
if (myContainedResources == null) {
myContainedResources = new ArrayList<IResource>();
}
return myContainedResources;
}
public void setContainedResources(List<IResource> theContainedResources) {
myContainedResources = theContainedResources;
}
@Override
public boolean isEmpty() {
return myContainedResources == null || myContainedResources.size() == 0;
}
}

View File

@ -0,0 +1,175 @@
package ca.uhn.fhir.model.dev.composite;
/*
* #%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 ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.BoundCodeDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
/**
* HAPI/FHIR <b>Narrative</b> Datatype
* (A human-readable formatted text, including images)
*
* <p>
* <b>Definition:</b>
* A human-readable formatted text, including images
* </p>
*
* <p>
* <b>Requirements:</b>
*
* </p>
*/
@DatatypeDef(name="Narrative")
public class NarrativeDt extends BaseNarrativeDt<NarrativeStatusEnum> {
@Child(name="status", type=CodeDt.class, order=0, min=1, max=1)
private BoundCodeDt<NarrativeStatusEnum> myStatus;
@Child(name="div", type=XhtmlDt.class, order=1, min=1, max=1)
private XhtmlDt myDiv;
public NarrativeDt() {
// nothing
}
public NarrativeDt(XhtmlDt theDiv, NarrativeStatusEnum theStatus) {
setDiv(theDiv);
setStatus(theStatus);
}
@Override
public boolean isEmpty() {
return ca.uhn.fhir.util.ElementUtil.isEmpty( myStatus, myDiv );
}
@Override
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements( theType, myStatus, myDiv );
}
/**
* Gets the value(s) for <b>status</b> (generated | extensions | additional).
* creating it if it does
* not exist. Will not return <code>null</code>.
*
* <p>
* <b>Definition:</b>
* The status of the narrative - whether it's entirely generated (from just the defined data or the extensions too), or whether a human authored it and it may contain additional data
* </p>
*/
public BoundCodeDt<NarrativeStatusEnum> getStatus() {
if (myStatus == null) {
myStatus = new BoundCodeDt<NarrativeStatusEnum>(NarrativeStatusEnum.VALUESET_BINDER);
}
return myStatus;
}
/**
* Sets the value(s) for <b>status</b> (generated | extensions | additional)
*
* <p>
* <b>Definition:</b>
* The status of the narrative - whether it's entirely generated (from just the defined data or the extensions too), or whether a human authored it and it may contain additional data
* </p>
*/
public void setStatus(BoundCodeDt<NarrativeStatusEnum> theValue) {
myStatus = theValue;
}
/**
* Sets the value(s) for <b>status</b> (generated | extensions | additional)
*
* <p>
* <b>Definition:</b>
* The status of the narrative - whether it's entirely generated (from just the defined data or the extensions too), or whether a human authored it and it may contain additional data
* </p>
*/
public void setStatus(NarrativeStatusEnum theValue) {
getStatus().setValueAsEnum(theValue);
}
/**
* Gets the value(s) for <b>div</b> (Limited xhtml content).
* creating it if it does
* not exist. Will not return <code>null</code>.
*
* <p>
* <b>Definition:</b>
* The actual narrative content, a stripped down version of XHTML
* </p>
*/
public XhtmlDt getDiv() {
if (myDiv == null) {
myDiv = new XhtmlDt();
}
return myDiv;
}
/**
* Sets the value(s) for <b>div</b> (Limited xhtml content)
*
* <p>
* <b>Definition:</b>
* The actual narrative content, a stripped down version of XHTML
* </p>
*/
public void setDiv(XhtmlDt theValue) {
myDiv = theValue;
}
/**
* Sets the value using a textual DIV (or simple text block which will be
* converted to XHTML)
*/
public void setDiv(String theTextDiv) {
myDiv = new XhtmlDt(theTextDiv);
}
}

View File

@ -0,0 +1,234 @@
package ca.uhn.fhir.model.dev.composite;
/*
* #%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 ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
/**
* HAPI/FHIR <b>ResourceReferenceDt</b> Datatype
* (A reference from one resource to another)
*
* <p>
* <b>Definition:</b>
* A reference from one resource to another
* </p>
*
* <p>
* <b>Requirements:</b>
*
* </p>
*/
@DatatypeDef(name="ResourceReferenceDt")
public class ResourceReferenceDt
extends BaseResourceReferenceDt implements ICompositeDatatype
{
/**
* Constructor
*/
public ResourceReferenceDt() {
// nothing
}
/**
* Constructor which creates a resource reference containing the actual resource in question.
* <p>
* <b> When using this in a server:</b> Generally if this is serialized, it will be serialized as a contained
* resource, so this should not be used if the intent is not to actually supply the referenced resource. This is not
* a hard-and-fast rule however, as the server can be configured to not serialized this resource, or to load an ID
* and contain even if this constructor is not used.
* </p>
*
* @param theResource
* The resource instance
*/
@SimpleSetter()
public ResourceReferenceDt(IResource theResource) {
super(theResource);
}
/**
* Constructor which accepts a reference directly (this can be an ID, a partial/relative URL or a complete/absolute
* URL)
*
* @param theId
* The reference itself
*/
public ResourceReferenceDt(String theId) {
setReference(new IdDt(theId));
}
/**
* Constructor which accepts a reference directly (this can be an ID, a partial/relative URL or a complete/absolute
* URL)
*
* @param theResourceId
* The reference itself
*/
public ResourceReferenceDt(IdDt theResourceId) {
setReference(theResourceId);
}
@Child(name="reference", type=IdDt.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 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"
)
private IdDt myReference;
@Child(name="display", type=StringDt.class, order=1, min=0, max=1)
@Description(
shortDefinition="Text alternative for the resource",
formalDefinition="Plain text narrative that identifies the resource in addition to the resource reference"
)
private StringDt myDisplay;
@Override
public boolean isEmpty() {
return super.isBaseEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty( myReference, myDisplay);
}
@Override
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements(theType, myReference, myDisplay);
}
/**
* Gets the value(s) for <b>reference</b> (Relative, internal or absolute URL reference).
* creating it if it does
* not exist. Will not return <code>null</code>.
*
* <p>
* <b>Definition:</b>
* A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources
* </p>
*/
public IdDt getReference() {
if (myReference == null) {
myReference = new IdDt();
}
return myReference;
}
/**
* Sets the value(s) for <b>reference</b> (Relative, internal or absolute URL reference)
*
* <p>
* <b>Definition:</b>
* A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources
* </p>
*/
public ResourceReferenceDt setReference(IdDt theValue) {
myReference = theValue;
return this;
}
/**
* Sets the value for <b>reference</b> (Relative, internal or absolute URL reference)
*
* <p>
* <b>Definition:</b>
* A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources
* </p>
*/
public ResourceReferenceDt setReference( String theId) {
myReference = new IdDt(theId);
return this;
}
/**
* Gets the value(s) for <b>display</b> (Text alternative for the resource).
* creating it if it does
* not exist. Will not return <code>null</code>.
*
* <p>
* <b>Definition:</b>
* Plain text narrative that identifies the resource in addition to the resource reference
* </p>
*/
public StringDt getDisplay() {
if (myDisplay == null) {
myDisplay = new StringDt();
}
return myDisplay;
}
/**
* Sets the value(s) for <b>display</b> (Text alternative for the resource)
*
* <p>
* <b>Definition:</b>
* Plain text narrative that identifies the resource in addition to the resource reference
* </p>
*/
public ResourceReferenceDt setDisplay(StringDt theValue) {
myDisplay = theValue;
return this;
}
/**
* Sets the value for <b>display</b> (Text alternative for the resource)
*
* <p>
* <b>Definition:</b>
* Plain text narrative that identifies the resource in addition to the resource reference
* </p>
*/
public ResourceReferenceDt setDisplay( String theString) {
myDisplay = new StringDt(theString);
return this;
}
@Override
public StringDt getDisplayElement() {
return getDisplay();
}
}

View File

@ -0,0 +1,112 @@
package ca.uhn.fhir.model.dev.resource;
/*
* #%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.Collections;
import java.util.List;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.BaseResource;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.primitive.Base64BinaryDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.util.ElementUtil;
@ResourceDef(name = "Binary", profile = "http://hl7.org/fhir/profiles/Binary", id = "binary")
public class Binary extends BaseResource implements IResource {
@Child(name = "content", order = 1)
private Base64BinaryDt myContent = new Base64BinaryDt();
@Child(name = "contentType", order = 0)
private StringDt myContentType;
/**
* Constructor
*/
public Binary() {
// nothing
}
/**
* Constructor
*
* @param theContentType
* The content type
* @param theContent
* The binary contents
*/
public Binary(String theContentType, byte[] theContent) {
setContentType(theContentType);
setContent(theContent);
}
@Override
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
return Collections.emptyList();
}
public byte[] getContent() {
return myContent.getValue();
}
public String getContentAsBase64() {
return myContent.getValueAsString();
}
public String getContentType() {
if (myContentType == null) {
return null;
}
return myContentType.getValue();
}
@Override
public boolean isEmpty() {
return (myContent.isEmpty()) && ElementUtil.isEmpty(myContentType);
}
public void setContent(byte[] theContent) {
myContent.setValue(theContent);
}
public void setContentAsBase64(String theContent) {
myContent.setValueAsString(theContent);
}
public void setContentType(String theContentType) {
myContentType = new StringDt(theContentType);
}
@Override
public String getResourceName() {
return Binary.class.getName();
}
@Override
public FhirVersionEnum getStructureFhirVersionEnum() {
return FhirVersionEnum.DSTU1;
}
}

View File

@ -37,22 +37,15 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dev.resource.Conformance; import ca.uhn.fhir.model.dev.resource.Conformance;
import ca.uhn.fhir.model.dev.resource.Conformance.Rest; import ca.uhn.fhir.model.dev.resource.Conformance.Rest;
import ca.uhn.fhir.model.dev.resource.Conformance.RestOperation;
import ca.uhn.fhir.model.dev.resource.Conformance.RestResource; import ca.uhn.fhir.model.dev.resource.Conformance.RestResource;
import ca.uhn.fhir.model.dev.resource.Conformance.RestResourceInteraction; import ca.uhn.fhir.model.dev.resource.Conformance.RestResourceInteraction;
import ca.uhn.fhir.model.dev.resource.Conformance.RestResourceSearchParam; import ca.uhn.fhir.model.dev.resource.Conformance.RestResourceSearchParam;
import ca.uhn.fhir.model.dev.resource.OperationDefinition;
import ca.uhn.fhir.model.dev.resource.OperationDefinition.Parameter;
import ca.uhn.fhir.model.dev.valueset.ResourceTypeEnum; import ca.uhn.fhir.model.dev.valueset.ResourceTypeEnum;
import ca.uhn.fhir.model.dev.valueset.RestfulConformanceModeEnum; import ca.uhn.fhir.model.dev.valueset.RestfulConformanceModeEnum;
import ca.uhn.fhir.model.dev.valueset.SystemRestfulInteractionEnum; import ca.uhn.fhir.model.dev.valueset.SystemRestfulInteractionEnum;
import ca.uhn.fhir.model.dev.valueset.TypeRestfulInteractionEnum; import ca.uhn.fhir.model.dev.valueset.TypeRestfulInteractionEnum;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.Metadata; import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.method.BaseMethodBinding; import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.rest.method.DynamicSearchMethodBinding; import ca.uhn.fhir.rest.method.DynamicSearchMethodBinding;
@ -64,7 +57,6 @@ import ca.uhn.fhir.rest.server.IServerConformanceProvider;
import ca.uhn.fhir.rest.server.ResourceBinding; import ca.uhn.fhir.rest.server.ResourceBinding;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.ExtensionConstants;
/** /**
* Server FHIR Provider which serves the conformance statement for a RESTful server implementation * Server FHIR Provider which serves the conformance statement for a RESTful server implementation

View File

@ -57,10 +57,15 @@ import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition; import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
import ca.uhn.fhir.model.api.ICompositeDatatype; import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IPrimitiveDatatype; import ca.uhn.fhir.model.api.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Profile; import ca.uhn.fhir.model.dstu.resource.Profile;
import ca.uhn.fhir.model.dstu.resource.Profile.ExtensionDefn; import ca.uhn.fhir.model.dstu.resource.Profile.ExtensionDefn;
import ca.uhn.fhir.model.dstu.resource.Profile.Structure; import ca.uhn.fhir.model.dstu.resource.Profile.Structure;
@ -70,7 +75,6 @@ import ca.uhn.fhir.model.dstu.valueset.DataTypeEnum;
import ca.uhn.fhir.model.dstu.valueset.SlicingRulesEnum; import ca.uhn.fhir.model.dstu.valueset.SlicingRulesEnum;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.IServerConformanceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.provider.ServerConformanceProvider; import ca.uhn.fhir.rest.server.provider.ServerConformanceProvider;
import ca.uhn.fhir.rest.server.provider.ServerProfileProvider; import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
@ -364,6 +368,16 @@ public class FhirDstu1 implements IFhirVersion {
return "ca/uhn/fhir/model/dstu/schema"; return "ca/uhn/fhir/model/dstu/schema";
} }
@Override
public Class<? extends BaseResourceReferenceDt> getResourceReferenceType() {
return ResourceReferenceDt.class;
}
@Override
public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class;
}
} }

View File

@ -62,7 +62,7 @@ import ca.uhn.fhir.model.primitive.XhtmlDt;
* </p> * </p>
*/ */
@DatatypeDef(name="Narrative") @DatatypeDef(name="Narrative")
public class NarrativeDt extends BaseNarrativeDt { public class NarrativeDt extends BaseNarrativeDt<NarrativeStatusEnum> {
@Child(name="status", type=CodeDt.class, order=0, min=1, max=1) @Child(name="status", type=CodeDt.class, order=0, min=1, max=1)
private BoundCodeDt<NarrativeStatusEnum> myStatus; private BoundCodeDt<NarrativeStatusEnum> myStatus;

View File

@ -226,7 +226,9 @@ public class ResourceReferenceDt
return this; return this;
} }
@Override
public StringDt getDisplayElement() {
return getDisplay();
}
} }

View File

@ -1,7 +1,7 @@
package ca.uhn.fhir.narrative; package ca.uhn.fhir.narrative;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*; import static org.junit.Assert.assertThat;
import org.junit.Test; import org.junit.Test;
@ -12,7 +12,6 @@ import ca.uhn.fhir.model.dstu.resource.Practitioner;
public class CustomThymeleafNarrativeGeneratorTest { public class CustomThymeleafNarrativeGeneratorTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CustomThymeleafNarrativeGeneratorTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CustomThymeleafNarrativeGeneratorTest.class);
private static FhirContext ourCtx = FhirContext.forDstu1();
@Test @Test
public void testGenerator() { public void testGenerator() {
@ -25,7 +24,8 @@ public class CustomThymeleafNarrativeGeneratorTest {
p.getAddress().addLine("line1").addLine("line2"); p.getAddress().addLine("line1").addLine("line2");
p.getName().addFamily("fam1").addGiven("given"); p.getName().addFamily("fam1").addGiven("given");
NarrativeDt narrative = gen.generateNarrative(p); NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative(p, narrative);
String actual = narrative.getDiv().getValueAsString(); String actual = narrative.getDiv().getValueAsString();
ourLog.info(actual); ourLog.info(actual);

View File

@ -61,7 +61,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
value.setBirthDate(new Date(), TemporalPrecisionEnum.DAY); value.setBirthDate(new Date(), TemporalPrecisionEnum.DAY);
String output = gen.generateNarrative(value).getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative(value, narrative);
String output = narrative.getDiv().getValueAsString();
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> joe john <b>BLOW </b></div>")); assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> joe john <b>BLOW </b></div>"));
String title = gen.generateTitle(value); String title = gen.generateTitle(value);
@ -109,7 +111,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
public void testGenerateServerConformance() throws DataFormatException { public void testGenerateServerConformance() throws DataFormatException {
Conformance value = myCtx.newXmlParser().parseResource(Conformance.class, new InputStreamReader(getClass().getResourceAsStream("/server-conformance-statement.xml"))); Conformance value = myCtx.newXmlParser().parseResource(Conformance.class, new InputStreamReader(getClass().getResourceAsStream("/server-conformance-statement.xml")));
String output = gen.generateNarrative(value).getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative(value, narrative);
String output =narrative.getDiv().getValueAsString();
ourLog.info(output); ourLog.info(output);
} }
@ -123,7 +127,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
value.addResult().setReference("Observation/2"); value.addResult().setReference("Observation/2");
value.addResult().setReference("Observation/3"); value.addResult().setReference("Observation/3");
String output = gen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value).getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value, narrative);
String output = narrative.getDiv().getValueAsString();
ourLog.info(output); ourLog.info(output);
assertThat(output, StringContains.containsString(value.getName().getText().getValue())); assertThat(output, StringContains.containsString(value.getName().getText().getValue()));
@ -146,18 +152,20 @@ public class DefaultThymeleafNarrativeGeneratorTest {
OperationOutcome oo = myCtx.newXmlParser().parseResource(OperationOutcome.class, parse); OperationOutcome oo = myCtx.newXmlParser().parseResource(OperationOutcome.class, parse);
// String output = gen.generateTitle(oo); // String output = gen.generateTitle(oo);
// ourLog.info(output); // ourLog.info(output);
// assertEquals("Operation Outcome (2 issues)", output); // assertEquals("Operation Outcome (2 issues)", output);
String nar = gen.generateNarrative(null, oo).getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative(null, oo, narrative);
String nar = narrative.getDiv().getValueAsString();
ourLog.info(nar); ourLog.info(nar);
// oo = new OperationOutcome(); // oo = new OperationOutcome();
// oo.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("AA"); // oo.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("AA");
// output = gen.generateTitle(oo); // output = gen.generateTitle(oo);
// ourLog.info(output); // ourLog.info(output);
// assertEquals("Operation Outcome (fatal)", output); // assertEquals("Operation Outcome (fatal)", output);
} }
@ -190,8 +198,10 @@ public class DefaultThymeleafNarrativeGeneratorTest {
obs.setName(new CodeableConceptDt("AA", "BB")); obs.setName(new CodeableConceptDt("AA", "BB"));
value.addResult().setResource(obs); value.addResult().setResource(obs);
} }
NarrativeDt generateNarrative = gen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value);
String output = generateNarrative.getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value, narrative);
String output = narrative.getDiv().getValueAsString();
ourLog.info(output); ourLog.info(output);
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>")); assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>"));
@ -207,25 +217,26 @@ public class DefaultThymeleafNarrativeGeneratorTest {
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>")); assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>"));
} }
@Test @Test
public void testGenerateMedicationPrescription(){ public void testGenerateMedicationPrescription() {
MedicationPrescription mp = new MedicationPrescription(); MedicationPrescription mp = new MedicationPrescription();
mp.setId("12345"); mp.setId("12345");
Medication med = new Medication(); Medication med = new Medication();
med.setName("ciprofloaxin"); med.setName("ciprofloaxin");
ResourceReferenceDt medRef = new ResourceReferenceDt(med); ResourceReferenceDt medRef = new ResourceReferenceDt(med);
mp.setMedication(medRef ); mp.setMedication(medRef);
mp.setStatus(MedicationPrescriptionStatusEnum.ACTIVE); mp.setStatus(MedicationPrescriptionStatusEnum.ACTIVE);
mp.setDateWritten(new DateTimeDt("2014-09-01")); mp.setDateWritten(new DateTimeDt("2014-09-01"));
NarrativeDt narrative = gen.generateNarrative(mp); NarrativeDt narrative = new NarrativeDt();
assertTrue("Expected medication name of ciprofloaxin within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ciprofloaxin")>-1); gen.generateNarrative(mp, narrative);
assertTrue("Expected string status of ACTIVE within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ACTIVE")>-1); assertTrue("Expected medication name of ciprofloaxin within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ciprofloaxin") > -1);
assertTrue("Expected string status of ACTIVE within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ACTIVE") > -1);
String title = gen.generateTitle(mp); String title = gen.generateTitle(mp);
assertEquals("ciprofloaxin", title); assertEquals("ciprofloaxin", title);
} }
} }

View File

@ -21,8 +21,10 @@ import org.apache.commons.io.IOUtils;
import org.hamcrest.core.IsNot; import org.hamcrest.core.IsNot;
import org.hamcrest.core.StringContains; import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder; import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers; import org.mockito.Matchers;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
@ -36,6 +38,7 @@ import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Extension; import ca.uhn.fhir.model.api.annotation.Extension;
import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.dstu.composite.AddressDt; import ca.uhn.fhir.model.dstu.composite.AddressDt;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt; import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt; import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
@ -890,11 +893,34 @@ public class JsonParserTest {
Organization org = new Organization(); Organization org = new Organization();
patient.getManagingOrganization().setResource(org); patient.getManagingOrganization().setResource(org);
INarrativeGenerator gen = mock(INarrativeGenerator.class); INarrativeGenerator gen = new INarrativeGenerator() {
XhtmlDt xhtmlDt = new XhtmlDt("<div>help</div>");
NarrativeDt nar = new NarrativeDt(xhtmlDt, NarrativeStatusEnum.GENERATED);
when(gen.generateNarrative(eq("http://hl7.org/fhir/profiles/Patient"), eq(patient))).thenReturn(nar);
@Override
public void generateNarrative(String theProfile, IBaseResource theResource, BaseNarrativeDt<?> theNarrative) throws DataFormatException {
theNarrative.getDiv().setValueAsString("<div>help</div>");
theNarrative.getStatus().setValueAsString("generated");
}
@Override
public void generateNarrative(IBaseResource theResource, BaseNarrativeDt<?> theNarrative) {
throw new UnsupportedOperationException();
}
@Override
public String generateTitle(IBaseResource theResource) {
throw new UnsupportedOperationException();
}
@Override
public String generateTitle(String theProfile, IBaseResource theResource) {
throw new UnsupportedOperationException();
}
@Override
public void setFhirContext(FhirContext theFhirContext) {
// nothing
}};
FhirContext context = new FhirContext(); FhirContext context = new FhirContext();
context.setNarrativeGenerator(gen); context.setNarrativeGenerator(gen);
IParser p = context.newJsonParser(); IParser p = context.newJsonParser();

View File

@ -10,9 +10,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -31,6 +28,7 @@ import org.hamcrest.Matchers;
import org.hamcrest.core.IsNot; import org.hamcrest.core.IsNot;
import org.hamcrest.core.StringContains; import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder; import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@ -44,10 +42,10 @@ import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.dstu.composite.AddressDt; import ca.uhn.fhir.model.dstu.composite.AddressDt;
import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt; import ca.uhn.fhir.model.dstu.composite.CodeableConceptDt;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt; import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.AllergyIntolerance; import ca.uhn.fhir.model.dstu.resource.AllergyIntolerance;
import ca.uhn.fhir.model.dstu.resource.Binary; import ca.uhn.fhir.model.dstu.resource.Binary;
@ -74,7 +72,6 @@ import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredAddressExtension; import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredAddressExtension;
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredExtension; import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredExtension;
@ -1062,10 +1059,33 @@ public class XmlParserTest {
patient.addName().addFamily("Smith"); patient.addName().addFamily("Smith");
INarrativeGenerator gen = mock(INarrativeGenerator.class); INarrativeGenerator gen = new INarrativeGenerator() {
XhtmlDt xhtmlDt = new XhtmlDt("<div>help</div>");
NarrativeDt nar = new NarrativeDt(xhtmlDt, NarrativeStatusEnum.GENERATED); @Override
when(gen.generateNarrative(eq("http://hl7.org/fhir/profiles/Patient"), eq(patient))).thenReturn(nar); public void generateNarrative(String theProfile, IBaseResource theResource, BaseNarrativeDt<?> theNarrative) throws DataFormatException {
theNarrative.getDiv().setValueAsString("<div>help</div>");
theNarrative.getStatus().setValueAsString("generated");
}
@Override
public void generateNarrative(IBaseResource theResource, BaseNarrativeDt<?> theNarrative) {
throw new UnsupportedOperationException();
}
@Override
public String generateTitle(IBaseResource theResource) {
throw new UnsupportedOperationException();
}
@Override
public String generateTitle(String theProfile, IBaseResource theResource) {
throw new UnsupportedOperationException();
}
@Override
public void setFhirContext(FhirContext theFhirContext) {
// nothing
}};
FhirContext context = ourCtx; FhirContext context = ourCtx;
context.setNarrativeGenerator(gen); context.setNarrativeGenerator(gen);

View File

@ -0,0 +1,162 @@
package ca.uhn.fhir.model.api;
/*
* #%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 org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.SearchParamDefinition;
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
import ca.uhn.fhir.model.dstu2.composite.ContainedDt;
import ca.uhn.fhir.model.dstu2.composite.NarrativeDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.util.ElementUtil;
public abstract class BaseResource extends BaseElement implements IResource {
/**
* Search parameter constant for <b>_language</b>
*/
@SearchParamDefinition(name="_language", path="", description="The language of the resource", type="string" )
public static final String SP_RES_LANGUAGE = "_language";
/**
* Search parameter constant for <b>_id</b>
*/
@SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" )
public static final String SP_RES_ID = "_id";
/**
* <b>Fluent Client</b> search parameter constant for <b>_id</b>
* <p>
* Description: <b>the _id of a resource</b><br>
* Type: <b>string</b><br>
* Path: <b>Resource._id</b><br>
* </p>
*/
public static final StringClientParam RES_ID = new StringClientParam(BaseResource.SP_RES_ID);
@Child(name = "contained", order = 2, min = 0, max = 1)
private ContainedDt myContained;
private IdDt myId;
@Child(name = "language", order = 0, min = 0, max = Child.MAX_UNLIMITED)
private CodeDt myLanguage;
private ResourceMetadataMap myResourceMetadata;
@Child(name = "text", order = 1, min = 0, max = 1)
private NarrativeDt myText;
@Override
public ContainedDt getContained() {
if (myContained == null) {
myContained = new ContainedDt();
}
return myContained;
}
public IdDt getId() {
if (myId == null) {
myId = new IdDt();
}
return myId;
}
@Override
public CodeDt getLanguage() {
if (myLanguage == null) {
myLanguage = new CodeDt();
}
return myLanguage;
}
@Override
public ResourceMetadataMap getResourceMetadata() {
if (myResourceMetadata == null) {
myResourceMetadata = new ResourceMetadataMap();
}
return myResourceMetadata;
}
@Override
public NarrativeDt getText() {
if (myText == null) {
myText = new NarrativeDt();
}
return myText;
}
public void setContained(ContainedDt theContained) {
myContained = theContained;
}
public void setId(IdDt theId) {
myId = theId;
}
public void setId(String theId) {
if (theId == null) {
myId = null;
} else {
myId = new IdDt(theId);
}
}
@Override
public void setLanguage(CodeDt theLanguage) {
myLanguage = theLanguage;
}
@Override
public void setResourceMetadata(ResourceMetadataMap theMap) {
Validate.notNull(theMap, "The Map must not be null");
myResourceMetadata = theMap;
}
public void setText(NarrativeDt theText) {
myText = theText;
}
@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("id", getId().toUnqualified());
return b.toString();
}
/**
* Intended to be called by extending classes {@link #isEmpty()} implementations, returns <code>true</code> if all
* content in this superclass instance is empty per the semantics of {@link #isEmpty()}.
*/
@Override
protected boolean isBaseEmpty() {
return super.isBaseEmpty() && ElementUtil.isEmpty(myLanguage, myText, myId);
}
}

View File

@ -27,8 +27,13 @@ import org.apache.commons.lang3.StringUtils;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.composite.ContainedDt;
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.Profile; import ca.uhn.fhir.model.dstu2.resource.Profile;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
@ -87,4 +92,14 @@ public class FhirDstu2 implements IFhirVersion {
return "ca/uhn/fhir/model/dstu2/schema"; return "ca/uhn/fhir/model/dstu2/schema";
} }
@Override
public Class<? extends BaseResourceReferenceDt> getResourceReferenceType() {
return ResourceReferenceDt.class;
}
@Override
public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class;
}
} }

View File

@ -226,6 +226,11 @@ public class ResourceReferenceDt
return this; return this;
} }
@Override
public StringDt getDisplayElement() {
return getDisplay();
}

View File

@ -27,7 +27,8 @@ public class CustomThymeleafNarrativeGeneratorTest {
p.addAddress().addLine("line1").addLine("line2"); p.addAddress().addLine("line1").addLine("line2");
p.getName().addFamily("fam1").addGiven("given"); p.getName().addFamily("fam1").addGiven("given");
NarrativeDt narrative = gen.generateNarrative(p); NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative(p, narrative);
String actual = narrative.getDiv().getValueAsString(); String actual = narrative.getDiv().getValueAsString();
ourLog.info(actual); ourLog.info(actual);

View File

@ -59,7 +59,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
value.setBirthDate(new Date(), TemporalPrecisionEnum.DAY); value.setBirthDate(new Date(), TemporalPrecisionEnum.DAY);
String output = myGen.generateNarrative(value).getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
myGen.generateNarrative(value, narrative);
String output = narrative.getDiv().getValueAsString();
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> joe john <b>BLOW </b></div>")); assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> joe john <b>BLOW </b></div>"));
String title = myGen.generateTitle(value); String title = myGen.generateTitle(value);
@ -99,7 +101,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
value.addResult().setReference("Observation/2"); value.addResult().setReference("Observation/2");
value.addResult().setReference("Observation/3"); value.addResult().setReference("Observation/3");
String output = myGen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value).getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
myGen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value, narrative);
String output = narrative.getDiv().getValueAsString();
ourLog.info(output); ourLog.info(output);
assertThat(output, StringContains.containsString(value.getName().getTextElement().getValue())); assertThat(output, StringContains.containsString(value.getName().getTextElement().getValue()));
@ -126,8 +130,11 @@ public class DefaultThymeleafNarrativeGeneratorTest {
// ourLog.info(output); // ourLog.info(output);
// assertEquals("Operation Outcome (2 issues)", output); // assertEquals("Operation Outcome (2 issues)", output);
String nar = myGen.generateNarrative(null, oo).getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
ourLog.info(nar); myGen.generateNarrative(null, oo, narrative);
String output = narrative.getDiv().getValueAsString();
ourLog.info(output);
// oo = new OperationOutcome(); // oo = new OperationOutcome();
// oo.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("AA"); // oo.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("AA");
@ -166,8 +173,10 @@ public class DefaultThymeleafNarrativeGeneratorTest {
obs.setName(new CodeableConceptDt("AA", "BB")); obs.setName(new CodeableConceptDt("AA", "BB"));
value.addResult().setResource(obs); value.addResult().setResource(obs);
} }
NarrativeDt generateNarrative = myGen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value);
String output = generateNarrative.getDiv().getValueAsString(); NarrativeDt narrative = new NarrativeDt();
myGen.generateNarrative("http://hl7.org/fhir/profiles/DiagnosticReport", value, narrative);
String output = narrative.getDiv().getValueAsString();
ourLog.info(output); ourLog.info(output);
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>")); assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>"));
@ -195,7 +204,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
mp.setStatus(MedicationPrescriptionStatusEnum.ACTIVE); mp.setStatus(MedicationPrescriptionStatusEnum.ACTIVE);
mp.setDateWritten(new DateTimeDt("2014-09-01")); mp.setDateWritten(new DateTimeDt("2014-09-01"));
NarrativeDt narrative = myGen.generateNarrative(mp); NarrativeDt narrative = new NarrativeDt();
myGen.generateNarrative(mp, narrative);
assertTrue("Expected medication name of ciprofloaxin within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ciprofloaxin")>-1); assertTrue("Expected medication name of ciprofloaxin within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ciprofloaxin")>-1);
assertTrue("Expected string status of ACTIVE within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ACTIVE")>-1); assertTrue("Expected string status of ACTIVE within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ACTIVE")>-1);