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

View File

@ -20,12 +20,13 @@ package ca.uhn.fhir.context;
* #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);
assert BaseContainedDt.class.isAssignableFrom(theClass);
}
@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.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.IServerConformanceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
@ -44,8 +46,8 @@ public interface IFhirVersion {
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;
import java.util.List;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.IResource;
/*
* #%L
@ -24,4 +27,6 @@ import ca.uhn.fhir.model.api.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.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
@ -24,6 +26,13 @@ import ca.uhn.fhir.model.api.IDatatype;
* #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.Reader;
import java.util.List;
import javax.json.JsonValue;
import org.apache.http.HttpResponse;
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.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.BaseClient;
import ca.uhn.fhir.rest.client.api.IRestfulClient;
@ -59,14 +63,15 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement {
setReference(theResource.getId());
}
public abstract StringDt getDisplayElement();
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
* {@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>
* for more information.
* See the FHIR specification section on <a href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> for more information.
*
* @see #loadResource(IRestfulClient)
*/

View File

@ -1,12 +1,18 @@
package ca.uhn.fhir.model.base.resource;
import ca.uhn.fhir.model.api.BaseResource;
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%
*/
import ca.uhn.fhir.model.api.BaseResource;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
//@ResourceDef(name="Conformance")
public abstract class BaseConformance extends BaseResource implements IResource {
public interface BaseConformance extends IResource {
public abstract StringDt getDescriptionElement();

View File

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

View File

@ -20,9 +20,8 @@ package ca.uhn.fhir.model.base.resource;
* #L%
*/
import ca.uhn.fhir.model.api.BaseResource;
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%
*/
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.File;
import java.io.FileInputStream;
@ -63,9 +63,7 @@ import org.thymeleaf.templateresolver.TemplateResolver;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.parser.DataFormatException;
public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGenerator {
@ -94,8 +92,8 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
}
@Override
public NarrativeDt generateNarrative(IBaseResource theResource) {
return generateNarrative( null, theResource);
public void generateNarrative(IBaseResource theResource, BaseNarrativeDt<?> theNarrative) {
generateNarrative(null, theResource, theNarrative);
}
@Override
@ -110,7 +108,7 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
}
@Override
public NarrativeDt generateNarrative(String theProfile, IBaseResource theResource) {
public void generateNarrative(String theProfile, IBaseResource theResource, BaseNarrativeDt<?> theNarrative) {
if (!myInitialized) {
initialize();
}
@ -129,7 +127,9 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
if (name == null) {
if (myIgnoreMissingTemplates) {
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 {
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);
}
XhtmlDt div = new XhtmlDt(result);
return new NarrativeDt(div, NarrativeStatusEnum.GENERATED);
theNarrative.getDiv().setValueAsString(result);
theNarrative.getStatus().setValueAsString("generated");
return;
} catch (Exception e) {
if (myIgnoreFailures) {
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 {
throw new DataFormatException(e);
}

View File

@ -23,14 +23,14 @@ package ca.uhn.fhir.narrative;
import org.hl7.fhir.instance.model.IBaseResource;
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;
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);

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.IResource;
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;
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);
for (ResourceReferenceDt next : allElements) {
List<BaseResourceReferenceDt> allElements = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt next : allElements) {
IResource resource = next.getResource();
if (resource != null) {
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);
}
protected String determineReferenceText(ResourceReferenceDt theRef) {
protected String determineReferenceText(BaseResourceReferenceDt theRef) {
String reference = theRef.getReference().getValue();
if (isBlank(reference)) {
if (theRef.getResource() != null) {

View File

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

View File

@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
* #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.HashMap;
@ -40,6 +42,7 @@ import org.hl7.fhir.instance.model.IPrimitiveType;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
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.Tag;
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.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.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
@ -718,8 +721,8 @@ class ParserState<T> {
}
for (IResource next : resources) {
List<ResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, ResourceReferenceDt.class);
for (ResourceReferenceDt nextRef : refs) {
List<BaseResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt nextRef : refs) {
if (nextRef.isEmpty() == false && nextRef.getReference() != null) {
IResource target = idToResource.get(nextRef.getReference().getValue());
if (target != null) {
@ -816,10 +819,10 @@ class ParserState<T> {
private static final int SUBSTATE_CONTENT = 2;
private static final int SUBSTATE_CT = 1;
private String myData;
private Binary myInstance;
private BaseBinary myInstance;
private int mySubState = 0;
public BinaryResourceStateForDstu1(PreResourceState thePreResourceState, Binary theInstance) {
public BinaryResourceStateForDstu1(PreResourceState thePreResourceState, BaseBinary theInstance) {
super(thePreResourceState);
myInstance = theInstance;
}
@ -1286,7 +1289,10 @@ class ParserState<T> {
}
}
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;
}
case RESOURCE_REF: {
ResourceReferenceDt newChildInstance = new ResourceReferenceDt();
BaseResourceReferenceDt newChildInstance = newResourceReferenceDt();
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
push(newState);
@ -1352,6 +1358,7 @@ class ParserState<T> {
}
}
@Override
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
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 BaseRuntimeElementCompositeDefinition<?> myDefinition;
@ -1447,7 +1466,7 @@ class ParserState<T> {
}
case RESOURCE_REF: {
RuntimeResourceReferenceDefinition resourceRefTarget = (RuntimeResourceReferenceDefinition) target;
ResourceReferenceDt newChildInstance = new ResourceReferenceDt();
BaseResourceReferenceDt newChildInstance = newResourceReferenceDt();
getPreResourceState().getResourceReferences().add(newChildInstance);
child.getMutator().addValue(myInstance, newChildInstance);
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
@ -1473,12 +1492,12 @@ class ParserState<T> {
case CONTAINED_RESOURCES: {
RuntimeElemContainedResources targetElem = (RuntimeElemContainedResources) target;
List<? extends IBase> values = child.getAccessor().getValues(myInstance);
ContainedDt newDt;
BaseContainedDt newDt;
if (values == null || values.isEmpty() || values.get(0) == null) {
newDt = targetElem.newInstance();
child.getMutator().addValue(myInstance, newDt);
} else {
newDt = (ContainedDt) values.get(0);
newDt = (BaseContainedDt) values.get(0);
}
ContainedResourcesState state = new ContainedResourcesState(getPreResourceState());
push(state);
@ -1555,7 +1574,7 @@ class ParserState<T> {
return;
}
case RESOURCE_REF: {
ResourceReferenceDt newChildInstance = new ResourceReferenceDt();
BaseResourceReferenceDt newChildInstance = newResourceReferenceDt();
myExtension.setValue(newChildInstance);
ResourceReferenceState newState = new ResourceReferenceState(getPreResourceState(), newChildInstance);
push(newState);
@ -1707,7 +1726,7 @@ class ParserState<T> {
private Map<String, IBaseResource> myContainedResources = new HashMap<String, IBaseResource>();
private BundleEntry myEntry;
private IResource myInstance;
private List<ResourceReferenceDt> myResourceReferences = new ArrayList<ResourceReferenceDt>();
private List<BaseResourceReferenceDt> myResourceReferences = new ArrayList<BaseResourceReferenceDt>();
private Class<? extends IBaseResource> myResourceType;
public PreResourceState(BundleEntry theEntry, Class<? extends IBaseResource> theResourceType) {
@ -1760,7 +1779,7 @@ class ParserState<T> {
String resourceName = def.getName();
if ("Binary".equals(resourceName) && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
push(new BinaryResourceStateForDstu1(getRootPreResourceState(), (Binary) myInstance));
push(new BinaryResourceStateForDstu1(getRootPreResourceState(), (BaseBinary) myInstance));
} else {
push(new ResourceState(getRootPreResourceState(), def, myInstance));
}
@ -1775,7 +1794,7 @@ class ParserState<T> {
return myInstance;
}
public List<ResourceReferenceDt> getResourceReferences() {
public List<BaseResourceReferenceDt> getResourceReferences() {
return myResourceReferences;
}
@ -1803,8 +1822,8 @@ class ParserState<T> {
@Override
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement instanceof ResourceReferenceDt) {
ResourceReferenceDt nextRef = (ResourceReferenceDt) theElement;
if (theElement instanceof BaseResourceReferenceDt) {
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
String ref = nextRef.getReference().getValue();
if (isNotBlank(ref)) {
if (ref.startsWith("#")) {
@ -1928,10 +1947,10 @@ class ParserState<T> {
private class ResourceReferenceState extends BaseState {
private ResourceReferenceDt myInstance;
private BaseResourceReferenceDt myInstance;
private ResourceReferenceSubState mySubState;
public ResourceReferenceState(PreResourceState thePreResourceState, ResourceReferenceDt theInstance) {
public ResourceReferenceState(PreResourceState thePreResourceState, BaseResourceReferenceDt theInstance) {
super(thePreResourceState);
myInstance = theInstance;
mySubState = ResourceReferenceSubState.INITIAL;
@ -1945,12 +1964,12 @@ class ParserState<T> {
switch (mySubState) {
case DISPLAY:
myInstance.setDisplay(theValue);
myInstance.getDisplayElement().setValue(theValue);
break;
case INITIAL:
throw new DataFormatException("Unexpected attribute: " + theValue);
case REFERENCE:
myInstance.setReference(theValue);
myInstance.getReference().setValue(theValue);
break;
}
}

View File

@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
* #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.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.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
@ -463,7 +465,7 @@ public class XmlParser extends BaseParser implements IParser {
break;
}
case RESOURCE_REF: {
ResourceReferenceDt ref = (ResourceReferenceDt) nextValue;
BaseResourceReferenceDt ref = (BaseResourceReferenceDt) nextValue;
if (!ref.isEmpty()) {
theEventWriter.writeStartElement(childName);
encodeResourceReferenceToStreamWriter(theEventWriter, ref);
@ -472,7 +474,7 @@ public class XmlParser extends BaseParser implements IParser {
break;
}
case CONTAINED_RESOURCES: {
ContainedDt value = (ContainedDt) nextValue;
BaseContainedDt value = (BaseContainedDt) nextValue;
/*
* Disable per #103 for (IResource next : value.getContainedResources()) { if
* (getContainedResources().getResourceId(next) != null) { continue; }
@ -511,11 +513,11 @@ public class XmlParser extends BaseParser implements IParser {
if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) {
INarrativeGenerator gen = myContext.getNarrativeGenerator();
if (theResource instanceof IResource) {
NarrativeDt narr = ((IResource) theResource).getText();
BaseNarrativeDt<?> narr = ((IResource) theResource).getText();
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;
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
@ -524,9 +526,10 @@ public class XmlParser extends BaseParser implements IParser {
}
} else {
Narrative narr1 = ((DomainResource) theResource).getText();
NarrativeDt narr2 = null;
BaseNarrativeDt<?> narr2 = null;
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) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
@ -544,7 +547,7 @@ public class XmlParser extends BaseParser implements IParser {
}
for (IBase nextValue : values) {
if ((nextValue == null || nextValue.isEmpty()) && !(nextValue instanceof ContainedDt)) {
if ((nextValue == null || nextValue.isEmpty()) && !(nextValue instanceof BaseContainedDt)) {
continue;
}
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);
if (StringUtils.isNotBlank(reference)) {
@ -602,9 +605,9 @@ public class XmlParser extends BaseParser implements IParser {
theEventWriter.writeAttribute("value", reference);
theEventWriter.writeEndElement();
}
if (!(theRef.getDisplay().isEmpty())) {
if (!(theRef.getDisplayElement().isEmpty())) {
theEventWriter.writeStartElement(RESREF_DISPLAY);
theEventWriter.writeAttribute("value", theRef.getDisplay().getValue());
theEventWriter.writeAttribute("value", theRef.getDisplayElement().getValue());
theEventWriter.writeEndElement();
}
}
@ -718,8 +721,8 @@ public class XmlParser extends BaseParser implements IParser {
}
if (theResource instanceof Binary) {
Binary bin = (Binary) theResource;
if (theResource instanceof BaseBinary) {
BaseBinary bin = (BaseBinary) theResource;
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
writeOptionalTagWithValue(theEventWriter, "contentType", bin.getContentType());
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.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ResourceParameter;
@ -65,7 +63,7 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
providerResourceType = ((IResourceProvider) theProvider).getResourceType();
}
if (providerResourceType.isAssignableFrom(Binary.class)) {
if (providerResourceType.isAssignableFrom(BaseBinary.class)) {
myBinary = true;
}
@ -97,7 +95,12 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
if (myBinary) {
String ct = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
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 {
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.model.api.Bundle;
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.model.primitive.IdDt;
@ -168,7 +168,10 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
@Override
public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
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()) {
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.Description;
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.CodeDt;
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
* </p>
*/
public ResourceReferenceDt getValueSet() {
public BaseResourceReferenceDt getValueSet() {
throw new UnsupportedOperationException();
}
@ -357,7 +357,7 @@ public class InternalCodingDt
* The set of possible coded values this coding was chosen from or constrained by
* </p>
*/
public InternalCodingDt setValueSet(ResourceReferenceDt theValue) {
public InternalCodingDt setValueSet(BaseResourceReferenceDt theValue) {
throw new UnsupportedOperationException();
}

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.rest.server;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException;
import java.io.OutputStreamWriter;
@ -30,7 +30,6 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
@ -52,7 +51,6 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
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.Tag;
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.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.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
@ -1177,11 +1175,11 @@ public class RestfulServer extends HttpServlet {
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 {
List<IResource> addedResourcesThisPass = new ArrayList<IResource>();
for (ResourceReferenceDt nextRef : references) {
for (BaseResourceReferenceDt nextRef : references) {
IResource nextRes = nextRef.getResource();
if (nextRes != null) {
if (nextRes.getId().hasIdPart()) {
@ -1206,9 +1204,9 @@ public class RestfulServer extends HttpServlet {
}
// Linked resources may themselves have linked resources
references = new ArrayList<ResourceReferenceDt>();
references = new ArrayList<BaseResourceReferenceDt>();
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);
}
@ -1449,8 +1447,8 @@ public class RestfulServer extends HttpServlet {
}
}
if (theResource instanceof Binary) {
Binary bin = (Binary) theResource;
if (theResource instanceof BaseBinary) {
BaseBinary bin = (BaseBinary) theResource;
if (isNotBlank(bin.getContentType())) {
theHttpResponse.setContentType(bin.getContentType());
} 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.IResource;
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.DataFormatException;
@ -73,7 +73,7 @@ public class FhirTerser {
* </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.
* {@link ResourceReferenceDt#getResource()})
* {@link BaseResourceReferenceDt#getResource()})
* </p>
*
* @param theResource
@ -196,7 +196,7 @@ public class FhirTerser {
// These are primitive types
break;
case RESOURCE_REF:
ResourceReferenceDt resRefDt = (ResourceReferenceDt) theElement;
BaseResourceReferenceDt resRefDt = (BaseResourceReferenceDt) theElement;
if (resRefDt.getReference().getValue() == null && resRefDt.getResource() != null) {
IResource theResource = resRefDt.getResource();
if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) {
@ -246,7 +246,7 @@ public class FhirTerser {
break;
}
case CONTAINED_RESOURCES: {
ContainedDt value = (ContainedDt) theElement;
BaseContainedDt value = (BaseContainedDt) theElement;
for (IResource next : value.getContainedResources()) {
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next);
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.model.api.IFhirVersion;
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.primitive.IdDt;
import ca.uhn.fhir.rest.server.IResourceProvider;
@ -87,4 +91,17 @@ public class FhirDev implements IFhirVersion {
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.dev.resource.Conformance;
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.RestResourceInteraction;
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.RestfulConformanceModeEnum;
import ca.uhn.fhir.model.dev.valueset.SystemRestfulInteractionEnum;
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.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
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.RestfulServer;
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

View File

@ -57,10 +57,15 @@ import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
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.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IResource;
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.ExtensionDefn;
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.primitive.IdDt;
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.provider.ServerConformanceProvider;
import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
@ -364,6 +368,16 @@ public class FhirDstu1 implements IFhirVersion {
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>
*/
@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)
private BoundCodeDt<NarrativeStatusEnum> myStatus;

View File

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

View File

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

View File

@ -61,7 +61,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
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>"));
String title = gen.generateTitle(value);
@ -109,7 +111,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
public void testGenerateServerConformance() throws DataFormatException {
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);
}
@ -123,7 +127,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
value.addResult().setReference("Observation/2");
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);
assertThat(output, StringContains.containsString(value.getName().getText().getValue()));
@ -150,7 +156,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
// ourLog.info(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);
// oo = new OperationOutcome();
@ -190,8 +198,10 @@ public class DefaultThymeleafNarrativeGeneratorTest {
obs.setName(new CodeableConceptDt("AA", "BB"));
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);
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>"));
@ -219,7 +229,8 @@ public class DefaultThymeleafNarrativeGeneratorTest {
mp.setStatus(MedicationPrescriptionStatusEnum.ACTIVE);
mp.setDateWritten(new DateTimeDt("2014-09-01"));
NarrativeDt narrative = gen.generateNarrative(mp);
NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative(mp, narrative);
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);

View File

@ -21,8 +21,10 @@ import org.apache.commons.io.IOUtils;
import org.hamcrest.core.IsNot;
import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers;
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.Extension;
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.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
@ -890,10 +893,33 @@ public class JsonParserTest {
Organization org = new Organization();
patient.getManagingOrganization().setResource(org);
INarrativeGenerator gen = mock(INarrativeGenerator.class);
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);
INarrativeGenerator gen = new INarrativeGenerator() {
@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();
context.setNarrativeGenerator(gen);

View File

@ -10,9 +10,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
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.InputStreamReader;
@ -31,6 +28,7 @@ import org.hamcrest.Matchers;
import org.hamcrest.core.IsNot;
import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.BeforeClass;
import org.junit.Test;
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.ResourceMetadataKeyEnum;
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.CodeableConceptDt;
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.resource.AllergyIntolerance;
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.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredAddressExtension;
import ca.uhn.fhir.parser.JsonParserTest.MyPatientWithOneDeclaredExtension;
@ -1062,10 +1059,33 @@ public class XmlParserTest {
patient.addName().addFamily("Smith");
INarrativeGenerator gen = mock(INarrativeGenerator.class);
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);
INarrativeGenerator gen = new INarrativeGenerator() {
@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 = ourCtx;
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.FhirVersionEnum;
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.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.primitive.IdDt;
import ca.uhn.fhir.rest.server.IResourceProvider;
@ -87,4 +92,14 @@ public class FhirDstu2 implements IFhirVersion {
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;
}
@Override
public StringDt getDisplayElement() {
return getDisplay();
}

View File

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

View File

@ -59,7 +59,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
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>"));
String title = myGen.generateTitle(value);
@ -99,7 +101,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
value.addResult().setReference("Observation/2");
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);
assertThat(output, StringContains.containsString(value.getName().getTextElement().getValue()));
@ -126,8 +130,11 @@ public class DefaultThymeleafNarrativeGeneratorTest {
// ourLog.info(output);
// assertEquals("Operation Outcome (2 issues)", output);
String nar = myGen.generateNarrative(null, oo).getDiv().getValueAsString();
ourLog.info(nar);
NarrativeDt narrative = new NarrativeDt();
myGen.generateNarrative(null, oo, narrative);
String output = narrative.getDiv().getValueAsString();
ourLog.info(output);
// oo = new OperationOutcome();
// oo.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("AA");
@ -166,8 +173,10 @@ public class DefaultThymeleafNarrativeGeneratorTest {
obs.setName(new CodeableConceptDt("AA", "BB"));
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);
assertThat(output, StringContains.containsString("<div class=\"hapiHeaderText\"> Some &amp; Diagnostic Report </div>"));
@ -195,7 +204,9 @@ public class DefaultThymeleafNarrativeGeneratorTest {
mp.setStatus(MedicationPrescriptionStatusEnum.ACTIVE);
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 string status of ACTIVE within narrative: " + narrative.getDiv().toString(), narrative.getDiv().toString().indexOf("ACTIVE")>-1);