o2) {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
index 734a7f92c8e..be2fc9c3aac 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
@@ -75,10 +75,64 @@ public class DaoConfig {
private boolean myDeleteStaleSearches = true;
private boolean myEnforceReferentialIntegrityOnDelete = true;
+ private boolean myUniqueIndexesEnabled = true;
+ /**
+ * If set to true
(default is true
), indexes will be
+ * created for search parameters marked as {@link ca.uhn.fhir.jpa.util.JpaConstants#EXT_SP_UNIQUE}.
+ * This is a HAPI FHIR specific extension which can be used to specify that no more than one
+ * resource can exist which matches a given criteria, using a database constraint to
+ * enforce this.
+ */
+ public boolean isUniqueIndexesEnabled() {
+ return myUniqueIndexesEnabled;
+ }
+
+ /**
+ * If set to true
(default is true
), indexes will be
+ * created for search parameters marked as {@link ca.uhn.fhir.jpa.util.JpaConstants#EXT_SP_UNIQUE}.
+ * This is a HAPI FHIR specific extension which can be used to specify that no more than one
+ * resource can exist which matches a given criteria, using a database constraint to
+ * enforce this.
+ */
+ public void setUniqueIndexesEnabled(boolean theUniqueIndexesEnabled) {
+ myUniqueIndexesEnabled = theUniqueIndexesEnabled;
+ }
+
+ /**
+ * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
+ * setting is set to true
(default is true
) the system
+ * will test for the existence of a particular unique index value prior to saving
+ * a new one.
+ *
+ * This causes friendlier error messages to be generated, but adds an
+ * extra round-trip to the database for eavh save so it can cause
+ * a small performance hit.
+ *
+ */
+ public boolean isUniqueIndexesCheckedBeforeSave() {
+ return myUniqueIndexesCheckedBeforeSave;
+ }
+
+ /**
+ * When using {@link #setUniqueIndexesEnabled(boolean) unique indexes}, if this
+ * setting is set to true
(default is true
) the system
+ * will test for the existence of a particular unique index value prior to saving
+ * a new one.
+ *
+ * This causes friendlier error messages to be generated, but adds an
+ * extra round-trip to the database for eavh save so it can cause
+ * a small performance hit.
+ *
+ */
+ public void setUniqueIndexesCheckedBeforeSave(boolean theUniqueIndexesCheckedBeforeSave) {
+ myUniqueIndexesCheckedBeforeSave = theUniqueIndexesCheckedBeforeSave;
+ }
+
+ private boolean myUniqueIndexesCheckedBeforeSave = true;
private boolean myEnforceReferentialIntegrityOnWrite = true;
-
private int myEverythingIncludesFetchPageSize = 50;
+
/**
* update setter javadoc if default changes
*/
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
index eace417ea9b..d9d36c3f608 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
@@ -1258,33 +1258,35 @@ public class SearchBuilder implements ISearchBuilder {
* Check if there is a unique key associated with the set
* of parameters passed in
*/
- if (myParams.getIncludes().isEmpty()) {
- if (myParams.getRevIncludes().isEmpty()) {
- if (myParams.getEverythingMode() == null) {
- if (myParams.isAllParametersHaveNoModifier()) {
- Set paramNames = theParams.keySet();
- if (paramNames.isEmpty() == false) {
- List searchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, paramNames);
- if (searchParams.size() > 0) {
- List> params = new ArrayList<>();
- for (Entry>> nextParamNameToValues : theParams.entrySet()) {
- String nextParamName = nextParamNameToValues.getKey();
- nextParamName = UrlUtil.escape(nextParamName);
- for (List extends IQueryParameterType> nextAnd : nextParamNameToValues.getValue()) {
- ArrayList nextValueList = new ArrayList<>();
- params.add(nextValueList);
- for (IQueryParameterType nextOr : nextAnd) {
- String nextOrValue = nextOr.getValueAsQueryToken(myContext);
- nextOrValue = UrlUtil.escape(nextOrValue);
- nextValueList.add(nextParamName + "=" + nextOrValue);
+ if (myCallingDao.getConfig().isUniqueIndexesEnabled()) {
+ if (myParams.getIncludes().isEmpty()) {
+ if (myParams.getRevIncludes().isEmpty()) {
+ if (myParams.getEverythingMode() == null) {
+ if (myParams.isAllParametersHaveNoModifier()) {
+ Set paramNames = theParams.keySet();
+ if (paramNames.isEmpty() == false) {
+ List searchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, paramNames);
+ if (searchParams.size() > 0) {
+ List> params = new ArrayList<>();
+ for (Entry>> nextParamNameToValues : theParams.entrySet()) {
+ String nextParamName = nextParamNameToValues.getKey();
+ nextParamName = UrlUtil.escape(nextParamName);
+ for (List extends IQueryParameterType> nextAnd : nextParamNameToValues.getValue()) {
+ ArrayList nextValueList = new ArrayList<>();
+ params.add(nextValueList);
+ for (IQueryParameterType nextOr : nextAnd) {
+ String nextOrValue = nextOr.getValueAsQueryToken(myContext);
+ nextOrValue = UrlUtil.escape(nextOrValue);
+ nextValueList.add(nextParamName + "=" + nextOrValue);
+ }
}
}
+
+ Set uniqueQueryStrings = BaseHapiFhirDao.extractCompositeStringUniquesValueChains(myResourceName, params);
+ ourLastHandlerMechanismForUnitTest = HandlerTypeEnum.UNIQUE_INDEX;
+ return new UniqueIndexIterator(uniqueQueryStrings);
+
}
-
- Set uniqueQueryStrings = BaseHapiFhirDao.extractCompositeStringUniquesValueChains(myResourceName, params);
- ourLastHandlerMechanismForUnitTest = HandlerTypeEnum.UNIQUE_INDEX;
- return new UniqueIndexIterator(uniqueQueryStrings);
-
}
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java
index 01b06e06048..911ec59a14a 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java
@@ -58,7 +58,7 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3 fetchAllConformanceResources(FhirContext theContext) {
+ return null;
+ }
+
+ @Override
+ @Transactional(value = TxType.SUPPORTS)
+ public List fetchAllStructureDefinitions(FhirContext theContext) {
+ return Collections.emptyList();
+ }
+
@Override
public CodeSystem fetchCodeSystem(FhirContext theCtx, String theSystem) {
return fetchResource(theCtx, CodeSystem.class, theSystem);
@@ -103,7 +111,7 @@ public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3 {
params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
- search = myValueSetDao.search(params);
+ search = myValueSetDao.search(params);
}
} else {
SearchParameterMap params = new SearchParameterMap();
@@ -145,28 +153,20 @@ public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3 {
}
@Override
- @Transactional(value=TxType.SUPPORTS)
+ public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
+ return fetchResource(theCtx, StructureDefinition.class, theUrl);
+ }
+
+ @Override
+ @Transactional(value = TxType.SUPPORTS)
public boolean isCodeSystemSupported(FhirContext theCtx, String theSystem) {
return false;
}
@Override
- @Transactional(value=TxType.SUPPORTS)
+ @Transactional(value = TxType.SUPPORTS)
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
return null;
}
-
- @Override
- public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
- return fetchResource(theCtx, StructureDefinition.class, theUrl);
- }
-
-
- @Override
- @Transactional(value=TxType.SUPPORTS)
- public List fetchAllStructureDefinitions(FhirContext theContext) {
- return Collections.emptyList();
- }
-
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java
index d76ea7a5140..20070c88268 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java
@@ -60,7 +60,7 @@ public class FhirResourceDaoSearchParameterR4 extends FhirResourceDaoR4 fetchAllConformanceResources(FhirContext theContext) {
+ return null;
+ }
+
+ @Override
+ @Transactional(value = TxType.SUPPORTS)
+ public List fetchAllStructureDefinitions(FhirContext theContext) {
+ return Collections.emptyList();
+ }
+
@Override
public CodeSystem fetchCodeSystem(FhirContext theCtx, String theSystem) {
return fetchResource(theCtx, CodeSystem.class, theSystem);
@@ -103,7 +111,7 @@ public class JpaValidationSupportR4 implements IJpaValidationSupportR4 {
params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
- search = myValueSetDao.search(params);
+ search = myValueSetDao.search(params);
}
} else {
SearchParameterMap params = new SearchParameterMap();
@@ -145,28 +153,20 @@ public class JpaValidationSupportR4 implements IJpaValidationSupportR4 {
}
@Override
- @Transactional(value=TxType.SUPPORTS)
+ public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
+ return fetchResource(theCtx, StructureDefinition.class, theUrl);
+ }
+
+ @Override
+ @Transactional(value = TxType.SUPPORTS)
public boolean isCodeSystemSupported(FhirContext theCtx, String theSystem) {
return false;
}
@Override
- @Transactional(value=TxType.SUPPORTS)
+ @Transactional(value = TxType.SUPPORTS)
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
return null;
}
-
- @Override
- public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
- return fetchResource(theCtx, StructureDefinition.class, theUrl);
- }
-
-
- @Override
- @Transactional(value=TxType.SUPPORTS)
- public List fetchAllStructureDefinitions(FhirContext theContext) {
- return Collections.emptyList();
- }
-
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedCompositeStringUnique.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedCompositeStringUnique.java
index 3f7c7f4a0a7..3a44fafebfd 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedCompositeStringUnique.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedCompositeStringUnique.java
@@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.entity;
+import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.*;
import org.hl7.fhir.r4.model.Resource;
@@ -88,6 +89,7 @@ public class ResourceIndexedCompositeStringUnique implements Comparable extends BaseJpaProvider {
public static final String MARK_ALL_RESOURCES_FOR_REINDEXING = "$mark-all-resources-for-reindexing";
+ public static final String PERFORM_REINDEXING_PASS = "$perform-reindexing-pass";
private IFhirSystemDao myDao;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProviderDstu2Plus.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProviderDstu2Plus.java
index 37897210d11..e8ad50fbc6f 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProviderDstu2Plus.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaSystemProviderDstu2Plus.java
@@ -30,11 +30,9 @@ import ca.uhn.fhir.util.ParametersUtil;
public abstract class BaseJpaSystemProviderDstu2Plus extends BaseJpaSystemProvider {
- //@formatter:off
@Operation(name=MARK_ALL_RESOURCES_FOR_REINDEXING, idempotent=true, returnParameters= {
@OperationParam(name="status")
})
- //@formatter:on
public IBaseResource markAllResourcesForReindexing() {
int count = getDao().markAllResourcesForReindexing();
@@ -42,9 +40,22 @@ public abstract class BaseJpaSystemProviderDstu2Plus extends BaseJpaSyste
IPrimitiveType> string = ParametersUtil.createString(getContext(), "Marked " + count + " resources");
ParametersUtil.addParameterToParameters(getContext(), retVal, string, "status");
-
+
+ return retVal;
+ }
+
+ @Operation(name=PERFORM_REINDEXING_PASS, idempotent=true, returnParameters= {
+ @OperationParam(name="status")
+ })
+ public IBaseResource performReindexingPass() {
+ int count = getDao().performReindexingPass(1000);
+
+ IBaseParameters retVal = ParametersUtil.newInstance(getContext());
+
+ IPrimitiveType> string = ParametersUtil.createString(getContext(), "Indexed " + count + " resources");
+ ParametersUtil.addParameterToParameters(getContext(), retVal, string, "status");
+
return retVal;
}
-
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java
index 57cbbec2c73..a8ac39a2600 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java
@@ -254,6 +254,11 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
return retVal;
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ return null;
+ }
+
@Override
public List expandValueSet(String theValueSet) {
ValueSet source = new ValueSet();
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java
index 990d7d60750..45189318700 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java
@@ -1,5 +1,43 @@
package ca.uhn.fhir.jpa.term;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.jpa.dao.DaoMethodOutcome;
+import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
+import ca.uhn.fhir.jpa.entity.ResourceTable;
+import ca.uhn.fhir.jpa.entity.TermCodeSystem;
+import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
+import ca.uhn.fhir.jpa.entity.TermConcept;
+import ca.uhn.fhir.jpa.util.StopWatch;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import ca.uhn.fhir.util.CoverageIgnore;
+import ca.uhn.fhir.util.UrlUtil;
+import org.apache.lucene.search.Query;
+import org.hibernate.search.jpa.FullTextEntityManager;
+import org.hibernate.search.jpa.FullTextQuery;
+import org.hibernate.search.query.dsl.BooleanJunction;
+import org.hibernate.search.query.dsl.QueryBuilder;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
+import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
+import org.hl7.fhir.r4.model.CodeSystem;
+import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode;
+import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent;
+import org.hl7.fhir.r4.model.StructureDefinition;
+import org.hl7.fhir.r4.model.ValueSet;
+import org.hl7.fhir.r4.model.ValueSet.*;
+import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
+import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@@ -12,9 +50,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* 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.
@@ -22,36 +60,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* limitations under the License.
* #L%
*/
-import java.util.*;
-
-import org.apache.lucene.search.Query;
-import org.hibernate.search.jpa.FullTextEntityManager;
-import org.hibernate.search.jpa.FullTextQuery;
-import org.hibernate.search.query.dsl.BooleanJunction;
-import org.hibernate.search.query.dsl.QueryBuilder;
-import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
-import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
-import org.hl7.fhir.r4.model.*;
-import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode;
-import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent;
-import org.hl7.fhir.r4.model.ValueSet.*;
-import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
-import org.hl7.fhir.instance.model.api.IBaseResource;
-import org.hl7.fhir.instance.model.api.IIdType;
-import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.fhir.jpa.dao.*;
-import ca.uhn.fhir.jpa.entity.*;
-import ca.uhn.fhir.jpa.util.StopWatch;
-import ca.uhn.fhir.rest.api.server.RequestDetails;
-import ca.uhn.fhir.rest.server.exceptions.*;
-import ca.uhn.fhir.util.CoverageIgnore;
-import ca.uhn.fhir.util.UrlUtil;
public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IValidationSupport, IHapiTerminologySvcR4 {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HapiTerminologySvcR4.class);
@@ -63,6 +71,15 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
@Autowired
private IValidationSupport myValidationSupport;
+ private void addAllChildren(String theSystemString, ConceptDefinitionComponent theCode, List theListToPopulate) {
+ if (isNotBlank(theCode.getCode())) {
+ theListToPopulate.add(new VersionIndependentConcept(theSystemString, theCode.getCode()));
+ }
+ for (ConceptDefinitionComponent nextChild : theCode.getConcept()) {
+ addAllChildren(theSystemString, nextChild, theListToPopulate);
+ }
+ }
+
private void addCodeIfNotAlreadyAdded(String system, ValueSetExpansionComponent retVal, Set addedCodes, TermConcept nextConcept) {
if (addedCodes.add(nextConcept.getCode())) {
ValueSetExpansionContainsComponent contains = retVal.addContains();
@@ -72,36 +89,20 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
}
}
- @Override
- protected List findCodesBelowUsingBuiltInSystems(String theSystem, String theCode) {
- ArrayList retVal = new ArrayList();
- CodeSystem system = myValidationSupport.fetchCodeSystem(myContext, theSystem);
- if (system != null) {
- findCodesBelow(system, theSystem, theCode, retVal);
- }
- return retVal;
+ private void addDisplayFilterExact(QueryBuilder qb, BooleanJunction> bool, ConceptSetFilterComponent nextFilter) {
+ bool.must(qb.phrase().onField("myDisplay").sentence(nextFilter.getValue()).createQuery());
}
- private void findCodesBelow(CodeSystem theSystem, String theSystemString, String theCode, List theListToPopulate) {
- List conceptList = theSystem.getConcept();
- findCodesBelow(theSystemString, theCode, theListToPopulate, conceptList);
- }
-
- private void findCodesBelow(String theSystemString, String theCode, List theListToPopulate, List conceptList) {
- for (ConceptDefinitionComponent next : conceptList) {
- if (theCode.equals(next.getCode())) {
- addAllChildren(theSystemString, next, theListToPopulate);
- } else {
- findCodesBelow(theSystemString, theCode, theListToPopulate, next.getConcept());
- }
- }
- }
-
- private void findCodesAbove(CodeSystem theSystem, String theSystemString, String theCode, List theListToPopulate) {
- List conceptList = theSystem.getConcept();
- for (ConceptDefinitionComponent next : conceptList) {
- addTreeIfItContainsCode(theSystemString, next, theCode, theListToPopulate);
- }
+ private void addDisplayFilterInexact(QueryBuilder qb, BooleanJunction> bool, ConceptSetFilterComponent nextFilter) {
+ Query textQuery = qb
+ .phrase()
+ .withSlop(2)
+ .onField("myDisplay").boostedTo(4.0f)
+ .andField("myDisplayEdgeNGram").boostedTo(2.0f)
+ // .andField("myDisplayNGram").boostedTo(1.0f)
+ // .andField("myDisplayPhonetic").boostedTo(0.5f)
+ .sentence(nextFilter.getValue().toLowerCase()).createQuery();
+ bool.must(textQuery);
}
private boolean addTreeIfItContainsCode(String theSystemString, ConceptDefinitionComponent theNext, String theCode, List theListToPopulate) {
@@ -118,41 +119,6 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
return false;
}
- private void addAllChildren(String theSystemString, ConceptDefinitionComponent theCode, List theListToPopulate) {
- if (isNotBlank(theCode.getCode())) {
- theListToPopulate.add(new VersionIndependentConcept(theSystemString, theCode.getCode()));
- }
- for (ConceptDefinitionComponent nextChild : theCode.getConcept()) {
- addAllChildren(theSystemString, nextChild, theListToPopulate);
- }
- }
-
- @Override
- protected List findCodesAboveUsingBuiltInSystems(String theSystem, String theCode) {
- ArrayList retVal = new ArrayList();
- CodeSystem system = myValidationSupport.fetchCodeSystem(myContext, theSystem);
- if (system != null) {
- findCodesAbove(system, theSystem, theCode, retVal);
- }
- return retVal;
- }
-
- private void addDisplayFilterExact(QueryBuilder qb, BooleanJunction> bool, ConceptSetFilterComponent nextFilter) {
- bool.must(qb.phrase().onField("myDisplay").sentence(nextFilter.getValue()).createQuery());
- }
-
- private void addDisplayFilterInexact(QueryBuilder qb, BooleanJunction> bool, ConceptSetFilterComponent nextFilter) {
- Query textQuery = qb
- .phrase()
- .withSlop(2)
- .onField("myDisplay").boostedTo(4.0f)
- .andField("myDisplayEdgeNGram").boostedTo(2.0f)
- // .andField("myDisplayNGram").boostedTo(1.0f)
- // .andField("myDisplayPhonetic").boostedTo(0.5f)
- .sentence(nextFilter.getValue().toLowerCase()).createQuery();
- bool.must(textQuery);
- }
-
@Override
public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
String system = theInclude.getSystem();
@@ -204,8 +170,8 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
if (isBlank(nextFilter.getValue()) || nextFilter.getOp() == null || isBlank(nextFilter.getProperty())) {
throw new InvalidRequestException("Invalid filter, must have fields populated: property op value");
}
-
-
+
+
if (nextFilter.getProperty().equals("display:exact") && nextFilter.getOp() == FilterOperator.EQUAL) {
addDisplayFilterExact(qb, bool, nextFilter);
} else if ("display".equals(nextFilter.getProperty()) && nextFilter.getOp() == FilterOperator.EQUAL) {
@@ -232,12 +198,12 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
jpaQuery.setMaxResults(1000);
StopWatch sw = new StopWatch();
-
+
@SuppressWarnings("unchecked")
List result = jpaQuery.getResultList();
-
+
ourLog.info("Expansion completed in {}ms", sw.getMillis());
-
+
for (TermConcept nextConcept : result) {
addCodeIfNotAlreadyAdded(system, retVal, addedCodes, nextConcept);
}
@@ -278,6 +244,11 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ return null;
+ }
+
@Override
public List fetchAllStructureDefinitions(FhirContext theContext) {
return Collections.emptyList();
@@ -300,6 +271,48 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
return null;
}
+ private void findCodesAbove(CodeSystem theSystem, String theSystemString, String theCode, List theListToPopulate) {
+ List conceptList = theSystem.getConcept();
+ for (ConceptDefinitionComponent next : conceptList) {
+ addTreeIfItContainsCode(theSystemString, next, theCode, theListToPopulate);
+ }
+ }
+
+ @Override
+ protected List findCodesAboveUsingBuiltInSystems(String theSystem, String theCode) {
+ ArrayList retVal = new ArrayList();
+ CodeSystem system = myValidationSupport.fetchCodeSystem(myContext, theSystem);
+ if (system != null) {
+ findCodesAbove(system, theSystem, theCode, retVal);
+ }
+ return retVal;
+ }
+
+ private void findCodesBelow(CodeSystem theSystem, String theSystemString, String theCode, List theListToPopulate) {
+ List conceptList = theSystem.getConcept();
+ findCodesBelow(theSystemString, theCode, theListToPopulate, conceptList);
+ }
+
+ private void findCodesBelow(String theSystemString, String theCode, List theListToPopulate, List conceptList) {
+ for (ConceptDefinitionComponent next : conceptList) {
+ if (theCode.equals(next.getCode())) {
+ addAllChildren(theSystemString, next, theListToPopulate);
+ } else {
+ findCodesBelow(theSystemString, theCode, theListToPopulate, next.getConcept());
+ }
+ }
+ }
+
+ @Override
+ protected List findCodesBelowUsingBuiltInSystems(String theSystem, String theCode) {
+ ArrayList retVal = new ArrayList();
+ CodeSystem system = myValidationSupport.fetchCodeSystem(myContext, theSystem);
+ if (system != null) {
+ findCodesBelow(system, theSystem, theCode, retVal);
+ }
+ return retVal;
+ }
+
@Override
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
return super.supportsSystem(theSystem);
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/StopWatch.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/StopWatch.java
index f1389e3d39c..414de7e53be 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/StopWatch.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/StopWatch.java
@@ -1,5 +1,7 @@
package ca.uhn.fhir.jpa.util;
+import org.apache.commons.lang3.time.DateUtils;
+
import java.util.Date;
/*
@@ -72,9 +74,15 @@ public class StopWatch {
static public String formatMillis(long val) {
StringBuilder buf = new StringBuilder(20);
- append(buf, "", 2, ((val % 3600000) / 60000));
- append(buf, ":", 2, ((val % 60000) / 1000));
- append(buf, ".", 3, (val % 1000));
+ if (val >= DateUtils.MILLIS_PER_DAY) {
+ append(buf, "", 1, ((val / DateUtils.MILLIS_PER_DAY)));
+ append(buf, "d", 2, ((val % DateUtils.MILLIS_PER_DAY) / DateUtils.MILLIS_PER_HOUR));
+ } else {
+ append(buf, "", 2, ((val % DateUtils.MILLIS_PER_DAY) / DateUtils.MILLIS_PER_HOUR));
+ }
+ append(buf, ":", 2, ((val % DateUtils.MILLIS_PER_HOUR) / DateUtils.MILLIS_PER_MINUTE));
+ append(buf, ":", 2, ((val % DateUtils.MILLIS_PER_MINUTE) / DateUtils.MILLIS_PER_SECOND));
+ append(buf, ".", 3, (val % DateUtils.MILLIS_PER_SECOND));
return buf.toString();
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java
index 99e4eb030d8..0e3af0f029f 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java
@@ -35,6 +35,7 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
@After
public void after() {
myDaoConfig.setDefaultSearchParamsCanBeOverridden(new DaoConfig().isDefaultSearchParamsCanBeOverridden());
+ myDaoConfig.setUniqueIndexesCheckedBeforeSave(new DaoConfig().isUniqueIndexesCheckedBeforeSave());
}
@Before
@@ -118,6 +119,58 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
mySearchParamRegsitry.forceRefresh();
}
+ private void createUniqueObservationSubjectDateCode() {
+ SearchParameter sp = new SearchParameter();
+ sp.setId("SearchParameter/obs-subject");
+ sp.setType(Enumerations.SearchParamType.REFERENCE);
+ sp.setCode("subject");
+ sp.setExpression("Observation.subject");
+ sp.setStatus(PublicationStatus.ACTIVE);
+ sp.addBase("Observation");
+ sp.addTarget("Patient");
+ mySearchParameterDao.update(sp);
+
+ sp = new SearchParameter();
+ sp.setId("SearchParameter/obs-effective");
+ sp.setType(Enumerations.SearchParamType.DATE);
+ sp.setCode("date");
+ sp.setExpression("Observation.effective");
+ sp.setStatus(PublicationStatus.ACTIVE);
+ sp.addBase("Observation");
+ mySearchParameterDao.update(sp);
+
+ sp = new SearchParameter();
+ sp.setId("SearchParameter/obs-code");
+ sp.setType(Enumerations.SearchParamType.TOKEN);
+ sp.setCode("code");
+ sp.setExpression("Observation.code");
+ sp.setStatus(PublicationStatus.ACTIVE);
+ sp.addBase("Observation");
+ mySearchParameterDao.update(sp);
+
+ sp = new SearchParameter();
+ sp.setId("SearchParameter/observation-subject-date-code");
+ sp.setType(Enumerations.SearchParamType.COMPOSITE);
+ sp.setStatus(PublicationStatus.ACTIVE);
+ sp.addBase("Observation");
+ sp.setExpression("Observation.code");
+ sp.addComponent()
+ .setExpression("Observation")
+ .setDefinition(new Reference("SearchParameter/obs-subject"));
+ sp.addComponent()
+ .setExpression("Observation")
+ .setDefinition(new Reference("SearchParameter/obs-effective"));
+ sp.addComponent()
+ .setExpression("Observation")
+ .setDefinition(new Reference("SearchParameter/obs-code"));
+ sp.addExtension()
+ .setUrl(JpaConstants.EXT_SP_UNIQUE)
+ .setValue(new BooleanType(true));
+ mySearchParameterDao.update(sp);
+
+ mySearchParamRegsitry.forceRefresh();
+ }
+
@Test
public void testDetectUniqueSearchParams() {
createUniqueBirthdateAndGenderSps();
@@ -131,9 +184,61 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
assertEquals("gender", params.get(0).getCompositeOf().get(1).getName());
}
+ @Test
+ public void testDuplicateUniqueValuesAreReIndexed() {
+
+ Patient pt1 = new Patient();
+ pt1.setActive(true);
+ IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
+
+ /*
+ * Both of the following resources will match the unique index we'll
+ * create afterward. So we can create them both, but then when we create
+ * the unique index that matches them both that's a problem...
+ */
+
+ Observation obs = new Observation();
+ obs.getCode().addCoding().setSystem("foo").setCode("bar");
+ obs.setSubject(new Reference(pt1.getIdElement().toUnqualifiedVersionless().getValue()));
+ obs.setEffective(new DateTimeType("2011-01-01"));
+ IIdType id2 = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
+
+ obs = new Observation();
+ obs.getCode().addCoding().setSystem("foo").setCode("bar");
+ obs.setSubject(new Reference(pt1.getIdElement().toUnqualifiedVersionless().getValue()));
+ obs.setEffective(new DateTimeType("2011-01-01"));
+ IIdType id3 = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
+
+ ourLog.info("ID1: {} - ID2: {} - ID3: {}", id1, id2, id3);
+
+ createUniqueObservationSubjectDateCode();
+
+ mySystemDao.markAllResourcesForReindexing();
+ mySystemDao.performReindexingPass(1000);
+ mySystemDao.performReindexingPass(1000);
+
+ List uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 1, uniques.size());
+ assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
+ assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
+
+ myResourceIndexedCompositeStringUniqueDao.deleteAll();
+
+ mySystemDao.markAllResourcesForReindexing();
+ mySystemDao.performReindexingPass(1000);
+ mySystemDao.performReindexingPass(1000);
+
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 1, uniques.size());
+ assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
+ assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
+
+ }
@Test
- public void testDuplicateUniqueValuesAreRejected() {
+ public void testDuplicateUniqueValuesAreRejectedWithChecking_TestingDisabled() {
+ myDaoConfig.setUniqueIndexesCheckedBeforeSave(false);
+
createUniqueBirthdateAndGenderSps();
Patient pt1 = new Patient();
@@ -147,26 +252,10 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
} catch (JpaSystemException e) {
// good
}
-
- Patient pt2 = new Patient();
- pt2.setGender(Enumerations.AdministrativeGender.MALE);
- IIdType id2 = myPatientDao.create(pt2).getId().toUnqualifiedVersionless();
-
- pt2 = new Patient();
- pt2.setId(id2);
- pt2.setGender(Enumerations.AdministrativeGender.MALE);
- pt2.setBirthDateElement(new DateType("2011-01-01"));
- try {
- myPatientDao.update(pt2);
- fail();
- } catch (JpaSystemException e) {
- // good
- }
-
}
@Test
- public void testUniqueValuesAreIndexed_DateAndToken() {
+ public void testDuplicateUniqueValuesAreRejectedWithChecking_TestingEnabled() {
createUniqueBirthdateAndGenderSps();
Patient pt1 = new Patient();
@@ -174,10 +263,12 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
pt1.setBirthDateElement(new DateType("2011-01-01"));
IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
- List uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
- assertEquals(1, uniques.size());
- assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
- assertEquals("Patient?birthdate=2011-01-01&gender=http%3A%2F%2Fhl7.org%2Ffhir%2Fadministrative-gender%7Cmale", uniques.get(0).getIndexString());
+ try {
+ myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
+ fail();
+ } catch (PreconditionFailedException e) {
+ assertEquals("Can not create resource of type Patient as it would create a duplicate index matching query: Patient?birthdate=2011-01-01&gender=http%3A%2F%2Fhl7.org%2Ffhir%2Fadministrative-gender%7Cmale (existing index belongs to Patient/" + id1.getIdPart() + ")", e.getMessage());
+ }
}
@Test
@@ -204,7 +295,7 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
assertEquals(SearchBuilder.HandlerTypeEnum.UNIQUE_INDEX, SearchBuilder.getLastHandlerMechanismForUnitTest());
}
- @Test
+ @Test
public void testSearchUsingUniqueComposite() {
createUniqueBirthdateAndGenderSps();
@@ -255,6 +346,51 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
}
+ @Test
+ public void testUniqueValuesAreIndexed_DateAndToken() {
+ createUniqueBirthdateAndGenderSps();
+
+ Patient pt1 = new Patient();
+ pt1.setGender(Enumerations.AdministrativeGender.MALE);
+ pt1.setBirthDateElement(new DateType("2011-01-01"));
+ IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
+
+ List uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 1, uniques.size());
+ assertEquals("Patient/" + id1.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
+ assertEquals("Patient?birthdate=2011-01-01&gender=http%3A%2F%2Fhl7.org%2Ffhir%2Fadministrative-gender%7Cmale", uniques.get(0).getIndexString());
+ }
+
+ @Test
+ public void testUniqueValuesAreIndexed_RefAndDateAndToken() {
+ createUniqueObservationSubjectDateCode();
+
+ List uniques;
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 0, uniques.size());
+
+ Patient pt1 = new Patient();
+ pt1.setActive(true);
+ IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
+
+ Observation obs = new Observation();
+ obs.getCode().addCoding().setSystem("foo").setCode("bar");
+ obs.setSubject(new Reference(pt1.getIdElement().toUnqualifiedVersionless().getValue()));
+ obs.setEffective(new DateTimeType("2011-01-01"));
+ IIdType id2 = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
+
+ Patient pt2 = new Patient();
+ pt2.setActive(false);
+ IIdType id3 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
+
+ ourLog.info("ID1: {} - ID2: {} - ID3: {}", id1, id2, id3);
+
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 1, uniques.size());
+ assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
+ assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
+ }
+
@Test
public void testUniqueValuesAreIndexed_StringAndReference() {
createUniqueNameAndManagingOrganizationSps();
@@ -287,6 +423,106 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
assertEquals("Patient?name=GIVEN2&organization=Organization%2FORG", uniques.get(2).getIndexString());
}
+ @Test
+ public void testUniqueValuesAreNotIndexedIfNotAllParamsAreFound_DateAndToken() {
+ createUniqueBirthdateAndGenderSps();
+
+ Patient pt;
+ List uniques;
+
+ pt = new Patient();
+ pt.setGender(Enumerations.AdministrativeGender.MALE);
+ myPatientDao.create(pt).getId().toUnqualifiedVersionless();
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 0, uniques.size());
+
+ pt = new Patient();
+ myPatientDao.create(pt).getId().toUnqualifiedVersionless();
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 0, uniques.size());
+
+ pt = new Patient();
+ pt.setBirthDateElement(new DateType());
+ pt.setGender(Enumerations.AdministrativeGender.MALE);
+ myPatientDao.create(pt).getId().toUnqualifiedVersionless();
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 0, uniques.size());
+
+ }
+
+ @Test
+ public void testUniqueValuesAreNotIndexedIfNotAllParamsAreFound_StringAndReference() {
+ createUniqueNameAndManagingOrganizationSps();
+
+ Organization org = new Organization();
+ org.setId("Organization/ORG");
+ org.setName("ORG");
+ myOrganizationDao.update(org);
+
+ List uniques;
+ Patient pt;
+
+ pt = new Patient();
+ pt.setManagingOrganization(new Reference("Organization/ORG"));
+ myPatientDao.create(pt).getId().toUnqualifiedVersionless();
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 0, uniques.size());
+
+ pt = new Patient();
+ pt.addName()
+ .setFamily("FAMILY1")
+ .addGiven("GIVEN1")
+ .addGiven("GIVEN2")
+ .addGiven("GIVEN2"); // GIVEN2 happens twice
+ myPatientDao.create(pt).getId().toUnqualifiedVersionless();
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 0, uniques.size());
+
+ pt = new Patient();
+ pt.setActive(true);
+ myPatientDao.create(pt).getId().toUnqualifiedVersionless();
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 0, uniques.size());
+ }
+
+ @Test
+ public void testUniqueValuesAreReIndexed() {
+ createUniqueObservationSubjectDateCode();
+
+ Patient pt1 = new Patient();
+ pt1.setActive(true);
+ IIdType id1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
+
+ Observation obs = new Observation();
+ obs.getCode().addCoding().setSystem("foo").setCode("bar");
+ obs.setSubject(new Reference(pt1.getIdElement().toUnqualifiedVersionless().getValue()));
+ obs.setEffective(new DateTimeType("2011-01-01"));
+ IIdType id2 = myObservationDao.create(obs).getId().toUnqualifiedVersionless();
+
+ Patient pt2 = new Patient();
+ pt2.setActive(false);
+ myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
+
+ mySystemDao.markAllResourcesForReindexing();
+ mySystemDao.performReindexingPass(1000);
+
+ List uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 1, uniques.size());
+ assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
+ assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
+
+ myResourceIndexedCompositeStringUniqueDao.deleteAll();
+
+ mySystemDao.markAllResourcesForReindexing();
+ mySystemDao.performReindexingPass(1000);
+
+ uniques = myResourceIndexedCompositeStringUniqueDao.findAll();
+ assertEquals(uniques.toString(), 1, uniques.size());
+ assertEquals("Observation/" + id2.getIdPart(), uniques.get(0).getResource().getIdDt().toUnqualifiedVersionless().getValue());
+ assertEquals("Observation?code=foo%7Cbar&date=2011-01-01&subject=Patient%2F" + id1.getIdPart(), uniques.get(0).getIndexString());
+
+ }
+
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java
index 0a26b2caf46..c00286c6825 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/SystemProviderR4Test.java
@@ -362,6 +362,17 @@ public class SystemProviderR4Test extends BaseJpaR4Test {
} finally {
IOUtils.closeQuietly(http);;
}
+
+ get = new HttpGet(ourServerBase + "/$perform-reindexing-pass");
+ http = ourHttpClient.execute(get);
+ try {
+ String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
+ ourLog.info(output);
+ assertEquals(200, http.getStatusLine().getStatusCode());
+ } finally {
+ IOUtils.closeQuietly(http);;
+ }
+
}
@Transactional(propagation = Propagation.NEVER)
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/StopWatchTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/StopWatchTest.java
index 1e1eafe10fb..54a2ed29e27 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/StopWatchTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/StopWatchTest.java
@@ -3,10 +3,12 @@ package ca.uhn.fhir.jpa.util;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.startsWith;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.Date;
+import org.apache.commons.lang3.time.DateUtils;
import org.junit.Test;
public class StopWatchTest {
@@ -46,4 +48,14 @@ public class StopWatchTest {
assertThat(string, startsWith("00:00"));
}
+ @Test
+ public void testFormatMillis() throws Exception {
+ assertEquals("00:00:01.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_SECOND));
+ assertEquals("00:01:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_MINUTE));
+ assertEquals("01:00:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_HOUR));
+ assertEquals("1d00:00:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_DAY));
+ assertEquals("2d00:00:00.000", StopWatch.formatMillis(DateUtils.MILLIS_PER_DAY*2));
+ assertEquals("2d00:00:00.001", StopWatch.formatMillis((DateUtils.MILLIS_PER_DAY*2)+1));
+ }
+
}
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/derby_maintenance.txt b/hapi-fhir-jpaserver-uhnfhirtest/derby_maintenance.txt
index 3646c2ac1b7..21e69afe88a 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/derby_maintenance.txt
+++ b/hapi-fhir-jpaserver-uhnfhirtest/derby_maintenance.txt
@@ -44,12 +44,34 @@ delete from hfj_forced_id where resource_pid = 16940;
delete from hfj_resource where res_id = 16940;
+# Drop all tables
+drop table hfj_history_tag cascade constraints;
+drop table hfj_res_ver cascade constraints;
+drop table hfj_forced_id cascade constraints;
+drop table hfj_res_link cascade constraints;
+drop table hfj_res_link cascade constraints;
+drop table hfj_spidx_coords cascade constraints;
+drop table hfj_spidx_date cascade constraints;
+drop table hfj_spidx_number cascade constraints;
+drop table hfj_spidx_quantity cascade constraints;
+drop table hfj_spidx_string cascade constraints;
+drop table hfj_spidx_token cascade constraints;
+drop table hfj_spidx_uri cascade constraints;
+drop table hfj_res_tag cascade constraints;
+drop table hfj_search_result cascade constraints;
+drop table hfj_res_param_present cascade constraints;
+drop table hfj_resource cascade constraints;
+drop table hfj_idx_cmp_string_uniq cascade constraints;
+drop table hfj_search cascade constraints;
+drop table hfj_search_include cascade constraints;
+drop table hfj_search_parm cascade constraints;
+drop table hfj_subscription cascade constraints;
+drop table hfj_subscription_flag_res cascade constraints;
+drop table hfj_tag_def cascade constraints;
+drop table trm_codesystem cascade constraints;
+drop table trm_codesystem_var cascade constraints;
+drop table trm_concept cascade constraints;
+drop table trm_concept_pc_link cascade constraints;
+drop table trm_concept_property cascade constraints;
-delete from hfj_res_link where src_resource_id in ( 156618, 1092 , 1114 , 1139 , 1140 , 1141, 1142 , 1143 , 1144 , 1146 , 1147, 1148, 1062912, 1062916, 1062918, 1062919, 1062922, 1062929, 1062930, 1062934, 1062939, 1062940, 1062944, 1062949, 1062955, 1062957, 1062958, 1062959, 1062966, 1062969, 1062975, 1062976, 1062979, 1062981, 1062985, 1062987, 1062992, 1063002, 1063005, 1063007, 1063013, 1063016, 1063018, 1063020, 1063022, 1063062, 1063068, 1063075, 1063078, 1063080, 1063083, 1063084, 1063091, 1063095, 1063096, 1063098, 1107579, 1107591, 1107598, 1107761, 1107705, 1107748, 1109361, 1109388, 1109378, 1109399, 1109400, 1109401, 1109403, 1109404, 1109406, 1109409, 1109411, 1109414, 1109417, 1109418, 1109421, 1109427, 1109428, 1109429, 1109431, 1109432, 1109433, 1109891, 1109893, 1109947, 1179553, 1182781, 1182788, 1182791, 1182792, 1182795, 1182798, 1182801, 1182806, 1182811, 1182815) or target_resource_id in ( 156618, 1092 , 1114 , 1139 , 1140 , 1141, 1142 , 1143 , 1144 , 1146 , 1147, 1148, 1062912, 1062916, 1062918, 1062919, 1062922, 1062929, 1062930, 1062934, 1062939, 1062940, 1062944, 1062949, 1062955, 1062957, 1062958, 1062959, 1062966, 1062969, 1062975, 1062976, 1062979, 1062981, 1062985, 1062987, 1062992, 1063002, 1063005, 1063007, 1063013, 1063016, 1063018, 1063020, 1063022, 1063062, 1063068, 1063075, 1063078, 1063080, 1063083, 1063084, 1063091, 1063095, 1063096, 1063098, 1107579, 1107591, 1107598, 1107761, 1107705, 1107748, 1109361, 1109388, 1109378, 1109399, 1109400, 1109401, 1109403, 1109404, 1109406, 1109409, 1109411, 1109414, 1109417, 1109418, 1109421, 1109427, 1109428, 1109429, 1109431, 1109432, 1109433, 1109891, 1109893, 1109947, 1179553, 1182781, 1182788, 1182791, 1182792, 1182795, 1182798, 1182801, 1182806, 1182811, 1182815);
-delete from hfj_spidx_date where res_id in ( 156618, 1092 , 1114 , 1139 , 1140 , 1141, 1142 , 1143 , 1144 , 1146 , 1147, 1148, 1062912, 1062916, 1062918, 1062919, 1062922, 1062929, 1062930, 1062934, 1062939, 1062940, 1062944, 1062949, 1062955, 1062957, 1062958, 1062959, 1062966, 1062969, 1062975, 1062976, 1062979, 1062981, 1062985, 1062987, 1062992, 1063002, 1063005, 1063007, 1063013, 1063016, 1063018, 1063020, 1063022, 1063062, 1063068, 1063075, 1063078, 1063080, 1063083, 1063084, 1063091, 1063095, 1063096, 1063098, 1107579, 1107591, 1107598, 1107761, 1107705, 1107748, 1109361, 1109388, 1109378, 1109399, 1109400, 1109401, 1109403, 1109404, 1109406, 1109409, 1109411, 1109414, 1109417, 1109418, 1109421, 1109427, 1109428, 1109429, 1109431, 1109432, 1109433, 1109891, 1109893, 1109947, 1179553, 1182781, 1182788, 1182791, 1182792, 1182795, 1182798, 1182801, 1182806, 1182811, 1182815);
-delete from hfj_spidx_string where res_id in ( 156618, 1092 , 1114 , 1139 , 1140 , 1141, 1142 , 1143 , 1144 , 1146 , 1147, 1148, 1062912, 1062916, 1062918, 1062919, 1062922, 1062929, 1062930, 1062934, 1062939, 1062940, 1062944, 1062949, 1062955, 1062957, 1062958, 1062959, 1062966, 1062969, 1062975, 1062976, 1062979, 1062981, 1062985, 1062987, 1062992, 1063002, 1063005, 1063007, 1063013, 1063016, 1063018, 1063020, 1063022, 1063062, 1063068, 1063075, 1063078, 1063080, 1063083, 1063084, 1063091, 1063095, 1063096, 1063098, 1107579, 1107591, 1107598, 1107761, 1107705, 1107748, 1109361, 1109388, 1109378, 1109399, 1109400, 1109401, 1109403, 1109404, 1109406, 1109409, 1109411, 1109414, 1109417, 1109418, 1109421, 1109427, 1109428, 1109429, 1109431, 1109432, 1109433, 1109891, 1109893, 1109947, 1179553, 1182781, 1182788, 1182791, 1182792, 1182795, 1182798, 1182801, 1182806, 1182811, 1182815);
-delete from hfj_spidx_token where res_id in ( 156618, 1092 , 1114 , 1139 , 1140 , 1141, 1142 , 1143 , 1144 , 1146 , 1147, 1148, 1062912, 1062916, 1062918, 1062919, 1062922, 1062929, 1062930, 1062934, 1062939, 1062940, 1062944, 1062949, 1062955, 1062957, 1062958, 1062959, 1062966, 1062969, 1062975, 1062976, 1062979, 1062981, 1062985, 1062987, 1062992, 1063002, 1063005, 1063007, 1063013, 1063016, 1063018, 1063020, 1063022, 1063062, 1063068, 1063075, 1063078, 1063080, 1063083, 1063084, 1063091, 1063095, 1063096, 1063098, 1107579, 1107591, 1107598, 1107761, 1107705, 1107748, 1109361, 1109388, 1109378, 1109399, 1109400, 1109401, 1109403, 1109404, 1109406, 1109409, 1109411, 1109414, 1109417, 1109418, 1109421, 1109427, 1109428, 1109429, 1109431, 1109432, 1109433, 1109891, 1109893, 1109947, 1179553, 1182781, 1182788, 1182791, 1182792, 1182795, 1182798, 1182801, 1182806, 1182811, 1182815);
-delete from hfj_search_result where resource_pid in ( 156618, 1092 , 1114 , 1139 , 1140 , 1141, 1142 , 1143 , 1144 , 1146 , 1147, 1148, 1062912, 1062916, 1062918, 1062919, 1062922, 1062929, 1062930, 1062934, 1062939, 1062940, 1062944, 1062949, 1062955, 1062957, 1062958, 1062959, 1062966, 1062969, 1062975, 1062976, 1062979, 1062981, 1062985, 1062987, 1062992, 1063002, 1063005, 1063007, 1063013, 1063016, 1063018, 1063020, 1063022, 1063062, 1063068, 1063075, 1063078, 1063080, 1063083, 1063084, 1063091, 1063095, 1063096, 1063098, 1107579, 1107591, 1107598, 1107761, 1107705, 1107748, 1109361, 1109388, 1109378, 1109399, 1109400, 1109401, 1109403, 1109404, 1109406, 1109409, 1109411, 1109414, 1109417, 1109418, 1109421, 1109427, 1109428, 1109429, 1109431, 1109432, 1109433, 1109891, 1109893, 1109947, 1179553, 1182781, 1182788, 1182791, 1182792, 1182795, 1182798, 1182801, 1182806, 1182811, 1182815);
-delete from hfj_resource where res_id in ( 156618, 1092 , 1114 , 1139 , 1140 , 1141, 1142 , 1143 , 1144 , 1146 , 1147, 1148, 1062912, 1062916, 1062918, 1062919, 1062922, 1062929, 1062930, 1062934, 1062939, 1062940, 1062944, 1062949, 1062955, 1062957, 1062958, 1062959, 1062966, 1062969, 1062975, 1062976, 1062979, 1062981, 1062985, 1062987, 1062992, 1063002, 1063005, 1063007, 1063013, 1063016, 1063018, 1063020, 1063022, 1063062, 1063068, 1063075, 1063078, 1063080, 1063083, 1063084, 1063091, 1063095, 1063096, 1063098, 1107579, 1107591, 1107598, 1107761, 1107705, 1107748, 1109361, 1109388, 1109378, 1109399, 1109400, 1109401, 1109403, 1109404, 1109406, 1109409, 1109411, 1109414, 1109417, 1109418, 1109421, 1109427, 1109428, 1109429, 1109431, 1109432, 1109433, 1109891, 1109893, 1109947, 1179553, 1182781, 1182788, 1182791, 1182792, 1182795, 1182798, 1182801, 1182806, 1182811, 1182815);
-
diff --git a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java
index 80e48d618cf..b5fe1903fb6 100644
--- a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java
+++ b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java
@@ -1,32 +1,22 @@
package org.hl7.fhir.dstu2016may.hapi.validation;
-import static org.apache.commons.lang3.StringUtils.isNotBlank;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.Charsets;
import org.apache.commons.lang3.Validate;
-import org.hl7.fhir.dstu2016may.model.Bundle;
+import org.hl7.fhir.dstu2016may.model.*;
import org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent;
-import org.hl7.fhir.dstu2016may.model.CodeSystem;
import org.hl7.fhir.dstu2016may.model.CodeSystem.ConceptDefinitionComponent;
-import org.hl7.fhir.dstu2016may.model.DomainResource;
import org.hl7.fhir.dstu2016may.model.OperationOutcome.IssueSeverity;
-import org.hl7.fhir.dstu2016may.model.StructureDefinition;
-import org.hl7.fhir.dstu2016may.model.ValueSet;
import org.hl7.fhir.dstu2016may.model.ValueSet.ConceptReferenceComponent;
import org.hl7.fhir.dstu2016may.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu2016may.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import ca.uhn.fhir.context.FhirContext;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.*;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class DefaultProfileValidationSupport implements IValidationSupport {
@@ -55,6 +45,15 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return retVal;
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ ArrayList retVal = new ArrayList<>();
+ retVal.addAll(myCodeSystems.values());
+ retVal.addAll(myStructureDefinitions.values());
+ retVal.addAll(myValueSets.values());
+ return retVal;
+ }
+
@Override
public List fetchAllStructureDefinitions(FhirContext theContext) {
return new ArrayList(provideStructureDefinitionMap(theContext).values());
@@ -219,25 +218,6 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return structureDefinitions;
}
- @Override
- public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
- CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
- if (cs != null) {
- boolean caseSensitive = true;
- if (cs.hasCaseSensitive()) {
- caseSensitive = cs.getCaseSensitive();
- }
-
- CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
-
- if (retVal != null) {
- return retVal;
- }
- }
-
- return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
- }
-
private CodeValidationResult testIfConceptIsInList(String theCode, List conceptList, boolean theCaseSensitive) {
String code = theCode;
if (theCaseSensitive == false) {
@@ -269,4 +249,23 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return retVal;
}
+ @Override
+ public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
+ CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
+ if (cs != null) {
+ boolean caseSensitive = true;
+ if (cs.hasCaseSensitive()) {
+ caseSensitive = cs.getCaseSensitive();
+ }
+
+ CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
+
+ if (retVal != null) {
+ return retVal;
+ }
+ }
+
+ return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
+ }
+
}
diff --git a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/PrePopulatedValidationSupport.java b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/PrePopulatedValidationSupport.java
index f8cfa70d28e..8771c1609ef 100644
--- a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/PrePopulatedValidationSupport.java
+++ b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/PrePopulatedValidationSupport.java
@@ -1,10 +1,6 @@
package org.hl7.fhir.dstu2016may.hapi.validation;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu2016may.model.CodeSystem;
import org.hl7.fhir.dstu2016may.model.StructureDefinition;
@@ -13,7 +9,10 @@ import org.hl7.fhir.dstu2016may.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu2016may.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import ca.uhn.fhir.context.FhirContext;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* This class is an implementation of {@link IValidationSupport} which may be pre-populated
@@ -29,30 +28,25 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
* Constructor
*/
public PrePopulatedValidationSupport() {
- myStructureDefinitions = new HashMap();
- myValueSets = new HashMap();
- myCodeSystems = new HashMap();
+ myStructureDefinitions = new HashMap();
+ myValueSets = new HashMap();
+ myCodeSystems = new HashMap();
}
-
-
+
/**
- * Add a new StructureDefinition resource which will be available to the validator. Note that
- * {@link StructureDefinition#getUrl() the URL field) in this resource must contain a value as this
- * value will be used as the logical URL.
+ * Constructor
+ *
+ * @param theStructureDefinitions The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
+ * values are the resource itself.
+ * @param theValueSets The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
+ * the resource itself.
+ * @param theCodeSystems The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
+ * the resource itself.
*/
- public void addStructureDefinition(StructureDefinition theStructureDefinition) {
- Validate.notBlank(theStructureDefinition.getUrl(), "theStructureDefinition.getUrl() must not return a value");
- myStructureDefinitions.put(theStructureDefinition.getUrl(), theStructureDefinition);
- }
-
- /**
- * Add a new ValueSet resource which will be available to the validator. Note that
- * {@link ValueSet#getUrl() the URL field) in this resource must contain a value as this
- * value will be used as the logical URL.
- */
- public void addValueSet(ValueSet theValueSet) {
- Validate.notBlank(theValueSet.getUrl(), "theValueSet.getUrl() must not return a value");
- myValueSets.put(theValueSet.getUrl(), theValueSet);
+ public PrePopulatedValidationSupport(Map theStructureDefinitions, Map theValueSets, Map theCodeSystems) {
+ myStructureDefinitions = theStructureDefinitions;
+ myValueSets = theValueSets;
+ myCodeSystems = theCodeSystems;
}
/**
@@ -66,22 +60,23 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
}
/**
- * Constructor
- *
- * @param theStructureDefinitions
- * The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
- * values are the resource itself.
- * @param theValueSets
- * The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
- * the resource itself.
- * @param theCodeSystems
- * The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
- * the resource itself.
+ * Add a new StructureDefinition resource which will be available to the validator. Note that
+ * {@link StructureDefinition#getUrl() the URL field) in this resource must contain a value as this
+ * value will be used as the logical URL.
*/
- public PrePopulatedValidationSupport(Map theStructureDefinitions, Map theValueSets, Map theCodeSystems) {
- myStructureDefinitions = theStructureDefinitions;
- myValueSets = theValueSets;
- myCodeSystems = theCodeSystems;
+ public void addStructureDefinition(StructureDefinition theStructureDefinition) {
+ Validate.notBlank(theStructureDefinition.getUrl(), "theStructureDefinition.getUrl() must not return a value");
+ myStructureDefinitions.put(theStructureDefinition.getUrl(), theStructureDefinition);
+ }
+
+ /**
+ * Add a new ValueSet resource which will be available to the validator. Note that
+ * {@link ValueSet#getUrl() the URL field) in this resource must contain a value as this
+ * value will be used as the logical URL.
+ */
+ public void addValueSet(ValueSet theValueSet) {
+ Validate.notBlank(theValueSet.getUrl(), "theValueSet.getUrl() must not return a value");
+ myValueSets.put(theValueSet.getUrl(), theValueSet);
}
@Override
@@ -89,6 +84,15 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
return null;
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ ArrayList retVal = new ArrayList<>();
+ retVal.addAll(myCodeSystems.values());
+ retVal.addAll(myStructureDefinitions.values());
+ retVal.addAll(myValueSets.values());
+ return retVal;
+ }
+
@Override
public List fetchAllStructureDefinitions(FhirContext theContext) {
return new ArrayList(myStructureDefinitions.values());
@@ -129,4 +133,4 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
return null;
}
-}
\ No newline at end of file
+}
diff --git a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/ValidationSupportChain.java b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/ValidationSupportChain.java
index 409e1d0b1e4..11889dba553 100644
--- a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/ValidationSupportChain.java
+++ b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/ValidationSupportChain.java
@@ -1,19 +1,18 @@
package org.hl7.fhir.dstu2016may.hapi.validation;
-import static org.apache.commons.lang3.StringUtils.isBlank;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
+import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.dstu2016may.model.CodeSystem;
import org.hl7.fhir.dstu2016may.model.StructureDefinition;
import org.hl7.fhir.dstu2016may.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu2016may.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import ca.uhn.fhir.context.FhirContext;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.commons.lang3.StringUtils.isBlank;
public class ValidationSupportChain implements IValidationSupport {
@@ -52,6 +51,32 @@ public class ValidationSupportChain implements IValidationSupport {
return myChain.get(0).expandValueSet(theCtx, theInclude);
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ List retVal = new ArrayList<>();
+ for (IValidationSupport next : myChain) {
+ List candidates = next.fetchAllConformanceResources(theContext);
+ if (candidates != null) {
+ retVal.addAll(candidates);
+ }
+ }
+ return retVal;
+ }
+
+ @Override
+ public List fetchAllStructureDefinitions(FhirContext theContext) {
+ ArrayList retVal = new ArrayList();
+ Set urls = new HashSet();
+ for (IValidationSupport nextSupport : myChain) {
+ for (StructureDefinition next : nextSupport.fetchAllStructureDefinitions(theContext)) {
+ if (isBlank(next.getUrl()) || urls.add(next.getUrl())) {
+ retVal.add(next);
+ }
+ }
+ }
+ return retVal;
+ }
+
@Override
public CodeSystem fetchCodeSystem(FhirContext theCtx, String theSystem) {
for (IValidationSupport next : myChain) {
@@ -105,18 +130,4 @@ public class ValidationSupportChain implements IValidationSupport {
return myChain.get(0).validateCode(theCtx, theCodeSystem, theCode, theDisplay);
}
- @Override
- public List fetchAllStructureDefinitions(FhirContext theContext) {
- ArrayList retVal = new ArrayList();
- Set urls= new HashSet();
- for (IValidationSupport nextSupport : myChain) {
- for (StructureDefinition next : nextSupport.fetchAllStructureDefinitions(theContext)) {
- if (isBlank(next.getUrl()) || urls.add(next.getUrl())) {
- retVal.add(next);
- }
- }
- }
- return retVal;
- }
-
}
diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java
index d88b0a2fefd..a674072a212 100644
--- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java
+++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java
@@ -1,11 +1,6 @@
package org.hl7.fhir.dstu3.hapi.validation;
-import static org.apache.commons.lang3.StringUtils.isNotBlank;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.*;
-
+import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
@@ -19,7 +14,11 @@ import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
-import ca.uhn.fhir.context.FhirContext;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.*;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class DefaultProfileValidationSupport implements IValidationSupport {
@@ -52,6 +51,15 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return retVal;
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ ArrayList retVal = new ArrayList<>();
+ retVal.addAll(myCodeSystems.values());
+ retVal.addAll(myStructureDefinitions.values());
+ retVal.addAll(myValueSets.values());
+ return retVal;
+ }
+
@Override
public List fetchAllStructureDefinitions(FhirContext theContext) {
return new ArrayList(provideStructureDefinitionMap(theContext).values());
@@ -94,7 +102,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
if (theClass.equals(StructureDefinition.class)) {
return (T) fetchStructureDefinition(theContext, theUri);
}
-
+
if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
return (T) fetchValueSet(theContext, theUri);
}
@@ -195,25 +203,6 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return structureDefinitions;
}
- @Override
- public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
- CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
- if (cs != null) {
- boolean caseSensitive = true;
- if (cs.hasCaseSensitive()) {
- caseSensitive = cs.getCaseSensitive();
- }
-
- CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
-
- if (retVal != null) {
- return retVal;
- }
- }
-
- return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
- }
-
private CodeValidationResult testIfConceptIsInList(String theCode, List conceptList, boolean theCaseSensitive) {
String code = theCode;
if (theCaseSensitive == false) {
@@ -245,4 +234,23 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return retVal;
}
+ @Override
+ public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
+ CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
+ if (cs != null) {
+ boolean caseSensitive = true;
+ if (cs.hasCaseSensitive()) {
+ caseSensitive = cs.getCaseSensitive();
+ }
+
+ CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
+
+ if (retVal != null) {
+ return retVal;
+ }
+ }
+
+ return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
+ }
+
}
diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java
index 08820d6c862..1914426daa7 100644
--- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java
+++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/PrePopulatedValidationSupport.java
@@ -1,19 +1,21 @@
package org.hl7.fhir.dstu3.hapi.validation;
-import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import ca.uhn.fhir.context.FhirContext;
+import org.apache.commons.lang3.Validate;
+import org.hl7.fhir.dstu3.model.CodeSystem;
+import org.hl7.fhir.dstu3.model.MetadataResource;
+import org.hl7.fhir.dstu3.model.StructureDefinition;
+import org.hl7.fhir.dstu3.model.ValueSet;
+import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
+import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
+import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.commons.lang3.Validate;
-import org.hl7.fhir.dstu3.model.*;
-import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
-import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
-import org.hl7.fhir.instance.model.api.IBaseResource;
-
-import ca.uhn.fhir.context.FhirContext;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* This class is an implementation of {@link IValidationSupport} which may be pre-populated
@@ -29,23 +31,20 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
* Constructor
*/
public PrePopulatedValidationSupport() {
- myStructureDefinitions = new HashMap();
- myValueSets = new HashMap();
- myCodeSystems = new HashMap();
+ myStructureDefinitions = new HashMap<>();
+ myValueSets = new HashMap<>();
+ myCodeSystems = new HashMap<>();
}
/**
* Constructor
- *
- * @param theStructureDefinitions
- * The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
- * values are the resource itself.
- * @param theValueSets
- * The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
- * the resource itself.
- * @param theCodeSystems
- * The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
- * the resource itself.
+ *
+ * @param theStructureDefinitions The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
+ * values are the resource itself.
+ * @param theValueSets The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
+ * the resource itself.
+ * @param theCodeSystems The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
+ * the resource itself.
*/
public PrePopulatedValidationSupport(Map theStructureDefinitions, Map theValueSets, Map theCodeSystems) {
myStructureDefinitions = theStructureDefinitions;
@@ -131,6 +130,15 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
return null;
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ ArrayList retVal = new ArrayList<>();
+ retVal.addAll(myCodeSystems.values());
+ retVal.addAll(myStructureDefinitions.values());
+ retVal.addAll(myValueSets.values());
+ return retVal;
+ }
+
@Override
public List fetchAllStructureDefinitions(FhirContext theContext) {
return new ArrayList(myStructureDefinitions.values());
@@ -171,4 +179,4 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
return null;
}
-}
\ No newline at end of file
+}
diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/ValidationSupportChain.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/ValidationSupportChain.java
index d7e0d60f469..e859f81746e 100644
--- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/ValidationSupportChain.java
+++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/validation/ValidationSupportChain.java
@@ -1,131 +1,143 @@
package org.hl7.fhir.dstu3.hapi.validation;
-import static org.apache.commons.lang3.StringUtils.isBlank;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
+import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import ca.uhn.fhir.context.FhirContext;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.commons.lang3.StringUtils.isBlank;
public class ValidationSupportChain implements IValidationSupport {
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationSupportChain.class);
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationSupportChain.class);
- private List myChain;
+ private List myChain;
- /**
- * Constructor
- */
- public ValidationSupportChain() {
- myChain = new ArrayList();
- }
+ /**
+ * Constructor
+ */
+ public ValidationSupportChain() {
+ myChain = new ArrayList();
+ }
- /**
- * Constructor
- */
- public ValidationSupportChain(IValidationSupport... theValidationSupportModules) {
- this();
- for (IValidationSupport next : theValidationSupportModules) {
- if (next != null) {
- myChain.add(next);
- }
- }
- }
+ /**
+ * Constructor
+ */
+ public ValidationSupportChain(IValidationSupport... theValidationSupportModules) {
+ this();
+ for (IValidationSupport next : theValidationSupportModules) {
+ if (next != null) {
+ myChain.add(next);
+ }
+ }
+ }
- public void addValidationSupport(IValidationSupport theValidationSupport) {
- myChain.add(theValidationSupport);
- }
+ public void addValidationSupport(IValidationSupport theValidationSupport) {
+ myChain.add(theValidationSupport);
+ }
- @Override
- public ValueSetExpansionComponent expandValueSet(FhirContext theCtx, ConceptSetComponent theInclude) {
- for (IValidationSupport next : myChain) {
- if (next.isCodeSystemSupported(theCtx, theInclude.getSystem())) {
- return next.expandValueSet(theCtx, theInclude);
- }
- }
- return myChain.get(0).expandValueSet(theCtx, theInclude);
- }
+ @Override
+ public ValueSetExpansionComponent expandValueSet(FhirContext theCtx, ConceptSetComponent theInclude) {
+ for (IValidationSupport next : myChain) {
+ if (next.isCodeSystemSupported(theCtx, theInclude.getSystem())) {
+ return next.expandValueSet(theCtx, theInclude);
+ }
+ }
+ return myChain.get(0).expandValueSet(theCtx, theInclude);
+ }
- @Override
- public CodeSystem fetchCodeSystem(FhirContext theCtx, String theSystem) {
- for (IValidationSupport next : myChain) {
- CodeSystem retVal = next.fetchCodeSystem(theCtx, theSystem);
- if (retVal != null) {
- return retVal;
- }
- }
- return null;
- }
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ List retVal = new ArrayList<>();
+ for (IValidationSupport next : myChain) {
+ List candidates = next.fetchAllConformanceResources(theContext);
+ if (candidates != null) {
+ retVal.addAll(candidates);
+ }
+ }
+ return retVal;
+ }
- @Override
- public T fetchResource(FhirContext theContext, Class theClass, String theUri) {
- for (IValidationSupport next : myChain) {
- T retVal = next.fetchResource(theContext, theClass, theUri);
- if (retVal != null) {
- return retVal;
- }
- }
- return null;
- }
+ @Override
+ public List fetchAllStructureDefinitions(FhirContext theContext) {
+ ArrayList retVal = new ArrayList();
+ Set urls = new HashSet();
+ for (IValidationSupport nextSupport : myChain) {
+ for (StructureDefinition next : nextSupport.fetchAllStructureDefinitions(theContext)) {
+ if (isBlank(next.getUrl()) || urls.add(next.getUrl())) {
+ retVal.add(next);
+ }
+ }
+ }
+ return retVal;
+ }
- @Override
- public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
- for (IValidationSupport next : myChain) {
- StructureDefinition retVal = next.fetchStructureDefinition(theCtx, theUrl);
- if (retVal != null) {
- return retVal;
- }
- }
- return null;
- }
+ @Override
+ public CodeSystem fetchCodeSystem(FhirContext theCtx, String theSystem) {
+ for (IValidationSupport next : myChain) {
+ CodeSystem retVal = next.fetchCodeSystem(theCtx, theSystem);
+ if (retVal != null) {
+ return retVal;
+ }
+ }
+ return null;
+ }
- @Override
- public boolean isCodeSystemSupported(FhirContext theCtx, String theSystem) {
- for (IValidationSupport next : myChain) {
- if (next.isCodeSystemSupported(theCtx, theSystem)) {
- return true;
- }
- }
- return false;
- }
+ @Override
+ public T fetchResource(FhirContext theContext, Class theClass, String theUri) {
+ for (IValidationSupport next : myChain) {
+ T retVal = next.fetchResource(theContext, theClass, theUri);
+ if (retVal != null) {
+ return retVal;
+ }
+ }
+ return null;
+ }
- @Override
- public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
-
- ourLog.info("Validating code {} in chain with {} items", theCode, myChain.size());
-
- for (IValidationSupport next : myChain) {
- if (next.isCodeSystemSupported(theCtx, theCodeSystem)) {
- CodeValidationResult result = next.validateCode(theCtx, theCodeSystem, theCode, theDisplay);
- ourLog.info("Chain item {} returned outcome {}", next, result.isOk());
- return result;
- } else {
- ourLog.info("Chain item {} does not support code system {}", next, theCodeSystem);
- }
- }
- return myChain.get(0).validateCode(theCtx, theCodeSystem, theCode, theDisplay);
- }
+ @Override
+ public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
+ for (IValidationSupport next : myChain) {
+ StructureDefinition retVal = next.fetchStructureDefinition(theCtx, theUrl);
+ if (retVal != null) {
+ return retVal;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isCodeSystemSupported(FhirContext theCtx, String theSystem) {
+ for (IValidationSupport next : myChain) {
+ if (next.isCodeSystemSupported(theCtx, theSystem)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
+
+ ourLog.info("Validating code {} in chain with {} items", theCode, myChain.size());
+
+ for (IValidationSupport next : myChain) {
+ if (next.isCodeSystemSupported(theCtx, theCodeSystem)) {
+ CodeValidationResult result = next.validateCode(theCtx, theCodeSystem, theCode, theDisplay);
+ ourLog.info("Chain item {} returned outcome {}", next, result.isOk());
+ return result;
+ } else {
+ ourLog.info("Chain item {} does not support code system {}", next, theCodeSystem);
+ }
+ }
+ return myChain.get(0).validateCode(theCtx, theCodeSystem, theCode, theDisplay);
+ }
- @Override
- public List fetchAllStructureDefinitions(FhirContext theContext) {
- ArrayList retVal = new ArrayList();
- Set urls= new HashSet();
- for (IValidationSupport nextSupport : myChain) {
- for (StructureDefinition next : nextSupport.fetchAllStructureDefinitions(theContext)) {
- if (isBlank(next.getUrl()) || urls.add(next.getUrl())) {
- retVal.add(next);
- }
- }
- }
- return retVal;
- }
}
diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java
index 1961fa84b46..120e25e8567 100644
--- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java
+++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java
@@ -1,11 +1,6 @@
package org.hl7.fhir.r4.hapi.ctx;
-import static org.apache.commons.lang3.StringUtils.isNotBlank;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.*;
-
+import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
@@ -14,10 +9,16 @@ import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent;
-import org.hl7.fhir.r4.model.ValueSet.*;
+import org.hl7.fhir.r4.model.ValueSet.ConceptReferenceComponent;
+import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
+import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
-import ca.uhn.fhir.context.FhirContext;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.*;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class DefaultProfileValidationSupport implements IValidationSupport {
@@ -51,10 +52,20 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
}
@Override
- public List fetchAllStructureDefinitions(FhirContext theContext) {
- return new ArrayList(provideStructureDefinitionMap(theContext).values());
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ ArrayList retVal = new ArrayList<>();
+ retVal.addAll(myCodeSystems.values());
+ retVal.addAll(myStructureDefinitions.values());
+ retVal.addAll(myValueSets.values());
+ return retVal;
}
+ @Override
+ public List fetchAllStructureDefinitions(FhirContext theContext) {
+ return new ArrayList<>(provideStructureDefinitionMap(theContext).values());
+ }
+
+
@Override
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
return (CodeSystem) fetchCodeSystemOrValueSet(theContext, theSystem, true);
@@ -65,8 +76,8 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
Map codeSystems = myCodeSystems;
Map valueSets = myValueSets;
if (codeSystems == null || valueSets == null) {
- codeSystems = new HashMap();
- valueSets = new HashMap();
+ codeSystems = new HashMap<>();
+ valueSets = new HashMap<>();
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/r4/model/valueset/valuesets.xml");
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/r4/model/valueset/v2-tables.xml");
@@ -92,7 +103,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
if (theClass.equals(StructureDefinition.class)) {
return (T) fetchStructureDefinition(theContext, theUri);
}
-
+
if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
return (T) fetchValueSet(theContext, theUri);
}
@@ -193,25 +204,6 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return structureDefinitions;
}
- @Override
- public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
- CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
- if (cs != null) {
- boolean caseSensitive = true;
- if (cs.hasCaseSensitive()) {
- caseSensitive = cs.getCaseSensitive();
- }
-
- CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
-
- if (retVal != null) {
- return retVal;
- }
- }
-
- return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
- }
-
private CodeValidationResult testIfConceptIsInList(String theCode, List conceptList, boolean theCaseSensitive) {
String code = theCode;
if (theCaseSensitive == false) {
@@ -243,4 +235,23 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return retVal;
}
+ @Override
+ public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
+ CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
+ if (cs != null) {
+ boolean caseSensitive = true;
+ if (cs.hasCaseSensitive()) {
+ caseSensitive = cs.getCaseSensitive();
+ }
+
+ CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
+
+ if (retVal != null) {
+ return retVal;
+ }
+ }
+
+ return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
+ }
+
}
diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/PrePopulatedValidationSupport.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/PrePopulatedValidationSupport.java
index 7545997ff31..92807c4f6c3 100644
--- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/PrePopulatedValidationSupport.java
+++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/PrePopulatedValidationSupport.java
@@ -1,16 +1,21 @@
package org.hl7.fhir.r4.hapi.ctx;
-import static org.apache.commons.lang3.StringUtils.isNotBlank;
-
-import java.util.*;
-
+import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import org.hl7.fhir.r4.model.*;
+import org.hl7.fhir.r4.model.CodeSystem;
+import org.hl7.fhir.r4.model.MetadataResource;
+import org.hl7.fhir.r4.model.StructureDefinition;
+import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent;
-import ca.uhn.fhir.context.FhirContext;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* This class is an implementation of {@link IValidationSupport} which may be pre-populated
@@ -26,23 +31,21 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
* Constructor
*/
public PrePopulatedValidationSupport() {
- myStructureDefinitions = new HashMap();
- myValueSets = new HashMap();
- myCodeSystems = new HashMap();
+ myStructureDefinitions = new HashMap<>();
+ myValueSets = new HashMap<>();
+ myCodeSystems = new HashMap<>();
}
+
/**
* Constructor
- *
- * @param theStructureDefinitions
- * The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
- * values are the resource itself.
- * @param theValueSets
- * The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
- * the resource itself.
- * @param theCodeSystems
- * The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
- * the resource itself.
+ *
+ * @param theStructureDefinitions The StructureDefinitions to be returned by this module. Keys are the logical URL for the resource, and
+ * values are the resource itself.
+ * @param theValueSets The ValueSets to be returned by this module. Keys are the logical URL for the resource, and values are
+ * the resource itself.
+ * @param theCodeSystems The CodeSystems to be returned by this module. Keys are the logical URL for the resource, and values are
+ * the resource itself.
*/
public PrePopulatedValidationSupport(Map theStructureDefinitions, Map theValueSets, Map theCodeSystems) {
myStructureDefinitions = theStructureDefinitions;
@@ -128,6 +131,15 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
return null;
}
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ ArrayList retVal = new ArrayList<>();
+ retVal.addAll(myCodeSystems.values());
+ retVal.addAll(myStructureDefinitions.values());
+ retVal.addAll(myValueSets.values());
+ return retVal;
+ }
+
@Override
public List fetchAllStructureDefinitions(FhirContext theContext) {
return new ArrayList(myStructureDefinitions.values());
@@ -168,4 +180,4 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
return null;
}
-}
\ No newline at end of file
+}
diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/ValidationSupportChain.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/ValidationSupportChain.java
index 64d29bf119f..0ab5873784d 100644
--- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/ValidationSupportChain.java
+++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/ValidationSupportChain.java
@@ -1,16 +1,18 @@
package org.hl7.fhir.r4.hapi.ctx;
-import static org.apache.commons.lang3.StringUtils.isBlank;
-
-import java.util.*;
-
+import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent;
-import ca.uhn.fhir.context.FhirContext;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.commons.lang3.StringUtils.isBlank;
public class ValidationSupportChain implements IValidationSupport {
@@ -51,7 +53,19 @@ public class ValidationSupportChain implements IValidationSupport {
return myChain.get(0).expandValueSet(theCtx, theInclude);
}
- @Override
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ List retVal = new ArrayList<>();
+ for (IValidationSupport next : myChain) {
+ List candidates = next.fetchAllConformanceResources(theContext);
+ if (candidates != null) {
+ retVal.addAll(candidates);
+ }
+ }
+ return retVal;
+ }
+
+ @Override
public CodeSystem fetchCodeSystem(FhirContext theCtx, String theSystem) {
for (IValidationSupport next : myChain) {
CodeSystem retVal = next.fetchCodeSystem(theCtx, theSystem);
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/LoggingInterceptorTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/LoggingInterceptorTest.java
index d6bfee274a6..6e7f3c6d413 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/LoggingInterceptorTest.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/LoggingInterceptorTest.java
@@ -85,7 +85,7 @@ public class LoggingInterceptorTest {
System.out.flush();
return
formattedMessage.contains("Client request: GET http://localhost:" + ourPort + "/Patient/1 HTTP/1.1") ||
- formattedMessage.contains("Client response: HTTP 200 OK (Location: http://localhost:" + ourPort + "/Patient/1/_history/1)");
+ formattedMessage.contains("Client response: HTTP 200 OK (Patient/1/_history/1)");
}
}));
}
diff --git a/pom.xml b/pom.xml
index 8eedd207397..a859dfaafab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1828,6 +1828,7 @@
example-projects/hapi-fhir-base-example-embedded-ws
example-projects/hapi-fhir-standalone-overlay-example
hapi-fhir-jacoco
+ hapi-fhir-igpacks
@@ -1875,6 +1876,4 @@
-
-