diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractSearchSet.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractSearchSet.java
index 9fdf9167d..817047c27 100644
--- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractSearchSet.java
+++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractSearchSet.java
@@ -3,6 +3,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
+import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -18,6 +19,7 @@
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.OperationOutcome.OperationOutcomeIssueComponent;
+import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.Task.ParameterComponent;
@@ -168,6 +170,19 @@ private int getCount(MultivaluedMap params, int defaultPageCount
return defaultPageCount;
}
+ protected final String getIdentifierValue(D resource, Function hasIdentifier,
+ Function getIdentifier)
+ {
+ Objects.requireNonNull(hasIdentifier, "hasIdentifier");
+ Objects.requireNonNull(getIdentifier, "getIdentifier");
+
+ if (!hasIdentifier.apply(resource))
+ return "";
+
+ Identifier identifier = getIdentifier.apply(resource);
+ return (identifier != null && identifier.hasValue()) ? identifier.getValue() : "";
+ }
+
protected final String getIdentifierValues(D resource,
Function hasIdentifier, Function> getIdentifier, String identifierSystem)
{
@@ -184,6 +199,24 @@ protected final String getIdentifierValues(D resource
return filteredIdentifiers.get(0) + (filteredIdentifiers.size() > 1 ? ", ..." : "");
}
+ protected final String getReferenceIdentifierValues(D resource,
+ Function hasReference, Function> getReference)
+ {
+ Objects.requireNonNull(hasReference, "hasReference");
+ Objects.requireNonNull(getReference, "getReference");
+
+ if (!hasReference.apply(resource))
+ return "";
+
+ List identifiers = getReference.apply(resource).stream().filter(Reference::hasIdentifier)
+ .map(Reference::getIdentifier).filter(Identifier::hasValue).map(Identifier::getValue).toList();
+
+ if (identifiers.isEmpty())
+ return "";
+
+ return identifiers.get(0) + (identifiers.size() > 1 ? ", ..." : "");
+ }
+
protected final String getResourceType(IIdType id)
{
return id != null ? id.getResourceType() : "";
diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractThymeleafContext.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractThymeleafContext.java
index 375da51fb..e68abce08 100644
--- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractThymeleafContext.java
+++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/AbstractThymeleafContext.java
@@ -18,8 +18,10 @@
import org.hl7.fhir.r4.model.DecimalType;
import org.hl7.fhir.r4.model.Enumeration;
import org.hl7.fhir.r4.model.Identifier;
+import org.hl7.fhir.r4.model.InstantType;
import org.hl7.fhir.r4.model.IntegerType;
import org.hl7.fhir.r4.model.PrimitiveType;
+import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
@@ -134,6 +136,12 @@ protected final String getDateTime(E resource, Predicate has
return formatDateTime(getValue(resource, hasDateTime, getDateTime));
}
+ protected final String getInstant(E resource, Predicate hasInstant,
+ Function getInstant)
+ {
+ return formatDateTime(getValue(resource, hasInstant, getInstant));
+ }
+
protected final Boolean getBoolean(E resource, Predicate hasBoolean,
Function getBoolean)
{
@@ -175,6 +183,19 @@ protected final String getEnumeration(E resource, Predicate
return e != null && e.hasCode() ? e.getCode() : null;
}
+ protected final ElementSystemValue getIdentifier(E resource, Predicate hasIdentifier,
+ Function getIdentifier)
+ {
+ Objects.requireNonNull(hasIdentifier, "hasIdentifier");
+ Objects.requireNonNull(getIdentifier, "getIdentifier");
+
+ if (resource == null || !hasIdentifier.test(resource))
+ return null;
+
+ Identifier identifier = getIdentifier.apply(resource);
+ return identifier != null ? ElementSystemValue.from(identifier) : null;
+ }
+
protected final List getIdentifiers(E resource, Predicate hasIdentifier,
Function> getIdentifier)
{
@@ -187,4 +208,20 @@ protected final List getIdentifiers(E resou
List identifier = getIdentifier.apply(resource);
return identifier != null ? identifier.stream().map(ElementSystemValue::from).toList() : null;
}
+
+ protected final List getReferenceIdentifiers(E resource,
+ Predicate hasReference, Function> getReference)
+ {
+ Objects.requireNonNull(hasReference, "hasReference");
+ Objects.requireNonNull(getReference, "getReference");
+
+ if (resource == null || !hasReference.test(resource))
+ return null;
+
+ List references = getReference.apply(resource);
+ return references != null
+ ? references.stream().filter(Reference::hasIdentifier).map(Reference::getIdentifier)
+ .map(ElementSystemValue::from).toList()
+ : null;
+ }
}
diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/ResourceDocumentReference.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/ResourceDocumentReference.java
new file mode 100644
index 000000000..ffc43767f
--- /dev/null
+++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/ResourceDocumentReference.java
@@ -0,0 +1,50 @@
+package dev.dsf.fhir.adapter;
+
+import java.util.List;
+
+import org.hl7.fhir.r4.model.Attachment;
+import org.hl7.fhir.r4.model.DocumentReference;
+
+public class ResourceDocumentReference extends AbstractResource
+{
+ private record AttachmentElement(String url, String contentType)
+ {
+ static AttachmentElement from(Attachment attachment)
+ {
+ return new AttachmentElement(attachment.getUrl(), attachment.getContentType());
+ }
+ }
+
+ private record Element(ElementSystemValue masterIdentifier, List identifier,
+ List author, String docStatus, String date, List attachment)
+ {
+ }
+
+ public ResourceDocumentReference()
+ {
+ super(DocumentReference.class, AbstractResource.ActiveOrStatus.status(DocumentReference::hasStatusElement,
+ DocumentReference::getStatusElement));
+ }
+
+ @Override
+ protected Element toElement(DocumentReference resource)
+ {
+ ElementSystemValue masterIdentifier = getIdentifier(resource, DocumentReference::hasMasterIdentifier,
+ DocumentReference::getMasterIdentifier);
+ List identifier = getIdentifiers(resource, DocumentReference::hasIdentifier,
+ DocumentReference::getIdentifier);
+
+ List author = getReferenceIdentifiers(resource, DocumentReference::hasAuthor,
+ DocumentReference::getAuthor);
+ String docStatus = resource.hasDocStatus() ? resource.getDocStatus().toCode() : null;
+
+ String date = getInstant(resource, DocumentReference::hasDate, DocumentReference::getDateElement);
+
+ List attachment = resource.getContent().stream()
+ .filter(DocumentReference.DocumentReferenceContentComponent::hasAttachment)
+ .map(DocumentReference.DocumentReferenceContentComponent::getAttachment).map(AttachmentElement::from)
+ .toList();
+
+ return new Element(masterIdentifier, nullIfEmpty(identifier), nullIfEmpty(author), docStatus, date, attachment);
+ }
+}
diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/SearchSetDocumentReference.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/SearchSetDocumentReference.java
new file mode 100644
index 000000000..087677890
--- /dev/null
+++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/adapter/SearchSetDocumentReference.java
@@ -0,0 +1,30 @@
+package dev.dsf.fhir.adapter;
+
+import org.hl7.fhir.r4.model.DocumentReference;
+
+public class SearchSetDocumentReference extends AbstractSearchSet
+{
+ private record Row(ElementId id, String masterIdentifier, String author, String status, String docStatus,
+ String lastUpdated)
+ {
+ }
+
+ public SearchSetDocumentReference(int defaultPageCount)
+ {
+ super(defaultPageCount, DocumentReference.class);
+ }
+
+ @Override
+ protected Row toRow(ElementId id, DocumentReference resource)
+ {
+ String masterIdentifier = getIdentifierValue(resource, DocumentReference::hasMasterIdentifier,
+ DocumentReference::getMasterIdentifier);
+ String author = getReferenceIdentifierValues(resource, DocumentReference::hasAuthor,
+ DocumentReference::getAuthor);
+ String status = resource.hasStatus() ? resource.getStatus().toCode() : "";
+ String docStatus = resource.hasDocStatus() ? resource.getDocStatus().toCode() : "";
+ String lastUpdated = formatLastUpdated(resource);
+
+ return new Row(id, masterIdentifier, author, status, docStatus, lastUpdated);
+ }
+}
diff --git a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/AdapterConfig.java b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/AdapterConfig.java
index d6bcc2d05..0bf4d359d 100755
--- a/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/AdapterConfig.java
+++ b/dsf-fhir/dsf-fhir-server/src/main/java/dev/dsf/fhir/spring/config/AdapterConfig.java
@@ -18,6 +18,7 @@
import dev.dsf.fhir.adapter.ResourceActivityDefinition;
import dev.dsf.fhir.adapter.ResourceBinary;
import dev.dsf.fhir.adapter.ResourceCodeSystem;
+import dev.dsf.fhir.adapter.ResourceDocumentReference;
import dev.dsf.fhir.adapter.ResourceEndpoint;
import dev.dsf.fhir.adapter.ResourceLibrary;
import dev.dsf.fhir.adapter.ResourceMeasure;
@@ -33,6 +34,7 @@
import dev.dsf.fhir.adapter.ResourceValueSet;
import dev.dsf.fhir.adapter.SearchSetActivityDefinition;
import dev.dsf.fhir.adapter.SearchSetBinary;
+import dev.dsf.fhir.adapter.SearchSetDocumentReference;
import dev.dsf.fhir.adapter.SearchSetEndpoint;
import dev.dsf.fhir.adapter.SearchSetMeasureReport;
import dev.dsf.fhir.adapter.SearchSetMetadataResource;
@@ -70,7 +72,7 @@ public ThymeleafTemplateService thymeleafTemplateService()
{
List thymeleafContexts = List.of(new ResourceActivityDefinition(),
new ResourceBinary(propertiesConfig.getDsfServerBaseUrl()), new ResourceCodeSystem(),
- new ResourceEndpoint(), new ResourceLibrary(), new ResourceMeasure(),
+ new ResourceDocumentReference(), new ResourceEndpoint(), new ResourceLibrary(), new ResourceMeasure(),
new ResourceMeasureReport(propertiesConfig.getDsfServerBaseUrl()), new ResourceNamingSystem(),
new ResourceOrganizationAffiliation(), new ResourceOrganization(), new ResourceQuestionnaire(),
new ResourceQuestionnaireResponse(), new ResourceStructureDefinition(), new ResourceSubscription(),
@@ -78,6 +80,7 @@ public ThymeleafTemplateService thymeleafTemplateService()
new SearchSetActivityDefinition(propertiesConfig.getDefaultPageCount()),
new SearchSetBinary(propertiesConfig.getDefaultPageCount()),
new SearchSetMetadataResource<>(propertiesConfig.getDefaultPageCount(), CodeSystem.class),
+ new SearchSetDocumentReference(propertiesConfig.getDefaultPageCount()),
new SearchSetEndpoint(propertiesConfig.getDefaultPageCount()),
new SearchSetMetadataResource<>(propertiesConfig.getDefaultPageCount(), Library.class),
new SearchSetMetadataResource<>(propertiesConfig.getDefaultPageCount(), Measure.class),
diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/bookmarks.js b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/bookmarks.js
index 531b57ac4..0b4ad6561 100644
--- a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/bookmarks.js
+++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/bookmarks.js
@@ -129,6 +129,7 @@ function getInitialBookmarks() {
'$ActivityDefinition': ['ActivityDefinition', "ActivityDefinition?_sort=status,url,version"],
'$Binary': ['Binary'],
'$CodeSystem': ['CodeSystem'],
+ '$DocumentReference': ['DocumentReference'],
'$Endpoint': ['Endpoint'],
'$NamingSystem': ['NamingSystem'],
'$Library': ['Library'],
diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/dsf.css b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/dsf.css
index 9bad98cb2..4bcb9cf86 100644
--- a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/dsf.css
+++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/static/dsf.css
@@ -452,6 +452,18 @@ pre.lang-html {
border-left-color: var(--color-row-border-grey);
}
+.bundle>#list>table tr[resource-type="DocumentReference"] td[status="current"] {
+ border-left-color: var(--color-row-border-green);
+}
+
+.bundle>#list>table tr[resource-type="DocumentReference"] td[status="superseded"] {
+ border-left-color: var(--color-row-border-grey);
+}
+
+.bundle>#list>table tr[resource-type="DocumentReference"] td[status="entered-in-error"] {
+ border-left-color: var(--color-row-border-red);
+}
+
.bundle>#list>table tr[resource-type="Endpoint"] td[status="active"] {
border-left-color: var(--color-row-border-green);
}
@@ -639,6 +651,21 @@ pre.lang-html {
color: var(--color-info-grey);
}
+#resource[resource-type="DocumentReference"][status="current"] #base-data {
+ background-color: var(--color-info-background-green);
+ color: var(--color-info-green);
+}
+
+#resource[resource-type="DocumentReference"][status="superseded"] #base-data {
+ background-color: var(--color-info-background-grey);
+ color: var(--color-info-grey);
+}
+
+#resource[resource-type="DocumentReference"][status="entered-in-error"] #base-data {
+ background-color: var(--color-info-background-red);
+ color: var(--color-info-red);
+}
+
#resource[resource-type="Endpoint"][status="active"] #base-data {
background-color: var(--color-info-background-green);
color: var(--color-info-green);
@@ -800,6 +827,18 @@ pre.lang-html {
fill: var(--color-info-grey);
}
+#resource[resource-type="DocumentReference"][status="current"] #base-data path {
+ fill: var(--color-info-green);
+}
+
+#resource[resource-type="DocumentReference"][status="superseded"] #base-data path {
+ fill: var(--color-info-grey);
+}
+
+#resource[resource-type="DocumentReference"][status="entered-in-error"] #base-data path {
+ fill: var(--color-info-red);
+}
+
#resource[resource-type="Endpoint"][status="active"] #base-data path {
fill: var(--color-info-green);
}
diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceDocumentReference.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceDocumentReference.html
new file mode 100644
index 000000000..863df4063
--- /dev/null
+++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceDocumentReference.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceElements.html b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceElements.html
index 4a2c252ca..64791bc6b 100644
--- a/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceElements.html
+++ b/dsf-fhir/dsf-fhir-server/src/main/resources/fhir/template/resourceElements.html
@@ -75,6 +75,21 @@
+
+
+
See json or xml for additional values.
+
+ | ID | Master Identifier | Author | Status | Document Status | Last Updated |
+
+ | id |
+ identifier |
+ name |
+ status |
+ docStatus |
+ lastUpdated |
+
+
+
+