Skip to content

Commit

Permalink
#369: reorganize Iti66 search parameter classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Ohr committed Dec 20, 2023
1 parent 557a35d commit 5625136
Show file tree
Hide file tree
Showing 13 changed files with 64 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
*/
public abstract class FhirSearchAndSortParameters<T extends IBaseResource> implements FhirSearchParameters {

@SuppressWarnings("unused")
public FhirSearchAndSortParameters() {
}

/**
* @return the sort specification as requested by the client
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
*/
abstract public class IgBasedInstanceValidator extends FhirTransactionValidator.Support {

private static final String STANDARD_PREFIX = "http://hl7.org/fhir/StructureDefinition/";
private final FhirContext fhirContext;

protected IgBasedInstanceValidator(FhirContext fhirContext) {
Expand All @@ -46,9 +47,9 @@ protected IgBasedInstanceValidator(FhirContext fhirContext) {
* @return {@link OperationOutcome} containing or not containing validation errors (never <code>null</code>).
*/
protected OperationOutcome validateProfileConformance(Resource resource, String profileUri) {
String standardPrefix = "http://hl7.org/fhir/StructureDefinition/";
if (profileUri.startsWith(standardPrefix)) {
String expectedResourceType = profileUri.substring(standardPrefix.length());

if (profileUri.startsWith(STANDARD_PREFIX)) {
String expectedResourceType = profileUri.substring(STANDARD_PREFIX.length());
if (resource.fhirType().equals(expectedResourceType)) {
return doValidate(resource);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.r4.model.Resource;
import org.openehealth.ipf.commons.ihe.fhir.mhd.MhdProfile;
import org.openehealth.ipf.commons.ihe.fhir.support.IgBasedInstanceValidator;

import java.util.Map;
Expand All @@ -40,6 +41,6 @@ public Iti105Validator(FhirContext fhirContext) {

@Override
public void validateRequest(Object payload, Map<String, Object> parameters) {
handleOperationOutcome(validateProfileConformance((Resource) payload, ITI105_PROFILE));
handleOperationOutcome(validateProfileConformance((Resource) payload, MhdProfile.SIMPLIFIED_PUBLISH_DOCUMENT_REFERENCE_PROFILE));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* @author Christian Ohr
* @since 3.6
*/
public class Iti66ResourceProvider extends AbstractPlainProvider {
public class Iti66DocumentManifestResourceProvider extends AbstractPlainProvider {

// Supported with MHD 3.2.0

Expand All @@ -60,7 +60,7 @@ public IBundleProvider documentManifestSearch(
HttpServletResponse httpServletResponse) {


var searchParameters = Iti66SearchParameters.builder()
var searchParameters = Iti66DocumentManifestSearchParameters.builder()
.created(created)
.type(type)
.source(source)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* @author Christian Ohr
* @since 4.8
*/
public class Iti66ListResourceProvider extends Iti66ResourceProvider {
public class Iti66ListResourceProvider extends AbstractPlainProvider {

// Supported as of MHD 4.2.1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,52 +20,43 @@
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.param.*;
import lombok.*;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hl7.fhir.r4.model.ListResource;
import org.hl7.fhir.r4.model.Practitioner;
import org.openehealth.ipf.commons.ihe.fhir.FhirSearchAndSortParameters;

import java.util.*;

import static java.util.Comparator.comparing;
import static java.util.Comparator.nullsLast;

/**
* @since 3.6
* @since 4.8
*/
@Builder
@ToString
@AllArgsConstructor
public class Iti66ListSearchParameters extends FhirSearchAndSortParameters<ListResource> {
public class Iti66ListSearchParameters extends Iti66SearchParameters<ListResource> {

@Getter @Setter private DateRangeParam date;
@Getter @Setter private StringParam authorFamilyName;
@Getter @Setter private StringParam authorGivenName;
@Getter @Setter private TokenOrListParam code;
@Getter @Setter private TokenOrListParam designationType;
@Getter @Setter private TokenOrListParam sourceId;
@Getter @Setter private TokenOrListParam status;
@Getter @Setter private TokenParam identifier;
@Getter @Setter private TokenParam _id;
@Getter @Setter private ReferenceParam patientReference;
@Getter @Setter private TokenParam patientIdentifier;
@Getter @Setter private TokenParam _id;

@Getter @Setter private StringParam authorFamilyName;
@Getter @Setter private StringParam authorGivenName;
@Getter @Setter private SortSpec sortSpec;
@Getter @Setter private Set<Include> includeSpec;

@Getter
private final FhirContext fhirContext;

@Override
public List<TokenParam> getPatientIdParam() {
if (_id != null)
return Collections.singletonList(_id);
if (patientReference != null)
return Collections.singletonList(patientReference.toTokenParam(fhirContext));

return Collections.singletonList(patientIdentifier);
}

public Iti66ListSearchParameters setAuthor(ReferenceAndListParam author) {
if (author != null) {
author.getValuesAsQueryTokens().forEach(param -> {
Expand All @@ -81,6 +72,16 @@ public Iti66ListSearchParameters setAuthor(ReferenceAndListParam author) {
return this;
}

@Override
public List<TokenParam> getPatientIdParam() {
if (_id != null)
return Collections.singletonList(_id);
if (patientReference != null)
return Collections.singletonList(patientReference.toTokenParam(fhirContext));

return Collections.singletonList(patientIdentifier);
}

@Override
public Optional<Comparator<ListResource>> comparatorFor(String paramName) {
if (ListResource.SP_DATE.equals(paramName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@ public enum Iti66Options implements FhirTransactionOptions {
/**
* Lenient MHD 3.2.0 Resource Provider, supporting some search parameters from STU3 versions
*/
LENIENT(Iti66ResourceProvider.class),
LENIENT(Iti66DocumentManifestResourceProvider.class),

/**
* MHD 4.2.1 Resource Provider, supporting querying List resources
*/
LIST(Iti66ListResourceProvider.class),

/**
* MHD 3.2.0 and 4.2.1 Resource Provider, supporting both DocumentManifest and List resources
*/
COMPATIBILITY(Iti66ListResourceProvider.class);
COMPATIBILITY(Iti66ListResourceProvider.class, Iti66DocumentManifestResourceProvider.class);

private final List<Class<? extends FhirProvider>> resourceProviders;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,114 +13,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.openehealth.ipf.commons.ihe.fhir.iti66;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hl7.fhir.r4.model.DocumentManifest;
import lombok.experimental.SuperBuilder;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.PractitionerRole;
import org.openehealth.ipf.commons.ihe.fhir.FhirSearchAndSortParameters;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static java.util.Comparator.comparing;
import static java.util.Comparator.nullsLast;

/**
* @since 3.6
* Common SearchParameter base class for ITI-66 transactions
* @param <T>
*/
@Builder
@ToString
@AllArgsConstructor
public class Iti66SearchParameters extends FhirSearchAndSortParameters<DocumentManifest> {

@Getter @Setter private DateRangeParam created;
@Getter @Setter private StringParam authorFamilyName;
@Getter @Setter private StringParam authorGivenName;
@Getter @Setter private TokenOrListParam type;
@Getter @Setter private TokenOrListParam source;
@Getter @Setter private TokenOrListParam status;
@Getter @Setter private TokenParam identifier;
@Getter @Setter private ReferenceParam patientReference;
@Getter @Setter private TokenParam patientIdentifier;
@Getter @Setter private TokenParam _id;

@Getter @Setter private SortSpec sortSpec;
@Getter @Setter private Set<Include> includeSpec;

@Getter
private final FhirContext fhirContext;

@Override
public List<TokenParam> getPatientIdParam() {
if (_id != null)
return Collections.singletonList(_id);
if (patientReference != null)
return Collections.singletonList(patientReference.toTokenParam(fhirContext));

return Collections.singletonList(patientIdentifier);
}

public Iti66SearchParameters setAuthor(ReferenceAndListParam author) {
if (author != null) {
author.getValuesAsQueryTokens().forEach(param -> {
var ref = param.getValuesAsQueryTokens().get(0);
var authorChain = ref.getChain();
if (Practitioner.SP_FAMILY.equals(authorChain)) {
setAuthorFamilyName(ref.toStringParam(getFhirContext()));
} else if (Practitioner.SP_GIVEN.equals(authorChain)) {
setAuthorGivenName(ref.toStringParam(getFhirContext()));
}
});
}
return this;
}
public abstract class Iti66SearchParameters<T extends IBaseResource> extends FhirSearchAndSortParameters<T> {

@Override
public Optional<Comparator<DocumentManifest>> comparatorFor(String paramName) {
if (DocumentManifest.SP_CREATED.equals(paramName)) {
return Optional.of(CP_CREATED);
} else if (DocumentManifest.SP_AUTHOR.equals(paramName)) {
return Optional.of(CP_AUTHOR);
}
return Optional.empty();
}
public abstract Iti66SearchParameters<T> setAuthor(ReferenceAndListParam author);

private static final Comparator<DocumentManifest> CP_CREATED = nullsLast(comparing(DocumentManifest::getCreated));
public abstract FhirContext getFhirContext();

private static final Comparator<DocumentManifest> CP_AUTHOR = nullsLast(comparing(documentManifest -> {
if (!documentManifest.hasAuthor()) return null;
var author = documentManifest.getAuthorFirstRep();
if (author.getResource() instanceof PractitionerRole) {
var practitionerRole = (PractitionerRole) author.getResource();
if (!practitionerRole.hasPractitioner()) return null;
author = practitionerRole.getPractitioner();
}
if (author.getResource() == null) return null;
if (author.getResource() instanceof Practitioner) {
var practitioner = (Practitioner) author.getResource();
if (!practitioner.hasName()) return null;
var name = practitioner.getNameFirstRep();
return name.getFamilyElement().getValueNotNull() + name.getGivenAsSingleString();
}
return null;
}));
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public IBundleProvider documentManifestSearch(
HttpServletResponse httpServletResponse) {


var searchParameters = Iti66SearchParameters.builder()
var searchParameters = Iti66DocumentManifestSearchParameters.builder()
.created(created)
.type(type)
.source(source)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.openehealth.ipf.commons.ihe.fhir.FhirTransactionValidator;
import org.openehealth.ipf.commons.ihe.fhir.audit.FhirQueryAuditDataset;

import java.util.Arrays;

/**
* Standard Configuration for Iti66Component. Supports lazy-loading by default.
*
Expand All @@ -30,12 +32,12 @@ public class Iti66TransactionConfiguration extends FhirTransactionConfiguration<

public Iti66TransactionConfiguration() {
super("mhd-iti66",
"Find Document Manifests",
"Find Document Manifests or Lists",
true,
new Iti66AuditStrategy(false),
new Iti66AuditStrategy(true),
FhirVersionEnum.R4,
new Iti66ListResourceProvider(),
Arrays.asList(new Iti66ListResourceProvider(), new Iti66DocumentManifestResourceProvider()),
new Iti66ClientRequestFactory(),
FhirTransactionValidator.NO_VALIDATION);
setSupportsLazyLoading(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import org.hl7.fhir.r4.model.Reference;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openehealth.ipf.commons.ihe.fhir.mhd.MhdProfile;
import org.openehealth.ipf.commons.ihe.fhir.mhd.MhdProfiles;
import org.openehealth.ipf.commons.ihe.fhir.mhd.MhdValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -37,6 +40,7 @@ public class Iti105ValidatorTest {
@BeforeAll
static void beforeAll() {
var context = FhirContext.forR4();
MhdProfile.registerDefaultTypes(context);
iti105Validator = new Iti105Validator(context);
}

Expand All @@ -47,7 +51,7 @@ void testValidConformance() {

@Test
void testInvalidConformance() throws Exception {
var documentReference = invalidDocumentreference();
var documentReference = invalidDocumentReference();
UnprocessableEntityException exception = assertThrows(UnprocessableEntityException.class, () ->
iti105Validator.validateRequest(documentReference, new HashMap<>())
);
Expand All @@ -57,12 +61,12 @@ void testInvalidConformance() throws Exception {
}

private static DocumentReference validDocumentreference() throws NoSuchAlgorithmException {
var reference = invalidDocumentreference();
reference.getMeta().addProfile(Iti105Validator.ITI105_PROFILE);
var reference = invalidDocumentReference();
reference.getMeta().addProfile(MhdProfile.SIMPLIFIED_PUBLISH_DOCUMENT_REFERENCE_PROFILE);
return reference;
}

private static DocumentReference invalidDocumentreference() throws NoSuchAlgorithmException {
private static DocumentReference invalidDocumentReference() throws NoSuchAlgorithmException {
var documentContent = "Hello IHE World".getBytes();
var practitioner = new Practitioner();
var reference = new DocumentReference();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
/**
* @author Christian Ohr
*/
public class Iti66SearchParametersTest {
public class Iti66DocumentManifestSearchParametersTest {

@Test
public void setAuthor() {
var searchParameters = Iti66SearchParameters.builder().build();
var searchParameters = Iti66DocumentManifestSearchParameters.builder().build();

var param = new ReferenceAndListParam()
.addAnd(new ReferenceOrListParam()
Expand Down
Loading

0 comments on commit 5625136

Please sign in to comment.