Merge branch 'ng_resource_flattening' into 2478_add_extension_mdm_matcher

This commit is contained in:
Nick Goupinets 2021-03-19 18:15:25 -04:00
commit ba835c7cac
5 changed files with 186 additions and 12 deletions

View File

@ -30,7 +30,9 @@ import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@ -56,6 +58,34 @@ public class ExtensionUtil {
return extension;
}
/**
* Returns an new empty extension.
*
* @param theBase Base resource to add the extension to
* @return Returns a new extension
* @throws IllegalArgumentException IllegalArgumentException is thrown in case resource doesn't support extensions
*/
public static IBaseExtension<?, ?> addExtension(IBase theBase) {
return addExtension(theBase, null);
}
/**
* Returns an extension with the specified URL
*
* @param theBase Base resource to add the extension to
* @param theUrl URL for the extension
* @return Returns a new extension with the specified URL.
* @throws IllegalArgumentException IllegalArgumentException is thrown in case resource doesn't support extensions
*/
public static IBaseExtension<?, ?> addExtension(IBase theBase, String theUrl) {
IBaseHasExtensions baseHasExtensions = validateExtensionSupport(theBase);
IBaseExtension extension = baseHasExtensions.addExtension();
if (theUrl != null) {
extension.setUrl(theUrl);
}
return extension;
}
private static IBaseHasExtensions validateExtensionSupport(IBase theBase) {
if (!(theBase instanceof IBaseHasExtensions)) {
throw new IllegalArgumentException(String.format("Expected instance that supports extensions, but got %s", theBase));
@ -106,14 +136,60 @@ public class ExtensionUtil {
* @param theExtensionUrl URL of the extension to get. Must be non-null
* @return Returns the first available extension with the specified URL, or null if such extension doesn't exist
*/
public static IBaseExtension<?, ?> getExtension(IBaseHasExtensions theBase, String theExtensionUrl) {
return theBase.getExtension()
public static IBaseExtension<?, ?> getExtension(IBase theBase, String theExtensionUrl) {
Predicate<IBaseExtension> filter;
if (theExtensionUrl == null) {
filter = (e -> true);
} else {
filter = (e -> theExtensionUrl.equals(e.getUrl()));
}
return getExtensions(theBase, filter)
.stream()
.filter(e -> theExtensionUrl.equals(e.getUrl()))
.findFirst()
.orElse(null);
}
/**
* Gets all extensions that match the specified filter predicate
*
* @param theBase The resource to get the extension for
* @param theFilter Predicate to match the extension against
* @return Returns all extension with the specified URL, or an empty list if such extensions do not exist
*/
public static List<IBaseExtension<?, ?>> getExtensions(IBase theBase, Predicate<? super IBaseExtension> theFilter) {
return validateExtensionSupport(theBase)
.getExtension()
.stream()
.filter(theFilter)
.collect(Collectors.toList());
}
/**
* Removes all extensions.
*
* @param theBase The resource to clear the extension for
* @return Returns all extension that were removed
*/
public static List<IBaseExtension<?, ?>> clearExtensions(IBase theBase) {
return clearExtensions(theBase, (e -> true));
}
/**
* Removes all extensions that match the specified predicate
*
* @param theBase The base object to clear the extension for
* @param theFilter Defines which extensions should be cleared
* @return Returns all extension that were removed
*/
public static List<IBaseExtension<?, ?>> clearExtensions(IBase theBase, Predicate<? super IBaseExtension> theFilter) {
List<IBaseExtension<?, ?>> retVal = getExtensions(theBase, theFilter);
validateExtensionSupport(theBase)
.getExtension()
.removeIf(theFilter);
return retVal;
}
/**
* Gets all extensions with the specified URL
*
@ -122,10 +198,8 @@ public class ExtensionUtil {
* @return Returns all extension with the specified URL, or an empty list if such extensions do not exist
*/
public static List<IBaseExtension<?, ?>> getExtensions(IBaseHasExtensions theBase, String theExtensionUrl) {
return theBase.getExtension()
.stream()
.filter(e -> theExtensionUrl.equals(e.getUrl()))
.collect(Collectors.toList());
Predicate<IBaseExtension> urlEqualityPredicate = e -> theExtensionUrl.equals(e.getUrl());
return getExtensions(theBase, urlEqualityPredicate);
}
/**

View File

@ -98,12 +98,12 @@ public final class TerserUtil {
}
/**
* get the Values of a specified field.
* Gets all values of the specified field.
*
* @param theFhirContext Context holding resource definition
* @param theResource Resource to check if the specified field is set
* @param theFieldName name of the field to check
* @return Returns true if field exists and has any values set, and false otherwise
* @return Returns all values for the specified field or null if field with the provided name doesn't exist
*/
public static List<IBase> getValues(FhirContext theFhirContext, IBaseResource theResource, String theFieldName) {
RuntimeResourceDefinition resourceDefinition = theFhirContext.getResourceDefinition(theResource);
@ -115,6 +115,23 @@ public final class TerserUtil {
return resourceIdentifier.getAccessor().getValues(theResource);
}
/**
* Gets the first available value for the specified field.
*
* @param theFhirContext Context holding resource definition
* @param theResource Resource to check if the specified field is set
* @param theFieldName name of the field to check
* @return Returns the first value for the specified field or null if field with the provided name doesn't exist or
* has no values
*/
public static IBase getValue(FhirContext theFhirContext, IBaseResource theResource, String theFieldName) {
List<IBase> values = getValues(theFhirContext, theResource, theFieldName);
if (values == null || values.isEmpty()) {
return null;
}
return values.get(0);
}
/**
* Clones specified composite field (collection). Composite field values must conform to the collections
* contract.
@ -274,6 +291,20 @@ public final class TerserUtil {
childDefinition.getAccessor().getValues(theResource).clear();
}
/**
* Sets the provided field with the given values. This method will add to the collection of existing field values
* in case of multiple cardinality. Use {@link #clearField(FhirContext, FhirTerser, String, IBaseResource, IBase...)}
* to remove values before setting
*
* @param theFhirContext Context holding resource definition
* @param theFieldName Child field name of the resource to set
* @param theResource The resource to set the values on
* @param theValues The values to set on the resource child field name
*/
public static void setField(FhirContext theFhirContext, String theFieldName, IBaseResource theResource, IBase... theValues) {
setField(theFhirContext, theFhirContext.newTerser(), theFieldName, theResource, theValues);
}
/**
* Sets the provided field with the given values. This method will add to the collection of existing field values
* in case of multiple cardinality. Use {@link #clearField(FhirContext, FhirTerser, String, IBaseResource, IBase...)}
@ -321,6 +352,18 @@ public final class TerserUtil {
setFieldByFhirPath(theFhirContext.newTerser(), theFhirPath, theResource, theValue);
}
public static List<IBase> getFieldByFhirPath(FhirContext theFhirContext, String theFhirPath, IBase theResource) {
return theFhirContext.newTerser().getValues(theResource, theFhirPath, false, false);
}
public static IBase getFirstFieldByFhirPath(FhirContext theFhirContext, String theFhirPath, IBase theResource) {
List<IBase> values = getFieldByFhirPath(theFhirContext, theFhirPath, theResource);
if (values == null || values.isEmpty()) {
return null;
}
return values.get(0);
}
private static void replaceField(IBaseResource theFrom, IBaseResource theTo, BaseRuntimeChildDefinition childDefinition) {
childDefinition.getAccessor().getFirstValueOrNull(theFrom).ifPresent(v -> {
childDefinition.getMutator().setValue(theTo, v);

View File

@ -108,15 +108,50 @@ public class TerserUtilHelper {
}
/**
* Gets values of the specified field.
* Gets values for the specified child field.
*
* @param theField The field to get values from
* @return Returns a collection of values containing values or null if the spefied field doesn't exist
* @return Returns a list of retrieved values or null if the specified field doesn't exist
*/
public List<IBase> getFieldValues(String theField) {
return TerserUtil.getValues(myContext, myResource, theField);
}
/**
* Gets values for the specified field values by FHIRPath.
*
* @param theFhirPath The FHIR path expression to get the values from
* @return Returns a collection of values or null if the specified field doesn't exist
*/
public List<IBase> getFieldValuesByFhirPath(String theFhirPath) {
return TerserUtil.getFieldByFhirPath(myContext, theFhirPath, myResource);
}
/**
* Gets first available value for the specified field values by FHIRPath.
*
* @param theFhirPath The FHIR path expression to get the values from
* @return Returns the value or null if the specified field doesn't exist or is empty
*/
public IBase getFieldValueByFhirPath(String theFhirPath) {
return TerserUtil.getFirstFieldByFhirPath(myContext, theFhirPath, myResource);
}
/**
* Gets first available values of the specified field.
*
* @param theField The field to get values from
* @return Returns the first available value for the field name or null if the
* specified field doesn't exist or has no values
*/
public IBase getFieldValue(String theField) {
List<IBase> values = getFieldValues(theField);
if (values == null || values.isEmpty()) {
return null;
}
return values.get(0);
}
/**
* Gets the terser instance, creating one if necessary.
*

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao.data;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
* %%
* 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 ca.uhn.fhir.jpa.entity.TermValueSetConceptViewOracle;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

View File

@ -57,9 +57,11 @@ class TerserUtilTest {
assertEquals(1, p2Helper.getFieldValues("identifier").size());
Identifier id1 = (Identifier) p1Helper.getFieldValues("identifier").get(0);
Identifier id2 = (Identifier) p2Helper.getFieldValues("identifier").get(0);
Identifier id2 = (Identifier) p2Helper.getFieldValue("identifier");
assertTrue(id1.equalsDeep(id2));
assertFalse(id1.equals(id2));
assertNull(p2Helper.getFieldValue("address"));
}
@Test