Merge pull request #1812 from hapifhir/2024-11-gg-user-data-refactor

2024 11 gg user data refactor
This commit is contained in:
Grahame Grieve 2024-11-18 06:53:35 +11:00 committed by GitHub
commit 56a68d4ea2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
79 changed files with 1531 additions and 401 deletions

View File

@ -37,6 +37,7 @@ import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.IniFile;
import org.hl7.fhir.utilities.Utilities;
@ -522,8 +523,8 @@ public class SpecDifferenceEvaluator {
for (ElementDefinition ed : rev.getDifferential().getElement()) {
ElementDefinition oed = getMatchingElement(rev.getName(), orig.getDifferential().getElement(), ed);
if (oed != null) {
ed.setUserData("match", oed);
oed.setUserData("match", ed);
ed.setUserData(UserDataNames.comparison_match, oed);
oed.setUserData(UserDataNames.comparison_match, ed);
}
}
@ -556,9 +557,9 @@ public class SpecDifferenceEvaluator {
right.ul().li().addText("No Changes");
for (ElementDefinition ed : rev.getDifferential().getElement())
ed.clearUserData("match");
ed.clearUserData(UserDataNames.comparison_match);
for (ElementDefinition ed : orig.getDifferential().getElement())
ed.clearUserData("match");
ed.clearUserData(UserDataNames.comparison_match);
}
@ -1078,8 +1079,8 @@ public class SpecDifferenceEvaluator {
for (ElementDefinition ed : rev.getDifferential().getElement()) {
ElementDefinition oed = getMatchingElement(rev.getName(), orig.getDifferential().getElement(), ed);
if (oed != null) {
ed.setUserData("match", oed);
oed.setUserData("match", ed);
ed.setUserData(UserDataNames.comparison_match, oed);
oed.setUserData(UserDataNames.comparison_match, ed);
}
}
@ -1121,9 +1122,9 @@ public class SpecDifferenceEvaluator {
type.addProperty("status", "no-change");
for (ElementDefinition ed : rev.getDifferential().getElement())
ed.clearUserData("match");
ed.clearUserData(UserDataNames.comparison_match);
for (ElementDefinition ed : orig.getDifferential().getElement())
ed.clearUserData("match");
ed.clearUserData(UserDataNames.comparison_match);
}
@ -1137,8 +1138,8 @@ public class SpecDifferenceEvaluator {
for (ElementDefinition ed : rev.getDifferential().getElement()) {
ElementDefinition oed = getMatchingElement(rev.getName(), orig.getDifferential().getElement(), ed);
if (oed != null) {
ed.setUserData("match", oed);
oed.setUserData("match", ed);
ed.setUserData(UserDataNames.comparison_match, oed);
oed.setUserData(UserDataNames.comparison_match, ed);
}
}
@ -1179,9 +1180,9 @@ public class SpecDifferenceEvaluator {
type.setAttribute("status", "no-change");
for (ElementDefinition ed : rev.getDifferential().getElement())
ed.clearUserData("match");
ed.clearUserData(UserDataNames.comparison_match);
for (ElementDefinition ed : orig.getDifferential().getElement())
ed.clearUserData("match");
ed.clearUserData(UserDataNames.comparison_match);
}

View File

@ -19,6 +19,7 @@ import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.npm.NpmPackage;
@ -54,9 +55,9 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
public void setPath(Resource r) {
String path = lkp.getResourcePath(r);
if (lkp.getWebRoot() != null) {
r.setUserData("webroot", lkp.getWebRoot());
r.setUserData(UserDataNames.render_webroot, lkp.getWebRoot());
} else {
r.setUserData("webroot", "");
r.setUserData(UserDataNames.render_webroot, "");
}
if (path != null) {
r.setWebPath(path);
@ -116,7 +117,7 @@ public abstract class BaseLoaderR5 implements IContextResourceLoader {
// and we only patch URLs to support version transforms
// so we just patch sd/od -> vs -> cs
protected void doPatchUrls(Resource resource) {
resource.setUserData("old.load.mode", true);
resource.setUserData(UserDataNames.loader_urls_patched, true);
if (resource instanceof CanonicalResource) {
CanonicalResource cr = (CanonicalResource) resource;
cr.setUrl(patchUrl(cr.getUrl(), cr.fhirType()));

View File

@ -242,4 +242,14 @@ public class ResourceWrapperR4 extends ResourceWrapper {
return null;
}
@Override
public boolean hasUserData(String name) {
return element.hasUserData(name);
}
@Override
public Object getUserData(String name) {
return element.getUserData(name);
}
}

View File

@ -242,4 +242,14 @@ public class ResourceWrapperR4B extends ResourceWrapper {
return null;
}
@Override
public boolean hasUserData(String name) {
return element.hasUserData(name);
}
@Override
public Object getUserData(String name) {
return element.getUserData(name);
}
}

View File

@ -430,7 +430,7 @@ public class Validator {
}
private boolean isSimpleType(String type) {
return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time", "canonical");
return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time", "canonical", "uri", "url");
}
private String simpleType(String type) {

View File

@ -26,6 +26,7 @@ import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.i18n.RenderingI18nContext;
public class ComparisonSession {
@ -191,11 +192,11 @@ public class ComparisonSession {
if (b == null) {
return null;
}
if (b.hasUserData(VersionComparisonAnnotation.USER_DATA_NAME)) {
return (VersionComparisonAnnotation) b.getUserData(VersionComparisonAnnotation.USER_DATA_NAME);
if (b.hasUserData(UserDataNames.COMP_VERSION_ANNOTATION)) {
return (VersionComparisonAnnotation) b.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
} else {
VersionComparisonAnnotation vca = new VersionComparisonAnnotation(AnotationType.NoChange);
b.setUserData(VersionComparisonAnnotation.USER_DATA_NAME, vca);
b.setUserData(UserDataNames.COMP_VERSION_ANNOTATION, vca);
return vca;
}
}

View File

@ -41,6 +41,7 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.utils.DefinitionNavigator;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.validation.ValidationMessage;
@ -870,12 +871,12 @@ public class StructureDefinitionComparer extends CanonicalResourceComparer imple
ex.setProfile(null);
} else {
// both have profiles. Is one derived from the other?
StructureDefinition sdex = ((IWorkerContext) ex.getUserData("ctxt")).fetchResource(StructureDefinition.class, ex.getProfile().get(0).getValue(), nwSource);
StructureDefinition sdex = ((IWorkerContext) ex.getUserData(UserDataNames.COMP_CONTEXT)).fetchResource(StructureDefinition.class, ex.getProfile().get(0).getValue(), nwSource);
StructureDefinition sdnw = ctxt.fetchResource(StructureDefinition.class, nw.getProfile().get(0).getValue(), nwSource);
if (sdex != null && sdnw != null) {
if (sdex.getUrl().equals(sdnw.getUrl())) {
pfound = true;
} else if (derivesFrom(sdex, sdnw, ((IWorkerContext) ex.getUserData("ctxt")))) {
} else if (derivesFrom(sdex, sdnw, ((IWorkerContext) ex.getUserData(UserDataNames.COMP_CONTEXT)))) {
ex.setProfile(nw.getProfile());
pfound = true;
} else if (derivesFrom(sdnw, sdex, ctxt)) {
@ -898,12 +899,12 @@ public class StructureDefinitionComparer extends CanonicalResourceComparer imple
ex.setTargetProfile(null);
} else {
// both have profiles. Is one derived from the other?
StructureDefinition sdex = ((IWorkerContext) ex.getUserData("ctxt")).fetchResource(StructureDefinition.class, ex.getTargetProfile().get(0).getValue(), nwSource);
StructureDefinition sdex = ((IWorkerContext) ex.getUserData(UserDataNames.COMP_CONTEXT)).fetchResource(StructureDefinition.class, ex.getTargetProfile().get(0).getValue(), nwSource);
StructureDefinition sdnw = ctxt.fetchResource(StructureDefinition.class, nw.getTargetProfile().get(0).getValue(), nwSource);
if (sdex != null && sdnw != null) {
if (matches(sdex, sdnw)) {
tfound = true;
} else if (derivesFrom(sdex, sdnw, ((IWorkerContext) ex.getUserData("ctxt")))) {
} else if (derivesFrom(sdex, sdnw, ((IWorkerContext) ex.getUserData(UserDataNames.COMP_CONTEXT)))) {
ex.setTargetProfile(nw.getTargetProfile());
tfound = true;
} else if (derivesFrom(sdnw, sdex, ctxt)) {
@ -925,7 +926,7 @@ public class StructureDefinitionComparer extends CanonicalResourceComparer imple
}
}
if (!tfound || !pfound) {
nw.setUserData("ctxt", ctxt);
nw.setUserData(UserDataNames.COMP_CONTEXT, ctxt);
results.add(nw);
}
}

View File

@ -8,6 +8,7 @@ import java.util.Map;
import org.hl7.fhir.r5.comparison.CanonicalResourceComparer.CanonicalResourceComparison;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.utils.UserDataNames;
public class VersionComparisonAnnotation {
@ -15,7 +16,6 @@ public class VersionComparisonAnnotation {
NoChange, Added, Changed, Deleted;
}
public static final String USER_DATA_NAME = "version-annotation";
private AnotationType type;
private String original;
@ -66,10 +66,6 @@ public class VersionComparisonAnnotation {
this.comp = comp;
}
public static String getUserDataName() {
return USER_DATA_NAME;
}
public AnotationType getType() {
return type;
}
@ -89,8 +85,8 @@ public class VersionComparisonAnnotation {
public static boolean hasDeleted(Base base, String... names) {
boolean result = false;
if (base.hasUserData(USER_DATA_NAME)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(USER_DATA_NAME);
if (base.hasUserData(UserDataNames.COMP_VERSION_ANNOTATION)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
for (String name : names) {
if (self.deletedChildren != null && self.deletedChildren.containsKey(name)) {
result = true;
@ -102,8 +98,8 @@ public class VersionComparisonAnnotation {
public static List<Base> getDeleted(Base base, String... names) {
List<Base> result = new ArrayList<>();
if (base.hasUserData(USER_DATA_NAME)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(USER_DATA_NAME);
if (base.hasUserData(UserDataNames.COMP_VERSION_ANNOTATION)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
for (String name : names) {
if (self.deletedChildren != null && self.deletedChildren.containsKey(name)) {
result.addAll(self.deletedChildren.get(name));
@ -115,8 +111,8 @@ public class VersionComparisonAnnotation {
public static Base getDeletedItem(Base base, String name) {
List<Base> result = new ArrayList<>();
if (base.hasUserData(USER_DATA_NAME)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(USER_DATA_NAME);
if (base.hasUserData(UserDataNames.COMP_VERSION_ANNOTATION)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
if (self.deletedChildren != null && self.deletedChildren.containsKey(name)) {
result.addAll(self.deletedChildren.get(name));
}
@ -128,8 +124,8 @@ public class VersionComparisonAnnotation {
public static CanonicalResourceComparison<? extends CanonicalResource> artifactComparison(Base base) {
if (base.hasUserData(USER_DATA_NAME)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(USER_DATA_NAME);
if (base.hasUserData(UserDataNames.COMP_VERSION_ANNOTATION)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
return self.comp;
} else {
return null;

View File

@ -14,6 +14,7 @@ import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionMappingComponent;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionMappingComponent;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
@ -47,7 +48,7 @@ public class MappingAssistant {
for (StructureDefinitionMappingComponent m : derived.getMapping()) {
masterList.add(m);
if (!isSuppressed(m)) {
m.setUserData("private-marked-as-derived", true);
m.setUserData(UserDataNames.mappings_inherited, true);
}
}
@ -127,7 +128,7 @@ public class MappingAssistant {
derived.getMapping().clear();
for (StructureDefinitionMappingComponent t : masterList) {
if (usedList.contains(t) || t.hasUserData("private-marked-as-derived")) {
if (usedList.contains(t) || t.hasUserData(UserDataNames.mappings_inherited)) {
derived.getMapping().add(t);
}
}
@ -163,7 +164,7 @@ public class MappingAssistant {
for (ElementDefinitionMappingComponent d : destination) {
if (compareMaps(name, s, d)) {
found = true;
d.setUserData(ProfileUtilities.UD_DERIVATION_EQUALS, true);
d.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
break;
}
}

View File

@ -19,6 +19,7 @@ import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionSnapshotComponent;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
@ -201,7 +202,7 @@ public class ProfilePathProcessor {
// int i = 0;
// List<ElementDefinition> list = getDifferential().getElement();
// for (ElementDefinition ed : list) {
// boolean assigned = ed.hasUserData("derived.pointer");
// boolean assigned = ed.hasUserData(UserDataNames.UD_DERIVATION_POINTER);
// if (i < cursors.diffCursor) {
// if (!assigned) {
// throw new Error("what?");
@ -295,7 +296,7 @@ public class ProfilePathProcessor {
if (!diffMatches.get(0).hasSlicing()) {
outcome.setSlicing(profileUtilities.makeExtensionSlicing());
outcome.setUserData("auto-added-slicing", true);
outcome.setUserData(UserDataNames.SNAPSHOT_auto_added_slicing, true);
} else {
outcome.setSlicing(diffMatches.get(0).getSlicing().copy());
for (int i = 1; i < diffMatches.size(); i++) {
@ -1041,9 +1042,9 @@ public class ProfilePathProcessor {
profileUtilities.updateFromDefinition(outcome, diffMatches.get(0), getProfileName(), closed, getUrl(), getSourceStructureDefinition(), getDerived(), diffPath(diffMatches.get(0)), mapHelper); // if there's no slice, we don't want to update the unsliced description
profileUtilities.removeStatusExtensions(outcome);
} else if (!diffMatches.get(0).hasSliceName()) {
diffMatches.get(0).setUserData(profileUtilities.UD_GENERATED_IN_SNAPSHOT, outcome); // because of updateFromDefinition isn't called
diffMatches.get(0).setUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT, outcome); // because of updateFromDefinition isn't called
} else {
outcome.setUserData("auto-added-slicing", true);
outcome.setUserData(UserDataNames.SNAPSHOT_auto_added_slicing, true);
}
debugCheck(outcome);
@ -1143,8 +1144,8 @@ public class ProfilePathProcessor {
outcome.setPath(profileUtilities.fixedPathDest(getContextPathTarget(), outcome.getPath(), getRedirector(), getContextPathSource()));
if (!outcome.getPath().startsWith(cursors.resultPathBase))
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH));
outcome.setUserData(profileUtilities.UD_BASE_PATH, outcome.getPath());
outcome.setUserData(profileUtilities.UD_BASE_MODEL, getSourceStructureDefinition().getUrl());
outcome.setUserData(UserDataNames.SNAPSHOT_BASE_PATH, outcome.getPath());
outcome.setUserData(UserDataNames.SNAPSHOT_BASE_MODEL, getSourceStructureDefinition().getUrl());
debugCheck(outcome);
getResult().getElement().add(outcome);
cursors.baseCursor++;
@ -1463,8 +1464,8 @@ public class ProfilePathProcessor {
throw new DefinitionException(profileUtilities.getContext().formatMessage(I18nConstants.ADDING_WRONG_PATH_IN_PROFILE___VS_, getProfileName(), outcome.getPath(), cursors.resultPathBase));
debugCheck(outcome);
getResult().getElement().add(outcome); // so we just copy it in
outcome.setUserData(profileUtilities.UD_BASE_MODEL, getSourceStructureDefinition().getUrl());
outcome.setUserData(profileUtilities.UD_BASE_PATH, cursors.resultPathBase);
outcome.setUserData(UserDataNames.SNAPSHOT_BASE_MODEL, getSourceStructureDefinition().getUrl());
outcome.setUserData(UserDataNames.SNAPSHOT_BASE_PATH, cursors.resultPathBase);
cursors.baseCursor++;
}
}

View File

@ -100,6 +100,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus;
import org.hl7.fhir.r5.utils.formats.CSVWriter;
@ -412,12 +413,6 @@ public class ProfileUtilities {
}
}
public static final String UD_BASE_MODEL = "base.model";
public static final String UD_BASE_PATH = "base.path";
public static final String UD_DERIVATION_EQUALS = "derivation.equals";
public static final String UD_DERIVATION_POINTER = "derived.pointer";
public static final String UD_IS_DERIVED = "derived.fact";
public static final String UD_GENERATED_IN_SNAPSHOT = "profileutilities.snapshot.processed";
private static final boolean COPY_BINDING_EXTENSIONS = false;
private static final boolean DONT_DO_THIS = false;
@ -727,7 +722,7 @@ public class ProfileUtilities {
if (snapshotStack.contains(derived.getUrl())) {
throw new DefinitionException(context.formatMessage(I18nConstants.CIRCULAR_SNAPSHOT_REFERENCES_DETECTED_CANNOT_GENERATE_SNAPSHOT_STACK__, snapshotStack.toString()));
}
derived.setUserData("profileutils.snapshot.generating", true);
derived.setUserData(UserDataNames.SNAPSHOT_GENERATING, true);
snapshotStack.add(derived.getUrl());
try {
@ -755,7 +750,7 @@ public class ProfileUtilities {
for (ElementDefinition e : derived.getDifferential().getElement())
e.clearUserData(UD_GENERATED_IN_SNAPSHOT);
e.clearUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT);
// we actually delegate the work to a subroutine so we can re-enter it with a different cursors
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential()); // we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
@ -778,13 +773,13 @@ public class ProfileUtilities {
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
int i = 0;
for (ElementDefinition e : diff.getElement()) {
if (!e.hasUserData(UD_GENERATED_IN_SNAPSHOT) && e.getPath().contains(".")) {
if (!e.hasUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT) && e.getPath().contains(".")) {
ElementDefinition existing = getElementInCurrentContext(e.getPath(), derived.getSnapshot().getElement());
if (existing != null) {
updateFromDefinition(existing, e, profileName, false, url, base, derived, "StructureDefinition.differential.element["+i+"]", mappingDetails);
} else {
ElementDefinition outcome = updateURLs(url, webUrl, e.copy(), true);
e.setUserData(UD_GENERATED_IN_SNAPSHOT, outcome);
e.setUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT, outcome);
derived.getSnapshot().addElement(outcome);
if (walksInto(diff.getElement(), e)) {
if (e.getType().size() > 1) {
@ -813,22 +808,22 @@ public class ProfileUtilities {
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed));
System.out.println("diff: ");
for (ElementDefinition ed : diff.getElement())
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed)+" [gen = "+(ed.hasUserData(UD_GENERATED_IN_SNAPSHOT) ? ed.getUserData(UD_GENERATED_IN_SNAPSHOT) : "--")+"]");
System.out.println(" "+ed.getId()+" : "+typeSummaryWithProfile(ed)+"["+ed.getMin()+".."+ed.getMax()+"]"+sliceSummary(ed)+" "+constraintSummary(ed)+" [gen = "+(ed.hasUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT) ? ed.getUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT) : "--")+"]");
}
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
//Check that all differential elements have a corresponding snapshot element
int ce = 0;
int i = 0;
for (ElementDefinition e : diff.getElement()) {
if (!e.hasUserData("diff-source"))
if (!e.hasUserData(UserDataNames.SNAPSHOT_diff_source))
throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT));
else {
if (e.hasUserData(UD_DERIVATION_EQUALS))
((Base) e.getUserData("diff-source")).setUserData(UD_DERIVATION_EQUALS, e.getUserData(UD_DERIVATION_EQUALS));
if (e.hasUserData(UD_DERIVATION_POINTER))
((Base) e.getUserData("diff-source")).setUserData(UD_DERIVATION_POINTER, e.getUserData(UD_DERIVATION_POINTER));
if (e.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS))
((Base) e.getUserData(UserDataNames.SNAPSHOT_diff_source)).setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, e.getUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS));
if (e.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER))
((Base) e.getUserData(UserDataNames.SNAPSHOT_diff_source)).setUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER, e.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER));
}
if (!e.hasUserData(UD_GENERATED_IN_SNAPSHOT)) {
if (!e.hasUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT)) {
b.append(e.hasId() ? "id: "+e.getId() : "path: "+e.getPath());
ce++;
if (e.hasId()) {
@ -902,7 +897,7 @@ public class ProfileUtilities {
int count = slice.checkMin();
boolean repeats = !"1".equals(slice.getFocus().getBase().getMax()); // type slicing if repeats = 1
if (count > -1 && repeats) {
if (slice.getFocus().hasUserData("auto-added-slicing")) {
if (slice.getFocus().hasUserData(UserDataNames.SNAPSHOT_auto_added_slicing)) {
slice.getFocus().setMin(count);
} else {
String msg = "The slice definition for "+slice.getFocus().getId()+" has a minimum of "+slice.getFocus().getMin()+" but the slices add up to a minimum of "+count;
@ -985,15 +980,15 @@ public class ProfileUtilities {
} catch (Exception e) {
// if we had an exception generating the snapshot, make sure we don't leave any half generated snapshot behind
derived.setSnapshot(null);
derived.clearUserData("profileutils.snapshot.generating");
derived.clearUserData(UserDataNames.SNAPSHOT_GENERATING);
throw e;
}
} finally {
derived.clearUserData("profileutils.snapshot.generating");
derived.clearUserData(UserDataNames.SNAPSHOT_GENERATING);
snapshotStack.remove(derived.getUrl());
}
derived.setUserData("profileutils.snapshot.generated", true); // used by the publisher
derived.setUserData("profileutils.snapshot.generated.messages", messages); // used by the publisher
derived.setUserData(UserDataNames.SNAPSHOT_GENERATED, true); // used by the publisher
derived.setUserData(UserDataNames.SNAPSHOT_GENERATED_MESSAGES, messages); // used by the publisher
}
@ -1304,7 +1299,7 @@ public class ProfileUtilities {
for (ElementDefinition sed : source.getElement()) {
ElementDefinition ted = sed.copy();
diff.getElement().add(ted);
ted.setUserData("diff-source", sed);
ted.setUserData(UserDataNames.SNAPSHOT_diff_source, sed);
}
return diff;
}
@ -1504,12 +1499,12 @@ public class ProfileUtilities {
}
protected boolean isGenerating(StructureDefinition sd) {
return sd.hasUserData("profileutils.snapshot.generating");
return sd.hasUserData(UserDataNames.SNAPSHOT_GENERATING);
}
protected void checkNotGenerating(StructureDefinition sd, String role) {
if (sd.hasUserData("profileutils.snapshot.generating")) {
if (sd.hasUserData(UserDataNames.SNAPSHOT_GENERATING)) {
throw new FHIRException(context.formatMessage(I18nConstants.ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED, sd.getUrl(), role));
}
}
@ -1792,7 +1787,7 @@ public class ProfileUtilities {
protected void markDerived(ElementDefinition outcome) {
for (ElementDefinitionConstraintComponent inv : outcome.getConstraint())
inv.setUserData(UD_IS_DERIVED, true);
inv.setUserData(UserDataNames.SNAPSHOT_IS_DERIVED, true);
}
@ -1823,8 +1818,8 @@ public class ProfileUtilities {
protected void updateFromBase(ElementDefinition derived, ElementDefinition base, String baseProfileUrl) {
derived.setUserData(UD_BASE_MODEL, baseProfileUrl);
derived.setUserData(UD_BASE_PATH, base.getPath());
derived.setUserData(UserDataNames.SNAPSHOT_BASE_MODEL, baseProfileUrl);
derived.setUserData(UserDataNames.SNAPSHOT_BASE_PATH, base.getPath());
if (base.hasBase()) {
if (!derived.hasBase())
derived.setBase(new ElementDefinitionBaseComponent());
@ -2395,12 +2390,12 @@ public class ProfileUtilities {
protected void updateFromDefinition(ElementDefinition dest, ElementDefinition source, String pn, boolean trimDifferential, String purl, StructureDefinition srcSD, StructureDefinition derivedSrc, String path, MappingAssistant mappings) throws DefinitionException, FHIRException {
source.setUserData(UD_GENERATED_IN_SNAPSHOT, dest);
source.setUserData(UserDataNames.SNAPSHOT_GENERATED_IN_SNAPSHOT, dest);
// we start with a clone of the base profile ('dest') and we copy from the profile ('source')
// over the top for anything the source has
ElementDefinition base = dest;
ElementDefinition derived = source;
derived.setUserData(UD_DERIVATION_POINTER, base);
derived.setUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER, base);
boolean isExtension = checkExtensionDoco(base);
List<ElementDefinition> obligationProfileElements = new ArrayList<>();
for (StructureDefinition sd : obligationProfiles) {
@ -2461,7 +2456,7 @@ public class ProfileUtilities {
throw new DefinitionException(context.formatMessage(I18nConstants.SNAPSHOT_IS_EMPTY, profile.getVersionedUrl()));
}
ElementDefinition e = profile.getSnapshot().getElement().get(0);
String webroot = profile.getUserString("webroot");
String webroot = profile.getUserString(UserDataNames.render_webroot);
if (e.hasDefinition()) {
base.setDefinition(processRelativeUrls(e.getDefinition(), webroot, context.getSpecUrl(), context.getResourceNames(), masterSourceFileNames, localFileNames, true));
@ -2506,7 +2501,7 @@ public class ProfileUtilities {
else if (trimDifferential)
derived.setShortElement(null);
else if (derived.hasShortElement())
derived.getShortElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getShortElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasDefinitionElement()) {
@ -2517,7 +2512,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setDefinitionElement(null);
else if (derived.hasDefinitionElement())
derived.getDefinitionElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getDefinitionElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasCommentElement()) {
@ -2528,7 +2523,7 @@ public class ProfileUtilities {
else if (trimDifferential)
base.setCommentElement(derived.getCommentElement().copy());
else if (derived.hasCommentElement())
derived.getCommentElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getCommentElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasLabelElement()) {
@ -2539,7 +2534,7 @@ public class ProfileUtilities {
else if (trimDifferential)
base.setLabelElement(derived.getLabelElement().copy());
else if (derived.hasLabelElement())
derived.getLabelElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getLabelElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasRequirementsElement()) {
@ -2550,7 +2545,7 @@ public class ProfileUtilities {
else if (trimDifferential)
base.setRequirementsElement(derived.getRequirementsElement().copy());
else if (derived.hasRequirementsElement())
derived.getRequirementsElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getRequirementsElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
// sdf-9
if (derived.hasRequirements() && !base.getPath().contains("."))
@ -2568,7 +2563,7 @@ public class ProfileUtilities {
derived.getAlias().clear();
else
for (StringType t : derived.getAlias())
t.setUserData(UD_DERIVATION_EQUALS, true);
t.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasMinElement()) {
@ -2579,7 +2574,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setMinElement(null);
else
derived.getMinElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getMinElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasMaxElement()) {
@ -2590,7 +2585,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setMaxElement(null);
else
derived.getMaxElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getMaxElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasFixed()) {
@ -2599,7 +2594,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setFixed(null);
else
derived.getFixed().setUserData(UD_DERIVATION_EQUALS, true);
derived.getFixed().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasPattern()) {
@ -2609,7 +2604,7 @@ public class ProfileUtilities {
if (trimDifferential)
derived.setPattern(null);
else
derived.getPattern().setUserData(UD_DERIVATION_EQUALS, true);
derived.getPattern().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
List<ElementDefinitionExampleComponent> toDelB = new ArrayList<>();
@ -2636,7 +2631,7 @@ public class ProfileUtilities {
} else if (trimDifferential) {
derived.getExample().remove(ex);
} else {
ex.setUserData(UD_DERIVATION_EQUALS, true);
ex.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
}
}
@ -2649,7 +2644,7 @@ public class ProfileUtilities {
else if (trimDifferential)
derived.setMaxLengthElement(null);
else
derived.getMaxLengthElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getMaxLengthElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasMaxValue()) {
@ -2658,7 +2653,7 @@ public class ProfileUtilities {
else if (trimDifferential)
derived.setMaxValue(null);
else
derived.getMaxValue().setUserData(UD_DERIVATION_EQUALS, true);
derived.getMaxValue().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasMinValue()) {
@ -2667,7 +2662,7 @@ public class ProfileUtilities {
else if (trimDifferential)
derived.setMinValue(null);
else
derived.getMinValue().setUserData(UD_DERIVATION_EQUALS, true);
derived.getMinValue().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
// todo: what to do about conditions?
@ -2693,7 +2688,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setMustSupportElement(null);
else
derived.getMustSupportElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getMustSupportElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasMustHaveValueElement()) {
@ -2705,7 +2700,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setMustHaveValueElement(null);
else
derived.getMustHaveValueElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getMustHaveValueElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasValueAlternatives()) {
if (!Base.compareDeep(derived.getValueAlternatives(), base.getValueAlternatives(), false))
@ -2717,7 +2712,7 @@ public class ProfileUtilities {
derived.getValueAlternatives().clear();
else
for (CanonicalType t : derived.getValueAlternatives())
t.setUserData(UD_DERIVATION_EQUALS, true);
t.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
// profiles cannot change : isModifier, defaultValue, meaningWhenMissing
@ -2728,13 +2723,13 @@ public class ProfileUtilities {
else if (trimDifferential)
derived.setIsModifierElement(null);
else if (derived.hasIsModifierElement())
derived.getIsModifierElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getIsModifierElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
if (derived.hasIsModifierReasonElement() && !(base.hasIsModifierReasonElement() && Base.compareDeep(derived.getIsModifierReasonElement(), base.getIsModifierReasonElement(), false)))
base.setIsModifierReasonElement(derived.getIsModifierReasonElement().copy());
else if (trimDifferential)
derived.setIsModifierReasonElement(null);
else if (derived.hasIsModifierReasonElement())
derived.getIsModifierReasonElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getIsModifierReasonElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
boolean hasBinding = derived.hasBinding();
@ -2830,7 +2825,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setBinding(null);
else
derived.getBinding().setUserData(UD_DERIVATION_EQUALS, true);
derived.getBinding().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
} else if (base.hasBinding()) {
base.getBinding().getExtension().removeIf(ext -> Utilities.existsInList(ext.getUrl(), ProfileUtilities.NON_INHERITED_ED_URLS));
}
@ -2843,7 +2838,7 @@ public class ProfileUtilities {
} else if (trimDifferential)
derived.setIsSummaryElement(null);
else
derived.getIsSummaryElement().setUserData(UD_DERIVATION_EQUALS, true);
derived.getIsSummaryElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
if (derived.hasType()) {
@ -2864,14 +2859,14 @@ public class ProfileUtilities {
derived.getType().clear();
else
for (TypeRefComponent t : derived.getType())
t.setUserData(UD_DERIVATION_EQUALS, true);
t.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
mappings.merge(derived, base); // note reversal of names to be correct in .merge()
// todo: constraints are cumulative. there is no replacing
for (ElementDefinitionConstraintComponent s : base.getConstraint()) {
s.setUserData(UD_IS_DERIVED, true);
s.setUserData(UserDataNames.SNAPSHOT_IS_DERIVED, true);
if (!s.hasSource()) {
s.setSource(srcSD.getUrl());
}
@ -3505,7 +3500,7 @@ public class ProfileUtilities {
public void sortDifferential(StructureDefinition base, StructureDefinition diff, String name, List<String> errors, boolean errorIfChanges) throws FHIRException {
int index = 0;
for (ElementDefinition ed : diff.getDifferential().getElement()) {
ed.setUserData("ed.index", Integer.toString(index));
ed.setUserData(UserDataNames.SNAPSHOT_SORT_ed_index, Integer.toString(index));
index++;
}
List<ElementDefinition> original = new ArrayList<>();
@ -3565,7 +3560,7 @@ public class ProfileUtilities {
ElementDefinition e = diffList.get(i);
ElementDefinition n = newDiff.get(i);
if (!n.getPath().equals(e.getPath())) {
errors.add("The element "+(e.hasId() ? e.getId() : e.getPath())+" @diff["+e.getUserString("ed.index")+"] is out of order (and maybe others after it)");
errors.add("The element "+(e.hasId() ? e.getId() : e.getPath())+" @diff["+e.getUserString(UserDataNames.SNAPSHOT_SORT_ed_index)+"] is out of order (and maybe others after it)");
return;
}
}
@ -4252,8 +4247,8 @@ public class ProfileUtilities {
// first, name them
int i = 0;
for (ElementDefinition ed : slices) {
if (ed.hasUserData("slice-name")) {
ed.setSliceName(ed.getUserString("slice-name"));
if (ed.hasUserData(UserDataNames.SNAPSHOT_slice_name)) {
ed.setSliceName(ed.getUserString(UserDataNames.SNAPSHOT_slice_name));
} else {
i++;
ed.setSliceName("slice-"+Integer.toString(i));

View File

@ -136,6 +136,7 @@ import org.hl7.fhir.r5.terminologies.client.TerminologyClientContext;
import org.hl7.fhir.r5.utils.PackageHackerR5;
import org.hl7.fhir.r5.utils.ResourceUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.client.EFhirClientException;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
import org.hl7.fhir.utilities.FhirPublication;
@ -1116,7 +1117,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} else {
be.getRequest().setUrl("CodeSystem/$validate-code");
}
be.setUserData("source", codingValidationRequest);
be.setUserData(UserDataNames.TX_REQUEST, codingValidationRequest);
systems.add(codingValidationRequest.getCoding().getSystem());
findRelevantSystems(systems, codingValidationRequest.getCoding());
}
@ -1126,7 +1127,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
TerminologyClientContext tc = terminologyClientManager.chooseServer(vs, systems, false);
Bundle resp = processBatch(tc, batch, systems);
for (int i = 0; i < batch.getEntry().size(); i++) {
CodingValidationRequest t = (CodingValidationRequest) batch.getEntry().get(i).getUserData("source");
CodingValidationRequest t = (CodingValidationRequest) batch.getEntry().get(i).getUserData(UserDataNames.TX_REQUEST);
BundleEntryComponent r = resp.getEntry().get(i);
if (r.getResource() instanceof Parameters) {
@ -1224,7 +1225,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
} else {
be.getRequest().setUrl("CodeSystem/$validate-code");
}
be.setUserData("source", codingValidationRequest);
be.setUserData(UserDataNames.TX_REQUEST, codingValidationRequest);
systems.add(codingValidationRequest.getCoding().getSystem());
}
}
@ -1233,7 +1234,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
if (batch.getEntry().size() > 0) {
Bundle resp = processBatch(tc, batch, systems);
for (int i = 0; i < batch.getEntry().size(); i++) {
CodingValidationRequest t = (CodingValidationRequest) batch.getEntry().get(i).getUserData("source");
CodingValidationRequest t = (CodingValidationRequest) batch.getEntry().get(i).getUserData(UserDataNames.TX_REQUEST);
BundleEntryComponent r = resp.getEntry().get(i);
if (r.getResource() instanceof Parameters) {
@ -3275,7 +3276,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
web = Utilities.pathURL(svs.getServer(), "ValueSet", svs.getVs().getIdBase());
}
svs.getVs().setWebPath(web);
svs.getVs().setUserData("External.Link", svs.getServer()); // so we can render it differently
svs.getVs().setUserData(UserDataNames.render_external_link, svs.getServer()); // so we can render it differently
}
if (svs == null) {
return null;
@ -3297,7 +3298,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
web = Utilities.pathURL(scs.getServer(), "ValueSet", scs.getCs().getIdBase());
}
scs.getCs().setWebPath(web);
scs.getCs().setUserData("External.Link", scs.getServer()); // so we can render it differently
scs.getCs().setUserData(UserDataNames.render_external_link, scs.getServer()); // so we can render it differently
}
if (scs == null) {
return null;

View File

@ -26,6 +26,7 @@ import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
import org.hl7.fhir.r5.model.StructureMap;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.NamingSystem;
@ -278,7 +279,7 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
for (String err : errors) {
msgs.add(new ValidationMessage(Source.ProfileValidator, IssueType.EXCEPTION, p.getWebPath(), "Error sorting Differential: "+err, ValidationMessage.IssueSeverity.ERROR));
}
pu.generateSnapshot(sd, p, p.getUrl(), sd.getUserString("webroot"), p.getName());
pu.generateSnapshot(sd, p, p.getUrl(), sd.getUserString(UserDataNames.render_webroot), p.getName());
for (ValidationMessage msg : msgs) {
if ((!ProfileUtilities.isSuppressIgnorableExceptions() && msg.getLevel() == ValidationMessage.IssueSeverity.ERROR) || msg.getLevel() == ValidationMessage.IssueSeverity.FATAL) {
if (!msg.isIgnorableError()) {
@ -298,9 +299,9 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
// work around the fact that some Implementation guides were published with old snapshot generators that left invalid snapshots behind.
private boolean isProfileNeedsRegenerate(StructureDefinition p) {
boolean needs = !p.hasUserData("hack.regnerated") && Utilities.existsInList(p.getUrl(), "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse");
boolean needs = !p.hasUserData(UserDataNames.SNAPSHOT_regeneration_tracker) && Utilities.existsInList(p.getUrl(), "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse");
if (needs) {
p.setUserData("hack.regnerated", "yes");
p.setUserData(UserDataNames.SNAPSHOT_regeneration_tracker, "yes");
}
return needs;
}

View File

@ -71,7 +71,9 @@ import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager;
import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager.ITerminologyClientFactory;
import org.hl7.fhir.r5.terminologies.client.TerminologyClientR5;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.r5.utils.R5Hacker;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.utilities.ByteProvider;
import org.hl7.fhir.utilities.MagicResources;
@ -139,8 +141,8 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
}
public interface IValidatorFactory {
IResourceValidator makeValidator(IWorkerContext ctxt) throws FHIRException;
IResourceValidator makeValidator(IWorkerContext ctxts, XVerExtensionManager xverManager) throws FHIRException;
IResourceValidator makeValidator(IWorkerContext ctxt, ValidatorSession session) throws FHIRException;
IResourceValidator makeValidator(IWorkerContext ctxts, XVerExtensionManager xverManager, ValidatorSession session) throws FHIRException;
}
private Questionnaire questionnaire;
@ -610,7 +612,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
public IResourceValidator newValidator() throws FHIRException {
if (validatorFactory == null)
throw new Error(formatMessage(I18nConstants.NO_VALIDATOR_CONFIGURED));
return validatorFactory.makeValidator(this, xverManager).setJurisdiction(JurisdictionUtilities.getJurisdictionCodingFromLocale(Locale.getDefault().getCountry()));
return validatorFactory.makeValidator(this, xverManager, null).setJurisdiction(JurisdictionUtilities.getJurisdictionCodingFromLocale(Locale.getDefault().getCountry()));
}
@ -620,7 +622,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
public List<String> getResourceNames() {
Set<String> result = new HashSet<String>();
for (StructureDefinition sd : listStructures()) {
if (sd.getKind() == StructureDefinitionKind.RESOURCE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && !sd.hasUserData("old.load.mode"))
if (sd.getKind() == StructureDefinitionKind.RESOURCE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && !sd.hasUserData(UserDataNames.loader_urls_patched))
result.add(sd.getName());
}
return Utilities.sorted(result);

View File

@ -12,6 +12,7 @@ import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.Utilities;
public class TypeManager {
@ -55,7 +56,7 @@ public class TypeManager {
typeDefinitions.put(type, types);
}
types.add(sd);
if (sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/")) {
if (sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/") || "true".equals(sd.getUserString(UserDataNames.loader_custom_resource))) {
types = fhirTypeDefinitions.get(type);
if (types == null) {
types = new HashSet<>();

View File

@ -54,6 +54,7 @@ import org.hl7.fhir.r5.model.TypeConvertor;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.ElementDecoration;
import org.hl7.fhir.utilities.ElementDecoration.DecorationType;
import org.hl7.fhir.utilities.FhirPublication;
@ -691,7 +692,7 @@ public class Element extends Base implements NamedItem {
}
public void clearDecorations() {
clearUserData("fhir.decorations");
clearUserData(UserDataNames.rendering_xml_decorations);
for (Element e : children) {
e.clearDecorations();
}
@ -699,10 +700,10 @@ public class Element extends Base implements NamedItem {
public void markValidation(StructureDefinition profile, ElementDefinition definition) {
@SuppressWarnings("unchecked")
List<ElementDecoration> decorations = (List<ElementDecoration>) getUserData("fhir.decorations");
List<ElementDecoration> decorations = (List<ElementDecoration>) getUserData(UserDataNames.rendering_xml_decorations);
if (decorations == null) {
decorations = new ArrayList<>();
setUserData("fhir.decorations", decorations);
setUserData(UserDataNames.rendering_xml_decorations, decorations);
}
decorations.add(new ElementDecoration(DecorationType.TYPE, profile.getWebPath(), definition.getPath()));
if (definition.getId() != null && tail(definition.getId()).contains(":")) {

View File

@ -28,6 +28,7 @@ import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.AcceptLanguageHeader;
@ -59,11 +60,6 @@ public class LanguageUtils {
public static final List<String> TRANSLATION_SUPPLEMENT_RESOURCE_TYPES = Arrays.asList("CodeSystem", "StructureDefinition", "Questionnaire");
private static final String ORPHAN_TRANSLATIONS_NAME = "translations.orphans";
private static final String SUPPLEMENT_SOURCE_RESOURCE = "translations.supplemented";
private static final String SUPPLEMENT_SOURCE_TRANSLATIONS = "translations.source-list";
IWorkerContext context;
private List<String> crlist;
@ -401,8 +397,8 @@ public class LanguageUtils {
}
public void fillSupplement(CodeSystem csSrc, CodeSystem csDst, List<TranslationUnit> list) {
csDst.setUserData(SUPPLEMENT_SOURCE_RESOURCE, csSrc);
csDst.setUserData(SUPPLEMENT_SOURCE_TRANSLATIONS, list);
csDst.setUserData(UserDataNames.LANGUTILS_SOURCE_SUPPLEMENT, csSrc);
csDst.setUserData(UserDataNames.LANGUTILS_SOURCE_TRANSLATIONS, list);
for (TranslationUnit tu : list) {
String code = tu.getId();
String subCode = null;
@ -458,10 +454,10 @@ public class LanguageUtils {
}
private void addOrphanTranslation(CodeSystem cs, TranslationUnit tu) {
List<TranslationUnit> list = (List<TranslationUnit>) cs.getUserData(ORPHAN_TRANSLATIONS_NAME);
List<TranslationUnit> list = (List<TranslationUnit>) cs.getUserData(UserDataNames.LANGUTILS_ORPHAN);
if (list == null) {
list = new ArrayList<>();
cs.setUserData(ORPHAN_TRANSLATIONS_NAME, list);
cs.setUserData(UserDataNames.LANGUTILS_ORPHAN, list);
}
list.add(tu);
}
@ -489,7 +485,7 @@ public class LanguageUtils {
}
public boolean handlesAsResource(Resource resource) {
return (resource instanceof CodeSystem && resource.hasUserData(SUPPLEMENT_SOURCE_RESOURCE)) || (resource instanceof StructureDefinition);
return (resource instanceof CodeSystem && resource.hasUserData(UserDataNames.LANGUTILS_SOURCE_SUPPLEMENT)) || (resource instanceof StructureDefinition);
}
public boolean handlesAsElement(Element element) {
@ -501,20 +497,20 @@ public class LanguageUtils {
if (res instanceof StructureDefinition) {
StructureDefinition sd = (StructureDefinition) res;
generateTranslations(list, sd, lang);
if (res.hasUserData(ORPHAN_TRANSLATIONS_NAME)) {
List<TranslationUnit> orphans = (List<TranslationUnit>) res.getUserData(ORPHAN_TRANSLATIONS_NAME);
if (res.hasUserData(UserDataNames.LANGUTILS_ORPHAN)) {
List<TranslationUnit> orphans = (List<TranslationUnit>) res.getUserData(UserDataNames.LANGUTILS_ORPHAN);
for (TranslationUnit t : orphans) {
list.add(new TranslationUnit(lang, "!!"+t.getId(), t.getContext1(), t.getSrcText(), t.getTgtText()));
}
}
} else {
CodeSystem cs = (CodeSystem) res.getUserData(SUPPLEMENT_SOURCE_RESOURCE);
List<TranslationUnit> inputs = res.hasUserData(SUPPLEMENT_SOURCE_TRANSLATIONS) ? (List<TranslationUnit>) res.getUserData(SUPPLEMENT_SOURCE_TRANSLATIONS) : new ArrayList<>();
CodeSystem cs = (CodeSystem) res.getUserData(UserDataNames.LANGUTILS_SOURCE_SUPPLEMENT);
List<TranslationUnit> inputs = res.hasUserData(UserDataNames.LANGUTILS_SOURCE_TRANSLATIONS) ? (List<TranslationUnit>) res.getUserData(UserDataNames.LANGUTILS_SOURCE_TRANSLATIONS) : new ArrayList<>();
for (ConceptDefinitionComponent cd : cs.getConcept()) {
generateTranslations(list, cd, lang, inputs);
}
if (cs.hasUserData(ORPHAN_TRANSLATIONS_NAME)) {
List<TranslationUnit> orphans = (List<TranslationUnit>) cs.getUserData(ORPHAN_TRANSLATIONS_NAME);
if (cs.hasUserData(UserDataNames.LANGUTILS_ORPHAN)) {
List<TranslationUnit> orphans = (List<TranslationUnit>) cs.getUserData(UserDataNames.LANGUTILS_ORPHAN);
for (TranslationUnit t : orphans) {
list.add(new TranslationUnit(lang, "!!"+t.getId(), t.getContext1(), t.getSrcText(), t.getTgtText()));
}

View File

@ -66,6 +66,7 @@ import org.hl7.fhir.r5.model.ElementDefinition.PropertyRepresentation;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.formats.XmlLocationAnnotator;
import org.hl7.fhir.r5.utils.formats.XmlLocationData;
import org.hl7.fhir.utilities.ElementDecoration;
@ -802,7 +803,7 @@ public class XmlParser extends ParserBase {
if (!(isElideElements() && element.isElided())) {
if (showDecorations) {
@SuppressWarnings("unchecked")
List<ElementDecoration> decorations = (List<ElementDecoration>) element.getUserData("fhir.decorations");
List<ElementDecoration> decorations = (List<ElementDecoration>) element.getUserData(UserDataNames.rendering_xml_decorations);
if (decorations != null)
for (ElementDecoration d : decorations)
xml.decorate(d);

View File

@ -36,6 +36,7 @@ import java.util.Date;
import java.util.List;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.r5.model.Enumerations.*;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.ICompositeType;
@ -596,8 +597,8 @@ public abstract class CanonicalResource extends DomainResource {
}
public String present() {
if (hasUserData("presentation")) {
return getUserString("presentation");
if (hasUserData(UserDataNames.render_presentation)) {
return getUserString(UserDataNames.render_presentation);
}
if (hasTitle())
return getTitle();

View File

@ -53,6 +53,7 @@ import org.hl7.fhir.r5.profilemodel.PEBuilder;
import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy;
import org.hl7.fhir.r5.profilemodel.gen.PECodeGenerator.ExtensionPolicy;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.profilemodel.PEDefinition;
import org.hl7.fhir.r5.profilemodel.PEInstance;
import org.hl7.fhir.r5.profilemodel.PEType;
@ -261,14 +262,14 @@ public class PECodeGenerator {
if (cc.getAbstract()) {
code = "_"+code;
}
cc.setUserData("java.code", code);
cc.setUserData(UserDataNames.java_code, code);
w(enums, " "+code+(i < vse.getValueset().getExpansion().getContains().size() - 1 ? "," : ";")+" // \""+cc.getDisplay()+"\" = "+cc.getSystem()+"#"+cc.getCode());
}
w(enums, "");
w(enums, " public static "+name+" fromCode(String s) {");
w(enums, " switch (s) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case \""+cc.getCode()+"\": return "+cc.getUserString("java.code")+";");
w(enums, " case \""+cc.getCode()+"\": return "+cc.getUserString(UserDataNames.java_code)+";");
}
w(enums, " default: return null;");
w(enums, " }");
@ -281,7 +282,7 @@ public class PECodeGenerator {
} else {
w(enums, " if (\""+cc.getSystem()+"\".equals(c.getSystem()) && \""+cc.getCode()+"\".equals(c.getCode())) {");
}
w(enums, " return "+cc.getUserString("java.code")+";");
w(enums, " return "+cc.getUserString(UserDataNames.java_code)+";");
w(enums, " }");
}
w(enums, " return null;");
@ -301,7 +302,7 @@ public class PECodeGenerator {
w(enums, " public String toDisplay() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case "+cc.getUserString("java.code")+": return \""+Utilities.escapeJava(cc.getDisplay())+"\";");
w(enums, " case "+cc.getUserString(UserDataNames.java_code)+": return \""+Utilities.escapeJava(cc.getDisplay())+"\";");
}
w(enums, " default: return null;");
w(enums, " }");
@ -311,7 +312,7 @@ public class PECodeGenerator {
w(enums, " public String toCode() {");
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
w(enums, " case "+cc.getUserString("java.code")+": return \""+cc.getCode()+"\";");
w(enums, " case "+cc.getUserString(UserDataNames.java_code)+": return \""+cc.getCode()+"\";");
}
w(enums, " default: return null;");
w(enums, " }");
@ -321,9 +322,9 @@ public class PECodeGenerator {
w(enums, " switch (this) {");
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
if (cc.hasVersion()) {
w(enums, " case "+cc.getUserString("java.code")+": return new Coding().setSystem(\""+cc.getSystem()+"\").setVersion(\""+cc.getVersion()+"\").setCode()\""+cc.getCode()+"\";");
w(enums, " case "+cc.getUserString(UserDataNames.java_code)+": return new Coding().setSystem(\""+cc.getSystem()+"\").setVersion(\""+cc.getVersion()+"\").setCode()\""+cc.getCode()+"\";");
} else {
w(enums, " case "+cc.getUserString("java.code")+": return new Coding().setSystem(\""+cc.getSystem()+"\").setCode(\""+cc.getCode()+"\");");
w(enums, " case "+cc.getUserString(UserDataNames.java_code)+": return new Coding().setSystem(\""+cc.getSystem()+"\").setCode(\""+cc.getCode()+"\");");
}
}
w(enums, " default: return null;");

View File

@ -20,6 +20,7 @@ import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.CodeResolver.CodeResolution;
import org.hl7.fhir.r5.renderers.Renderer.RenderingStatus;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
@ -117,7 +118,7 @@ public class AdditionalBindingsRenderer {
abr.compare = new AdditionalBindingDetail();
abr.compare.valueSet = compExt==null ? null : compExt.getValue().primitiveValue();
} else {
abr.isUnchanged = ext.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
abr.isUnchanged = ext.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS);
}
bindings.add(abr);
}
@ -181,7 +182,7 @@ public class AdditionalBindingsRenderer {
}
}
abr.any = "any".equals(ext.getExtensionString("scope"));
abr.isUnchanged = ext.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
abr.isUnchanged = ext.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS);
return abr;
}
@ -193,7 +194,7 @@ public class AdditionalBindingsRenderer {
abr.docoShort = ab.getShortDoco();
abr.usages.addAll(ab.getUsage());
abr.any = ab.getAny();
abr.isUnchanged = ab.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
abr.isUnchanged = ab.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS);
return abr;
}

View File

@ -35,6 +35,7 @@ import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.CodeSystemNavigator;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.LoincLinker;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -409,7 +410,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
}
private boolean conceptsHaveVersion(ConceptDefinitionComponent c) {
if (c.hasUserData("cs.version.notes"))
if (c.hasUserData(UserDataNames.tx_cs_version_notes))
return true;
for (ConceptDefinitionComponent g : c.getConcept())
if (conceptsHaveVersion(g))
@ -567,8 +568,9 @@ public class CodeSystemRenderer extends TerminologyRenderer {
}
if (version) {
td = tr.td();
if (c.hasUserData("cs.version.notes"))
td.addText(c.getUserString("cs.version.notes"));
if (c.hasUserData(UserDataNames.tx_cs_version_notes)) { // todo: this is never set
td.addText(c.getUserString(UserDataNames.tx_cs_version_notes));
}
}
if (properties != null) {
for (PropertyComponent pc : properties) {

View File

@ -50,6 +50,7 @@ import org.hl7.fhir.r5.terminologies.JurisdictionUtilities;
import org.hl7.fhir.r5.terminologies.utilities.SnomedUtilities;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
@ -148,7 +149,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
url = p.getWebPath();
if (url == null) {
url = p.getUserString("filename");
url = p.getUserString(UserDataNames.render_filename);
}
} else {
throw new DefinitionException(context.formatPhrase(RenderingContext.DATA_REND_MKDWN_LNK, link) + " ");
@ -261,8 +262,8 @@ public class DataRenderer extends Renderer implements CodeResolver {
}
private String crPresent(CanonicalResource cr) {
if (cr.hasUserData("presentation")) {
return cr.getUserString("presentation");
if (cr.hasUserData(UserDataNames.render_presentation)) {
return cr.getUserString(UserDataNames.render_presentation);
}
if (cr.hasTitle())
return context.getTranslated(cr.getTitleElement());

View File

@ -19,6 +19,7 @@ import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.CodeResolver.CodeResolution;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece;
@ -65,7 +66,7 @@ public class ObligationsRenderer extends Renderer {
for (Extension eid : ext.getExtensionsByUrl("elementId")) {
this.elementIds.add(eid.getValue().primitiveValue());
}
this.isUnchanged = ext.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS);
this.isUnchanged = ext.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS);
}
private String getKey() {

View File

@ -12,6 +12,7 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
@ -87,7 +88,7 @@ public class Renderer {
if (b == null || context.getChangeVersion() == null) {
return x;
}
VersionComparisonAnnotation vca = (VersionComparisonAnnotation) b.getUserData(VersionComparisonAnnotation.USER_DATA_NAME);
VersionComparisonAnnotation vca = (VersionComparisonAnnotation) b.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
if (vca == null) {
return x;
}
@ -119,7 +120,7 @@ public class Renderer {
if (b == null || context.getChangeVersion() == null) {
return x;
}
VersionComparisonAnnotation vca = (VersionComparisonAnnotation) b.getUserData(VersionComparisonAnnotation.USER_DATA_NAME);
VersionComparisonAnnotation vca = (VersionComparisonAnnotation) b.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
if (vca == null) {
return x;
}
@ -152,7 +153,7 @@ public class Renderer {
if (b == null || context.getChangeVersion() == null) {
return tr.td();
}
VersionComparisonAnnotation vca = (VersionComparisonAnnotation) b.getUserData(VersionComparisonAnnotation.USER_DATA_NAME);
VersionComparisonAnnotation vca = (VersionComparisonAnnotation) b.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
if (vca == null) {
return tr.td();
}
@ -191,8 +192,8 @@ public class Renderer {
}
public static void renderStatusSummary(RenderingContext context, Base base, XhtmlNode x, String version, String... metadataFields) {
if (base.hasUserData(VersionComparisonAnnotation.USER_DATA_NAME)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(VersionComparisonAnnotation.USER_DATA_NAME);
if (base.hasUserData(UserDataNames.COMP_VERSION_ANNOTATION)) {
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(UserDataNames.COMP_VERSION_ANNOTATION);
switch (self.getType()) {
case Added:
XhtmlNode spanInner = x.span("background-color: #fff2ff; border-left: solid 3px #ffa0ff; margin: 2px; padding: 2px", context.formatPhrase(RenderingContext.REND_SINCE_ADDED, version));

View File

@ -70,7 +70,7 @@ public class RendererFactory {
switch (resource.fhirType()) {
case "DiagnosticReport": return new DiagnosticReportRenderer(context);
case "Library": return new LibraryRenderer(context);
case "Questionnaire": return new LibraryRenderer(context);
case "ViewDefinition": return new ViewDefinitionRenderer(context);
case "List": return new ListRenderer(context);
case "Patient": return new PatientRenderer(context);
case "Provenance": return new ProvenanceRenderer(context);

View File

@ -66,6 +66,10 @@ public abstract class ResourceRenderer extends DataRenderer {
return this;
}
public boolean renderingUsesValidation() {
return false;
}
/**
* Just build the narrative that would go in the resource (per @renderResource()), but don't put it in the resource
* @param dr

View File

@ -75,6 +75,7 @@ import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.PublicationHacker;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.StandardsStatus;
@ -292,8 +293,8 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
public void renderDetails(XhtmlNode f) {
if (value.hasUserData("render.link")) {
f = f.ah(context.prefixLocalHref(value.getUserString("render.link")));
if (value.hasUserData(UserDataNames.render_link)) {
f = f.ah(context.prefixLocalHref(value.getUserString(UserDataNames.render_link)));
}
f.tx(value.asStringValue());
}
@ -312,8 +313,8 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
public void renderDetails(XhtmlNode f) throws IOException {
if (value.hasUserData("render.link")) {
f = f.ah(context.prefixLocalHref(value.getUserString("render.link")));
if (value.hasUserData(UserDataNames.render_link)) {
f = f.ah(context.prefixLocalHref(value.getUserString(UserDataNames.render_link)));
}
f.tx(summarize(value));
}
@ -777,7 +778,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
} else {
row.setIcon("icon_resource.png", context.formatPhrase(RenderingContext.GENERAL_RESOURCE));
}
if (element.hasUserData("render.opaque")) {
if (element.hasUserData(UserDataNames.render_opaque)) {
row.setOpacity("0.5");
}
UnusedTracker used = new UnusedTracker();
@ -790,8 +791,8 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
if (logicalModel) {
if (element.hasRepresentation(PropertyRepresentation.XMLATTR)) {
sName = "@"+sName;
} else if (element.hasUserData("derived.pointer")) {
ElementDefinition drv = (ElementDefinition) element.getUserData("derived.pointer");
} else if (element.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER)) {
ElementDefinition drv = (ElementDefinition) element.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER);
if (drv.hasRepresentation(PropertyRepresentation.XMLATTR)) {
sName = "@"+sName;
}
@ -969,7 +970,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
private boolean isTypeSlice(ElementDefinition child) {
ElementDefinition derived = (ElementDefinition) child.getUserData("derived.pointer");
ElementDefinition derived = (ElementDefinition) child.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER);
return derived != null && derived.getBase().getPath().endsWith("[x]");
}
@ -1138,7 +1139,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
if (extDefn == null) {
res.add(genCardinality(gen, element, row, hasDef, used, null));
res.add(addCell(row, gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null)));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER), used.used, profile == null ? "" : profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
} else {
String name = element.hasSliceName() ? element.getSliceName() : urltail(eurl);
nameCell.getPieces().get(0).setText(name);
@ -1159,7 +1160,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
res.add(addCell(row, gen.new Cell()));
else
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
}
}
} else if (element != null) {
@ -1168,7 +1169,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root, mustSupport));
else
res.add(addCell(row, gen.new Cell()));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
res.add(generateDescription(status, gen, row, element, (ElementDefinition) element.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot, mustSupport, allowSubRows, rc, inScopeElements, resource));
}
return res;
}
@ -1176,18 +1177,18 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
private Cell genCardinality(HierarchicalTableGenerator gen, ElementDefinition definition, Row row, boolean hasDef, UnusedTracker tracker, ElementDefinition fallback) {
IntegerType min = !hasDef ? new IntegerType() : definition.hasMinElement() ? definition.getMinElement() : new IntegerType();
StringType max = !hasDef ? new StringType() : definition.hasMaxElement() ? definition.getMaxElement() : new StringType();
if (min.isEmpty() && definition.getUserData(ProfileUtilities.UD_DERIVATION_POINTER) != null) {
ElementDefinition base = (ElementDefinition) definition.getUserData(ProfileUtilities.UD_DERIVATION_POINTER);
if (min.isEmpty() && definition.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER) != null) {
ElementDefinition base = (ElementDefinition) definition.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER);
if (base.hasMinElement()) {
min = base.getMinElement().copy();
min.setUserData(ProfileUtilities.UD_DERIVATION_EQUALS, true);
min.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
}
if (max.isEmpty() && definition.getUserData(ProfileUtilities.UD_DERIVATION_POINTER) != null) {
ElementDefinition base = (ElementDefinition) definition.getUserData(ProfileUtilities.UD_DERIVATION_POINTER);
if (max.isEmpty() && definition.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER) != null) {
ElementDefinition base = (ElementDefinition) definition.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER);
if (base.hasMaxElement()) {
max = base.getMaxElement().copy();
max.setUserData(ProfileUtilities.UD_DERIVATION_EQUALS, true);
max.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
}
}
if (min.isEmpty() && fallback != null)
@ -1848,14 +1849,14 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
private Piece checkForNoChange(Element source, Piece piece) {
if (source.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS)) {
if (source.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS)) {
piece.addStyle("opacity: 0.5");
}
return piece;
}
private String checkForNoChange(Element source) {
if (source.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS)) {
if (source.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS)) {
return "opacity: 0.5";
} else {
return null;
@ -1875,7 +1876,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
c.getPieces().add(gen.new Piece("#"+ed.getElement().getPath(), tail(ed.getElement().getPath()), ed.getElement().getPath()));
} else {
c.getPieces().add(gen.new Piece(null, context.formatPhrase(RenderingContext.STRUC_DEF_SEE)+" ", null));
c.getPieces().add(gen.new Piece(pfx(corePath, ed.getSource().getWebPath())+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getTypeName()+")", ed.getElement().getPath()));
c.getPieces().add(gen.new Piece(typePath(corePath, ed.getSource())+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getTypeName()+")", ed.getElement().getPath()));
}
}
return c;
@ -1899,12 +1900,12 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
} else if (e.hasContentReference()) {
return c;
} else {
ElementDefinition d = (ElementDefinition) e.getUserData(ProfileUtilities.UD_DERIVATION_POINTER);
ElementDefinition d = (ElementDefinition) e.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER);
if (d != null && d.hasType()) {
types = new ArrayList<ElementDefinition.TypeRefComponent>();
for (TypeRefComponent tr : d.getType()) {
TypeRefComponent tt = tr.copy();
tt.setUserData(ProfileUtilities.UD_DERIVATION_EQUALS, true);
tt.setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, true);
types.add(tt);
}
} else {
@ -2054,6 +2055,14 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
private String typePath(String cp, StructureDefinition source) {
if (source.hasUserData(UserDataNames.loader_custom_resource)) {
return source.getWebPath();
} else {
return pfx(cp, source.getWebPath());
}
}
private boolean hasMultipleVersions(List<? extends CanonicalResource> list) {
Set<String> vl = new HashSet<>();
for (CanonicalResource cr : list) {
@ -2281,33 +2290,33 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
private ElementDefinitionBindingComponent makeUnifiedBinding(ElementDefinitionBindingComponent binding, ElementDefinition element) {
if (!element.hasUserData(ProfileUtilities.UD_DERIVATION_POINTER)) {
if (!element.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER)) {
return binding;
}
ElementDefinition base = (ElementDefinition) element.getUserData(ProfileUtilities.UD_DERIVATION_POINTER);
ElementDefinition base = (ElementDefinition) element.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER);
if (!base.hasBinding()) {
return binding;
}
ElementDefinitionBindingComponent o = base.getBinding();
ElementDefinitionBindingComponent b = new ElementDefinitionBindingComponent();
b.setUserData(ProfileUtilities.UD_DERIVATION_POINTER, o);
b.setUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER, o);
if (binding.hasValueSet()) {
b.setValueSet(binding.getValueSet());
} else if (o.hasValueSet()) {
b.setValueSet(o.getValueSet());
b.getValueSetElement().setUserData(ProfileUtilities.UD_DERIVATION_EQUALS, o.getValueSetElement());
b.getValueSetElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, o.getValueSetElement());
}
if (binding.hasStrength()) {
b.setStrength(binding.getStrength());
} else if (o.hasStrength()) {
b.setStrength(o.getStrength());
b.getStrengthElement().setUserData(ProfileUtilities.UD_DERIVATION_EQUALS, o.getStrengthElement());
b.getStrengthElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, o.getStrengthElement());
}
if (binding.hasDescription()) {
b.setDescription(binding.getDescription());
} else if (o.hasDescription()) {
b.setDescription(o.getDescription());
b.getDescriptionElement().setUserData(ProfileUtilities.UD_DERIVATION_EQUALS, o.getDescriptionElement());
b.getDescriptionElement().setUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS, o.getDescriptionElement());
}
// todo: derivation?
b.getExtension().addAll(binding.getExtension());
@ -2913,7 +2922,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
private Piece checkForNoChange(Element src1, Element src2, Piece piece) {
if (src1.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS) && src2.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS)) {
if (src1.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS) && src2.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_EQUALS)) {
piece.addStyle("opacity: 0.5");
}
return piece;
@ -3460,7 +3469,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
sdCache = new HashMap<String, ElementDefinition>();
sdMapCache.put(url, sdCache);
String webroot = sd.getUserString("webroot");
String webroot = sd.getUserString(UserDataNames.render_webroot);
for (ElementDefinition e : sd.getSnapshot().getElement()) {
context.getProfileUtilities().updateURLs(sd.getUrl(), webroot, e, false);
sdCache.put(e.getId(), e);
@ -3472,8 +3481,8 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
// Returns the ElementDefinition for the 'parent' of the current element
private ElementDefinition getBaseElement(ElementDefinition e, String url) {
if (e.hasUserData(ProfileUtilities.UD_DERIVATION_POINTER)) {
return getElementById(url, e.getUserString(ProfileUtilities.UD_DERIVATION_POINTER));
if (e.hasUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER)) {
return getElementById(url, e.getUserString(UserDataNames.SNAPSHOT_DERIVATION_POINTER));
}
return null;
}
@ -3550,13 +3559,13 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
} else {
// we delete it from the other
@SuppressWarnings("unchecked")
List<String> other = (List<String>) allAnchors.get(s).getUserData("dict.generator.anchors");
List<String> other = (List<String>) allAnchors.get(s).getUserData(UserDataNames.render_dict_generator_anchors);
other.remove(s);
allAnchors.put(s, ed);
}
}
list.removeAll(removed);
ed.setUserData("dict.generator.anchors", list);
ed.setUserData(UserDataNames.render_dict_generator_anchors, list);
}
private void addToStack(List<ElementDefinition> stack, ElementDefinition ec) {
@ -3571,7 +3580,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
}
private List<String> makeAnchors(ElementDefinition ed, String anchorPrefix) {
List<String> list = (List<String>) ed.getUserData("dict.generator.anchors");
List<String> list = (List<String>) ed.getUserData(UserDataNames.render_dict_generator_anchors);
List<String> res = new ArrayList<>();
res.add(anchorPrefix + ed.getId());
for (String s : list) {
@ -3908,7 +3917,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
// gc.addStyledText("Standards Status = "+ss.toDisplay(), ss.getAbbrev(), "black", ss.getColor(), baseSpecUrl()+, true);
StructureDefinition sdb = context.getContext().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
if (sdb != null) {
StandardsStatus base = determineStandardsStatus(sdb, (ElementDefinition) d.getUserData("derived.pointer"));
StandardsStatus base = determineStandardsStatus(sdb, (ElementDefinition) d.getUserData(UserDataNames.SNAPSHOT_DERIVATION_POINTER));
if (base != null) {
tableRow(tbl, context.formatPhrase(RenderingContext.STRUC_DEF_STAND_STAT), "versions.html#std-process", strikethrough, ss.toDisplay()+" (from "+base.toDisplay()+")");
} else {
@ -4501,11 +4510,11 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
if (!t.getAggregation().isEmpty() || (compare!=null && !compare.getAggregation().isEmpty())) {
for (Enumeration<AggregationMode> a :t.getAggregation()) {
a.setUserData("render.link", corePath + "codesystem-resource-aggregation-mode.html#content");
a.setUserData(UserDataNames.render_link, corePath + "codesystem-resource-aggregation-mode.html#content");
}
if (compare!=null) {
for (Enumeration<AggregationMode> a : compare.getAggregation()) {
a.setUserData("render.link", corePath + "codesystem-resource-aggregation-mode.html#content");
a.setUserData(UserDataNames.render_link, corePath + "codesystem-resource-aggregation-mode.html#content");
}
}
var xt = compareSimpleTypeLists(t.getAggregation(), compare == null ? null : compare.getAggregation(), mode);

View File

@ -25,6 +25,7 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CanonicalPair;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -149,9 +150,9 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
String ref = null;
boolean addHtml = true;
if (cs != null) {
ref = (String) cs.getUserData("external.url");
ref = (String) cs.getUserData(UserDataNames.render_external_link);
if (Utilities.noString(ref))
ref = (String) cs.getUserData("filename");
ref = (String) cs.getUserData(UserDataNames.render_filename);
else
addHtml = false;
if (Utilities.noString(ref)) {

View File

@ -55,6 +55,7 @@ import org.hl7.fhir.r5.terminologies.utilities.SnomedUtilities;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.LoincLinker;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
@ -159,7 +160,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
// String url = "";
// ValueSet vsr = context.getWorker().findTxResource(ValueSet.class, ((Reference) a.getTarget()).getReference());
// if (vsr != null)
// url = (String) vsr.getUserData("filename");
// url = (String) vsr.getUserData(UserDataNames.filename);
// mymaps.put(a, url);
// }
// Map<ConceptMap, String> mymaps = new HashMap<ConceptMap, String>();
@ -167,7 +168,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
// String url = "";
// ValueSet vsr = context.getWorker().fetchResource(ValueSet.class, ((Reference) a.getTarget()).getReference());
// if (vsr != null)
// url = (String) vsr.getUserData("filename");
// url = (String) vsr.getUserData(UserDataNames.filename);
// mymaps.put(a, url);
// }
// also, look in the contained resources for a concept map
@ -178,7 +179,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
// String url = "";
// ValueSet vsr = context.getWorker().findTxResource(ValueSet.class, ((Reference) cm.getTarget()).getReference());
// if (vsr != null)
// url = (String) vsr.getUserData("filename");
// url = (String) vsr.getUserData(UserDataNames.filename);
// mymaps.put(cm, url);
// }
// }
@ -753,7 +754,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
}
String ref = cs.getWebPath();
if (ref == null) {
ref = cs.getUserString("filename");
ref = cs.getUserString(UserDataNames.render_filename);
}
return ref == null ? null : ref.replace("\\", "/");
}

View File

@ -0,0 +1,247 @@
package org.hl7.fhir.r5.renderers;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules;
import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType;
import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.sql.Column;
import org.hl7.fhir.r5.utils.sql.ColumnKind;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Row;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.TableModel;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Title;
public class ViewDefinitionRenderer extends ResourceRenderer {
public ViewDefinitionRenderer(RenderingContext context) {
super(context);
}
@Override
public boolean renderingUsesValidation() {
return true;
}
@Override
public String buildSummary(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
return canonicalTitle(r);
}
@Override
public void buildNarrative(RenderingStatus status, XhtmlNode x, ResourceWrapper vd) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
renderResourceTechDetails(vd, x);
genSummaryTable(status, x, vd);
XhtmlNode p = x.para();
p.tx("This view acts on the "+vd.primitiveValue("resource")+" resource");
var vers = vd.children("fhirVersion");
for (int i = 0; i < vers.size(); i++) {
if (i == 0) {
p.tx(" for version"+(vers.size() == 1 ? "" : "s")+" ");
} else if (i == vers.size() - 1) {
p.tx(" and ");
} else {
p.tx(", ");
}
String ver = vers.get(i).primitiveValue();
p.ah(VersionUtilities.getSpecUrl(ver)).tx(VersionUtilities.getNameForVersion(ver));
}
if (vd.has("resourceProfile")) {
p.tx(" using profile ?");
}
if (vd.has("name")) {
p.tx(" to produce a table named \"");
p.code().tx(vd.primitiveValue("name"));
p.tx("\"");
} else {
p.tx(" to produce a unnamed table");
}
if (vd.has("where")) {
List<ResourceWrapper> wheres = vd.children("where");
if (wheres.size() == 1) {
p.tx(" where ");
p.code().tx(wheres.get(0).primitiveValue("path"));
if (wheres.get(0).has("description")) {
p.tx(" ("+wheres.get(0).primitiveValue("description")+")");
}
p.tx(".");
} else {
p.tx(" where:");
XhtmlNode ul = x.ul();
for (ResourceWrapper w : wheres) {
XhtmlNode li = ul.li();
li.code().tx(wheres.get(0).primitiveValue("path"));
if (wheres.get(0).has("description")) {
li.tx(" ("+wheres.get(0).primitiveValue("description")+")");
}
}
}
} else {
p.tx(".");
}
if (vd.hasUserData(UserDataNames.db_columns)) {
x.para().tx("The table contains the following columns:");
List<Column> cols = (List<Column>) vd.getUserData(UserDataNames.db_columns);
boolean hasNotes = false;
for (Column col : cols) {
hasNotes = hasNotes || !Utilities.noString(col.getNotes());
}
XhtmlNode t2 = x.table("grid");
XhtmlNode tr = t2.tr();
tr.th().tx("Name");
tr.th().tx("Fhir Type");
tr.th().tx("SQL Type");
tr.th().tx("Collection");
if (hasNotes) {
tr.th().tx("Notes");
}
for (Column col : cols) {
tr = t2.tr();
tr.td().tx(col.getName());
tr.td().tx(col.getType());
tr.td().tx(col.getKind().name());
tr.td().tx(col.isColl() == null ? "" : col.isColl() ? "Y" : "N");
if (hasNotes) {
tr.td().tx(col.getNotes());
}
}
}
if (vd.has("constant")) {
x.para().tx("Constants:");
XhtmlNode t2 = x.table("grid");
XhtmlNode tr = t2.tr();
tr.th().tx("Name");
tr.th().tx("Value");
for (ResourceWrapper cnst : vd.children("constant")) {
tr = t2.tr();
tr.td().tx(cnst.primitiveValue("name"));
tr.td().tx(cnst.primitiveValue("value"));
}
}
// row 4: select tree
x.para().tx("Selection Rules:");
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context, context.getDestDir(), context.isInlineGraphics(), true, "");
TableModel model = gen.new TableModel("vd="+vd.getId(), context.getRules() == GenerationRules.IG_PUBLISHER);
model.setAlternating(true);
if (context.getRules() == GenerationRules.VALID_RESOURCE || context.isInlineGraphics()) {
model.setDocoImg(HierarchicalTableGenerator.help16AsData());
} else {
model.setDocoImg(Utilities.pathURL(context.getLink(KnownLinkType.SPEC), "help16.png"));
}
model.getTitles().add(gen.new Title(null, model.getDocoRef(), ("Item"), (context.formatPhrase(RenderingContext.QUEST_LINK)), null, 0));
model.getTitles().add(gen.new Title(null, model.getDocoRef(), ("Coll"), (context.formatPhrase(RenderingContext.QUEST_TEXTFOR)), null, 0));
model.getTitles().add(gen.new Title(null, model.getDocoRef(), ("Type"), (context.formatPhrase(RenderingContext.QUEST_TIMES)), null, 0));
model.getTitles().add(gen.new Title(null, model.getDocoRef(), ("Description"), (context.formatPhrase(RenderingContext.QUEST_TYPE_ITEM)), null, 0));
// first we add a root for the questionaire itself
Row row = addViewRoot(gen, model.getRows(), vd);
for (ResourceWrapper select : vd.children("select")) {
renderSelect(status, gen, row.getSubRows(), vd, select);
}
XhtmlNode xn = gen.generate(model, context.getLocalPrefix(), 1, null);
x.addChildNode(xn);
}
private void renderSelect(RenderingStatus status, HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper vd, ResourceWrapper select) {
Row r = gen.new Row();
rows.add(r);
r.setIcon("icon_vd_select.png", "Select");
Cell c1 = gen.new Cell(null, null, "Select", null, null);
r.getCells().add(c1);
r.getCells().add(gen.new Cell(null, null, null, null, null));
r.getCells().add(gen.new Cell(null, null, null, null, null));
Cell cell = gen.new Cell(null, null, null, null, null);
if (select.has("forEach")) {
addFHIRPath(cell.getPieces().get(0), "for each ", select.primitiveValue("forEach"), null);
} else if (select.has("forEachOrNull")) {
addFHIRPath(cell.getPieces().get(0), "for each ", select.primitiveValue("forEachOrNull"), ", or null");
} else {
}
r.getCells().add(cell);
for (ResourceWrapper column : select.children("column")) {
renderColumn(status, gen, r.getSubRows(), vd, select, column);
}
for (ResourceWrapper child : select.children("select")) {
renderSelect(status, gen, r.getSubRows(), vd, child);
}
}
private void renderColumn(RenderingStatus status, HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper vd, ResourceWrapper select, ResourceWrapper column) {
Row r = gen.new Row();
rows.add(r);
r.setIcon("icon_vd_col.png", "Column");
Cell c1 = gen.new Cell(null, null, column.primitiveValue("name"), null, null);
r.getCells().add(c1);
String coll = column.has("collection") ? "true".equals(column.primitiveValue("collection")) ? "Y" : "N" : "";
r.getCells().add(gen.new Cell(null, null, coll, null, null));
r.getCells().add(gen.new Cell(null, null, column.primitiveValue("type"), null, null));
Cell cell = gen.new Cell(null, null, null, null, null);
addFHIRPath(cell.getPieces().get(0), null, column.primitiveValue("path"), null);
if (column.has("description")) {
cell.addPiece(gen.new Piece("br"));
cell.addPiece(gen.new Piece(null, column.primitiveValue("description"), null));
}
for (ResourceWrapper tag : column.children("tag")) {
cell.addPiece(gen.new Piece("br"));
cell.addPiece(gen.new Piece(null, tag.primitiveValue("name")+"="+tag.primitiveValue("value"), null));
}
r.getCells().add(cell);
}
private void addFHIRPath(Piece p, String pfx, String expr, String sfx) {
XhtmlNode x = new XhtmlNode(NodeType.Element, "span").style("font-size: 11px");
p.addHtml(x);
if (pfx != null) {
x.tx(pfx);
}
x.code(expr);
if (sfx != null) {
x.tx(sfx);
}
}
private Row addViewRoot(HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper vd) throws IOException {
Row r = gen.new Row();
rows.add(r);
r.setIcon("icon_vd_view.png", context.formatPhrase(RenderingContext.QUEST_ROOT));
r.getCells().add(gen.new Cell(null, null, vd.primitiveValue("name"), null, null));
r.getCells().add(gen.new Cell(null, null, "", null, null));
r.getCells().add(gen.new Cell(null, null, vd.primitiveValue("resource"), null, null));
r.getCells().add(gen.new Cell(null, null, vd.primitiveValue("description"), null, null));
return r;
}
}

View File

@ -522,6 +522,8 @@ public abstract class ResourceWrapper {
public abstract boolean hasPrimitiveValue();
public abstract String primitiveValue();
public abstract boolean isResource();
public abstract boolean hasUserData(String name);
public abstract Object getUserData(String name);
}

View File

@ -270,5 +270,15 @@ public class ResourceWrapperModel extends ResourceWrapper {
return null;
}
@Override
public boolean hasUserData(String name) {
return model.hasUserData(name);
}
@Override
public Object getUserData(String name) {
return model.getUserData(name);
}
}

View File

@ -10,6 +10,7 @@ import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.Narrative;
import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
@ -143,7 +144,7 @@ public class ResourceWrapperNative extends ResourceWrapper {
public void setNarrative(XhtmlNode x, String status, boolean multiLangMode, Locale locale, boolean isPretty) {
if (element instanceof DomainResource) {
DomainResource r = (DomainResource) element;
r.getText().setUserData("renderer.generated", true);
r.getText().setUserData(UserDataNames.renderer_is_generated, true);
if (!r.hasText() || !r.getText().hasDiv()) {
r.setText(new Narrative());
r.getText().setStatusAsString(status);
@ -231,4 +232,14 @@ public class ResourceWrapperNative extends ResourceWrapper {
return null;
}
@Override
public boolean hasUserData(String name) {
return element.hasUserData(name);
}
@Override
public Object getUserData(String name) {
return element.getUserData(name);
}
}

View File

@ -67,6 +67,7 @@ import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.utils.CanonicalResourceUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.MarkDownProcessor;
import org.hl7.fhir.utilities.StandardsStatus;
@ -590,11 +591,11 @@ public class CodeSystemUtilities extends TerminologyUtilities {
if (ss == null || ss.isLowerThan(status))
ToolingExtensions.setStandardsStatus(cs, status, normativeVersion);
if (pckage != null) {
if (!cs.hasUserData("ballot.package"))
cs.setUserData("ballot.package", pckage);
else if (!pckage.equals(cs.getUserString("ballot.package")))
if (!"infrastructure".equals(cs.getUserString("ballot.package")))
System.out.println("Code System "+cs.getUrl()+": ownership clash "+pckage+" vs "+cs.getUserString("ballot.package"));
if (!cs.hasUserData(UserDataNames.kindling_ballot_package))
cs.setUserData(UserDataNames.kindling_ballot_package, pckage);
else if (!pckage.equals(cs.getUserString(UserDataNames.kindling_ballot_package)))
if (!"infrastructure".equals(cs.getUserString(UserDataNames.kindling_ballot_package)))
System.out.println("Code System "+cs.getUrl()+": ownership clash "+pckage+" vs "+cs.getUserString(UserDataNames.kindling_ballot_package));
}
if (status == StandardsStatus.NORMATIVE) {
cs.setExperimental(false);
@ -842,7 +843,7 @@ public class CodeSystemUtilities extends TerminologyUtilities {
for (CodeSystem sup : supplements) {
b.append(sup.getVersionedUrl());
}
ret.setUserData("supplements.installed", b.toString());
ret.setUserData(UserDataNames.tx_known_supplements, b.toString());
for (ConceptDefinitionComponent t : ret.getConcept()) {
mergeSupplements(ret, t, supplements);

View File

@ -67,6 +67,7 @@ import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.ConceptDefinitionCompon
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.ConceptStatus;
import org.hl7.fhir.r5.utils.CanonicalResourceUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
@ -167,7 +168,7 @@ public class ValueSetUtilities extends TerminologyUtilities {
}
public static void markStatus(ValueSet vs, String wg, StandardsStatus status, String pckage, String fmm, IWorkerContext context, String normativeVersion) throws FHIRException {
if (vs.hasUserData("external.url"))
if (vs.hasUserData(UserDataNames.render_external_link))
return;
if (wg != null) {
@ -181,11 +182,11 @@ public class ValueSetUtilities extends TerminologyUtilities {
if (ss == null || ss.isLowerThan(status))
ToolingExtensions.setStandardsStatus(vs, status, normativeVersion);
if (pckage != null) {
if (!vs.hasUserData("ballot.package"))
vs.setUserData("ballot.package", pckage);
else if (!pckage.equals(vs.getUserString("ballot.package")))
if (!"infrastructure".equals(vs.getUserString("ballot.package")))
System.out.println("Value Set "+vs.getUrl()+": ownership clash "+pckage+" vs "+vs.getUserString("ballot.package"));
if (!vs.hasUserData(UserDataNames.kindling_ballot_package))
vs.setUserData(UserDataNames.kindling_ballot_package, pckage);
else if (!pckage.equals(vs.getUserString(UserDataNames.kindling_ballot_package)))
if (!"infrastructure".equals(vs.getUserString(UserDataNames.kindling_ballot_package)))
System.out.println("Value Set "+vs.getUrl()+": ownership clash "+pckage+" vs "+vs.getUserString(UserDataNames.kindling_ballot_package));
}
if (status == StandardsStatus.NORMATIVE) {
vs.setExperimental(false);
@ -201,8 +202,8 @@ public class ValueSetUtilities extends TerminologyUtilities {
vs.setExperimental(true);
}
}
if (vs.hasUserData("cs"))
CodeSystemUtilities.markStatus((CodeSystem) vs.getUserData("cs"), wg, status, pckage, fmm, normativeVersion);
if (vs.hasUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM))
CodeSystemUtilities.markStatus((CodeSystem) vs.getUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM), wg, status, pckage, fmm, normativeVersion);
else if (status == StandardsStatus.NORMATIVE && context != null) {
for (ConceptSetComponent csc : vs.getCompose().getInclude()) {
if (csc.hasSystem()) {

View File

@ -31,6 +31,7 @@ import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedCodeSystem;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedValueSet;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
@ -241,8 +242,8 @@ public class TerminologyClientManager {
// no agreement? Then what we do depends
if (vs != null) {
if (vs.hasUserData("External.Link")) {
String el = vs.getUserString("External.Link");
if (vs.hasUserData(UserDataNames.render_external_link)) {
String el = vs.getUserString(UserDataNames.render_external_link);
if ("https://vsac.nlm.nih.gov".equals(el)) {
el = getMaster().getAddress();
}

View File

@ -125,6 +125,7 @@ import org.hl7.fhir.r5.terminologies.utilities.TerminologyOperationContext.Termi
import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass;
import org.hl7.fhir.r5.terminologies.utilities.ValueSetProcessBase;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.client.EFhirClientException;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
@ -1022,8 +1023,8 @@ public class ValueSetExpander extends ValueSetProcessBase {
if (ValueSetUtilities.isServerSide(inc.getSystem()) || (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT))) {
doServerIncludeCodes(inc, heirarchical, exp, imports, expParams, extensions, noInactive, valueSet.getExpansion().getProperty());
} else {
if (cs.hasUserData("supplements.installed")) {
for (String s : cs.getUserString("supplements.installed").split("\\,")) {
if (cs.hasUserData(UserDataNames.tx_known_supplements)) {
for (String s : cs.getUserString(UserDataNames.tx_known_supplements).split("\\,")) {
requiredSupplements.remove(s);
}
}
@ -1090,8 +1091,8 @@ public class ValueSetExpander extends ValueSetProcessBase {
UriType u = new UriType(cs.getUrl() + (cs.hasVersion() ? "|"+cs.getVersion() : ""));
if (!existsInParams(exp.getParameter(), "used-codesystem", u))
exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("used-codesystem").setValue(u));
if (cs.hasUserData("supplements.installed")) {
for (String s : cs.getUserString("supplements.installed").split("\\,")) {
if (cs.hasUserData(UserDataNames.tx_known_supplements)) {
for (String s : cs.getUserString(UserDataNames.tx_known_supplements).split("\\,")) {
u = new UriType(s);
if (!existsInParams(exp.getParameter(), "used-supplement", u)) {
exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("used-supplement").setValue(u));

View File

@ -18,6 +18,7 @@ import org.hl7.fhir.r5.model.UrlType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
@ -181,8 +182,8 @@ public class ValueSetProcessBase {
List<OperationOutcomeIssueComponent> iss = makeIssue(IssueSeverity.INFORMATION, IssueType.BUSINESSRULE, null, context.formatMessage(msg, resource.getVersionedUrl(), null, resource.fhirType()), OpIssueCode.StatusCheck, null);
// this is a testing hack - see TerminologyServiceTests
iss.get(0).setUserData("status-msg-name", "warning-"+id);
iss.get(0).setUserData("status-msg-value", new UriType(resource.getVersionedUrl()));
iss.get(0).setUserData(UserDataNames.tx_status_msg_name, "warning-"+id);
iss.get(0).setUserData(UserDataNames.tx_status_msg_value, new UriType(resource.getVersionedUrl()));
ToolingExtensions.setStringExtension(iss.get(0), ToolingExtensions.EXT_ISSUE_MSG_ID, msg);
return iss;

View File

@ -92,6 +92,7 @@ import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.terminologies.utilities.ValueSetProcessBase;
import org.hl7.fhir.r5.utils.OperationOutcomeUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier.ValidationContextResourceProxy;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
@ -240,8 +241,8 @@ public class ValueSetValidator extends ValueSetProcessBase {
if (!options.isMembershipOnly()) {
int i = 0;
for (Coding c : code.getCoding()) {
if (!c.hasSystem() && !c.hasUserData("val.sys.error")) {
c.setUserData("val.sys.error", true);
if (!c.hasSystem() && !c.hasUserData(UserDataNames.tx_val_sys_error)) {
c.setUserData(UserDataNames.tx_val_sys_error, true);
info.addIssue(makeIssue(IssueSeverity.WARNING, IssueType.INVALID, path+".coding["+i+"]", context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE), OpIssueCode.InvalidData, null));
} else {
VersionInfo vi = new VersionInfo(this);
@ -278,7 +279,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
}
}
} else {
c.setUserData("cs", cs);
c.setUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM, cs);
checkCanonical(info.getIssues(), path, cs, valueset);
res = validateCode(path+".coding["+i+"]", c, cs, vcc, info);
@ -361,7 +362,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
cd.setDisplay(lookupDisplay(foundCoding));
res.setDefinition(cd);
res.setSystem(foundCoding.getSystem());
res.setVersion(foundCoding.hasVersion() ? foundCoding.getVersion() : foundCoding.hasUserData("cs") ? ((CodeSystem) foundCoding.getUserData("cs")).getVersion() : null);
res.setVersion(foundCoding.hasVersion() ? foundCoding.getVersion() : foundCoding.hasUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM) ? ((CodeSystem) foundCoding.getUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM)).getVersion() : null);
res.setDisplay(cd.getDisplay());
}
if (info.getErr() != null) {
@ -463,8 +464,8 @@ public class ValueSetValidator extends ValueSetProcessBase {
private String getVersion(Coding c) {
if (c.hasVersion()) {
return c.getVersion();
} else if (c.hasUserData("cs")) {
return ((CodeSystem) c.getUserData("cs")).getVersion();
} else if (c.hasUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM)) {
return ((CodeSystem) c.getUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM)).getVersion();
} else {
return null;
}
@ -562,8 +563,8 @@ public class ValueSetValidator extends ValueSetProcessBase {
}
if (!code.hasSystem()) {
res = new ValidationResult(IssueSeverity.WARNING, context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE), null);
if (!code.hasUserData("val.sys.error")) {
code.setUserData("val.sys.error", true);
if (!code.hasUserData(UserDataNames.tx_val_sys_error)) {
code.setUserData(UserDataNames.tx_val_sys_error, true);
res.getIssues().addAll(makeIssue(IssueSeverity.WARNING, IssueType.INVALID, path, context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE), OpIssueCode.InvalidData, null));
}
} else {
@ -831,7 +832,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
if ("urn:ietf:rfc:3986".equals(system)) {
CodeSystem cs = new CodeSystem();
cs.setUrl(system);
cs.setUserData("tx.cs.special", new URICodeSystem());
cs.setUserData(UserDataNames.tx_cs_special, new URICodeSystem());
cs.setContent(CodeSystemContentMode.COMPLETE);
return cs;
}
@ -886,7 +887,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
}
private ValidationResult validateCode(String path, Coding code, CodeSystem cs, CodeableConcept vcc, ValidationProcessInfo info) {
ConceptDefinitionComponent cc = cs.hasUserData("tx.cs.special") ? ((SpecialCodeSystem) cs.getUserData("tx.cs.special")).findConcept(code) : findCodeInConcept(cs.getConcept(), code.getCode(), cs.getCaseSensitive(), allAltCodes);
ConceptDefinitionComponent cc = cs.hasUserData(UserDataNames.tx_cs_special) ? ((SpecialCodeSystem) cs.getUserData(UserDataNames.tx_cs_special)).findConcept(code) : findCodeInConcept(cs.getConcept(), code.getCode(), cs.getCaseSensitive(), allAltCodes);
if (cc == null) {
cc = findSpecialConcept(code, cs);
}
@ -1592,8 +1593,8 @@ public class ValueSetValidator extends ValueSetProcessBase {
public boolean validateCodeInConceptList(String code, CodeSystem def, List<ConceptDefinitionComponent> list, AlternateCodesProcessingRules altCodeRules) {
opContext.deadCheck("validateCodeInConceptList");
if (def.hasUserData("tx.cs.special")) {
return ((SpecialCodeSystem) def.getUserData("tx.cs.special")).findConcept(new Coding().setCode(code)) != null;
if (def.hasUserData(UserDataNames.tx_cs_special)) {
return ((SpecialCodeSystem) def.getUserData(UserDataNames.tx_cs_special)).findConcept(new Coding().setCode(code)) != null;
} else if (def.getCaseSensitive()) {
for (ConceptDefinitionComponent cc : list) {
if (cc.getCode().equals(code)) {

View File

@ -75,7 +75,7 @@ import org.hl7.fhir.utilities.npm.ToolsVersion;
public class NPMPackageGenerator {
public enum Category {
RESOURCE, EXAMPLE, OPENAPI, SCHEMATRON, RDF, OTHER, TOOL, TEMPLATE, JEKYLL, TEST;
RESOURCE, EXAMPLE, OPENAPI, SCHEMATRON, RDF, OTHER, TOOL, TEMPLATE, JEKYLL, TEST, CUSTOM;
private String getDirectory() {
switch (this) {
@ -89,6 +89,7 @@ public class NPMPackageGenerator {
case JEKYLL: return "package/jekyll/";
case TEST: return "package/tests/";
case TOOL: return "package/bin/";
case CUSTOM: return "package/custom/";
}
return "/";
}

View File

@ -52,7 +52,7 @@ public class OperationOutcomeUtilities {
public static OperationOutcomeIssueComponent convertToIssue(ValidationMessage message, OperationOutcome op) {
OperationOutcomeIssueComponent issue = new OperationOutcome.OperationOutcomeIssueComponent();
issue.setUserData("source.vm", message);
issue.setUserData(UserDataNames.validator_source_vm, message);
issue.setCode(convert(message.getType()));
if (message.getLocation() != null) {
@ -76,7 +76,7 @@ public class OperationOutcomeUtilities {
if (message.getMessageId() != null) {
issue.getExtension().add(ToolingExtensions.makeIssueMessageId(message.getMessageId()));
}
issue.setUserData("source.msg", message);
issue.setUserData(UserDataNames.validator_source_msg, message);
return issue;
}
@ -152,7 +152,7 @@ public class OperationOutcomeUtilities {
public static OperationOutcomeIssueComponent convertToIssueSimple(ValidationMessage message, OperationOutcome op) {
OperationOutcomeIssueComponent issue = new OperationOutcome.OperationOutcomeIssueComponent();
issue.setUserData("source.vm", message);
issue.setUserData(UserDataNames.validator_source_vm, message);
issue.setCode(convert(message.getType()));
if (message.getLocation() != null) {

View File

@ -97,12 +97,14 @@ public class PackageHackerR5 {
StructureDefinition sd = (StructureDefinition) r.getResource();
for (ElementDefinition ed : sd.getSnapshot().getElement()) {
if (ed.getType().removeIf(tr -> Utilities.existsInList(tr.getCode(), "integer64", "CodeableReference", "RatioRange", "Availability", "ExtendedContactDetail"))) {
sd.setUserData("fixed-by-loader", true);
// sd.setUserData(UserDataNames.fixed_by_loader, true);
// don't need to track this (for now)
}
}
for (ElementDefinition ed : sd.getDifferential().getElement()) {
if (ed.getType().removeIf(tr -> Utilities.existsInList(tr.getCode(), "integer64", "CodeableReference", "RatioRange", "Availability", "ExtendedContactDetail"))) {
sd.setUserData("fixed-by-loader", true);
// sd.setUserData(UserDataNames.fixed_by_loader, true);
// don't need to track this (for now)
}
}
}

View File

@ -249,7 +249,7 @@ public class QuestionnaireBuilder {
QuestionnaireResponse.QuestionnaireResponseItemComponent item = new QuestionnaireResponse.QuestionnaireResponseItemComponent();
response.addItem(item);
item.setLinkId("meta");
item.setUserData("object", resource);
item.setUserData(UserDataNames.questionnaire_object, resource);
}
}
@ -353,12 +353,12 @@ public class QuestionnaireBuilder {
private void processExisting(String path, List<QuestionnaireResponse.QuestionnaireResponseItemComponent> answerGroups, QuestionnaireItemComponent item, List<QuestionnaireResponse.QuestionnaireResponseItemComponent> nResponse) throws FHIRException {
// processing existing data
for (QuestionnaireResponse.QuestionnaireResponseItemComponent ag : answerGroups) {
List<Base> children = ((Element) ag.getUserData("object")).listChildrenByName(tail(path));
List<Base> children = ((Element) ag.getUserData(UserDataNames.questionnaire_object)).listChildrenByName(tail(path));
for (Base child : children) {
if (child != null) {
QuestionnaireResponse.QuestionnaireResponseItemComponent ans = ag.addItem();
ag.setLinkId(item.getLinkId());
ans.setUserData("object", child);
ans.setUserData(UserDataNames.questionnaire_object, child);
nResponse.add(ans);
}
}
@ -393,13 +393,13 @@ public class QuestionnaireBuilder {
for (TypeRefComponent t : types) {
Questionnaire.QuestionnaireItemComponent sub = q.addItem();
sub.setType(QuestionnaireItemType.GROUP);
sub.setLinkId(element.getPath()+"._"+t.getUserData("text"));
sub.setText((String) t.getUserData("text"));
sub.setLinkId(element.getPath()+"._"+t.getUserData(UserDataNames.questionnaire_text));
sub.setText((String) t.getUserData(UserDataNames.questionnaire_text));
// always optional, never repeats
List<QuestionnaireResponse.QuestionnaireResponseItemComponent> selected = new ArrayList<QuestionnaireResponse.QuestionnaireResponseItemComponent>();
selectTypes(profile, sub, t, answerGroups, selected);
processDataType(profile, sub, element, element.getPath()+"._"+t.getUserData("text"), t, selected, parents);
processDataType(profile, sub, element, element.getPath()+"._"+t.getUserData(UserDataNames.questionnaire_text), t, selected, parents);
}
} else
// now we have to build the question panel for each different data type
@ -483,7 +483,7 @@ public class QuestionnaireBuilder {
List<QuestionnaireResponse.QuestionnaireResponseItemComponent> temp = new ArrayList<QuestionnaireResponse.QuestionnaireResponseItemComponent>();
for (QuestionnaireResponse.QuestionnaireResponseItemComponent g : source)
if (instanceOf(t, (Element) g.getUserData("object")))
if (instanceOf(t, (Element) g.getUserData(UserDataNames.questionnaire_object)))
temp.add(g);
for (QuestionnaireResponse.QuestionnaireResponseItemComponent g : temp)
source.remove(g);
@ -526,7 +526,7 @@ public class QuestionnaireBuilder {
dest.add(subg);
subg.setLinkId(sub.getLinkId());
subg.setText(sub.getText());
subg.setUserData("object", g.getUserData("object"));
subg.setUserData(UserDataNames.questionnaire_object, g.getUserData(UserDataNames.questionnaire_object));
}
}
@ -590,7 +590,7 @@ public class QuestionnaireBuilder {
List<Base> children = new ArrayList<Base>();
QuestionnaireResponse.QuestionnaireResponseItemComponent aq = null;
Element obj = (Element) ag.getUserData("object");
Element obj = (Element) ag.getUserData(UserDataNames.questionnaire_object);
if (isPrimitive((TypeRefComponent) obj))
children.add(obj);
else if (obj instanceof Enumeration) {

View File

@ -0,0 +1,140 @@
package org.hl7.fhir.r5.utils;
// other than render_src_package, all these are intended to be made consistent in format, using
// the standard format scope-name-name where scope is one of
// lib - core library (most of them)
// validator - validator CLI or web functionality
// pub - IG publisher functionality
// kindling - kindling related functionality
public class UserDataNames {
public static final String loader_urls_patched = "old.load.mode";
public static final String loader_custom_resource = "loader-custom-resource";
public static final String SNAPSHOT_BASE_MODEL = "base.model";
public static final String SNAPSHOT_BASE_PATH = "base.path";
public static final String SNAPSHOT_DERIVATION_EQUALS = "derivation.equals";
public static final String SNAPSHOT_DERIVATION_POINTER = "derived.pointer";
public static final String SNAPSHOT_IS_DERIVED = "derived.fact";
public static final String SNAPSHOT_GENERATED_IN_SNAPSHOT = "profileutilities.snapshot.processed";
public static final String SNAPSHOT_GENERATING = "profileutils.snapshot.generating";
public static final String SNAPSHOT_GENERATED = "profileutils.snapshot.generated";
public static final String SNAPSHOT_GENERATED_MESSAGES = "profileutils.snapshot.generated.messages";
public static final String SNAPSHOT_ERRORS = "profileutils.snapshot.errors";
public static final String SNAPSHOT_auto_added_slicing = "auto-added-slicing";
public static final String SNAPSHOT_messages = "profileutils.snapshot.messages";
public static final String SNAPSHOT_slice_name = "slice-name";
public static final String SNAPSHOT_SORT_ed_index = "ed.index";
public static final String SNAPSHOT_diff_source = "diff-source";
public static final String SNAPSHOT_regeneration_tracker = "hack.regnerated";
public static final String LANGUTILS_ORPHAN = "translations.orphans";
public static final String LANGUTILS_SOURCE_SUPPLEMENT = "translations.supplemented";
public static final String LANGUTILS_SOURCE_TRANSLATIONS = "translations.source-list";
public static final String rendering_xml_decorations = "fhir_decorations";
public static final String render_extension_slice = "slice";
public static final String render_opaque = "render.opaque";
public static final String render_tx_value = "tx.value";
public static final String render_tx_pattern = "tx.pattern";
public static final String render_link = "render.link";
public static final String render_external_link = "External.Link";
public static final String render_dict_generator_anchors = "dict.generator.anchors";
public static final String render_presentation = "presentation";
public static final String render_src_package = "package"; // <--- this value is reused by HAPI and can't change without consultation
public static final String renderer_is_generated = "renderer.generated";
public static final String keyview_elementSupported = "elementSupported";
public static final String keyview_hasFixed = "hasFixed";
public static final String keyview_usesMustSupport = "usesMustSupport";
public static final String LAYOUT_SvgLeft = "SvgLeft";
public static final String LAYOUT_SvgTop = "SvgTop";
public static final String LAYOUT_SvgWidth = "SvgWidth";
public static final String LAYOUT_UmlBreak = "UmlBreak";
public static final String LAYOUT_UmlDir = "UmlDir";
public static final String questionnaire_object = "object";
public static final String questionnaire_text = "text";
public static final String mappings_inherited = "private-marked-as-derived";
@Deprecated
public static final String deprecated_committee = "committee";
@Deprecated
public static final String render_filename = "filename";
public static final String render_webroot = "webroot";
public static final String comparison_match = "match";
public static final String COMP_VERSION_ANNOTATION = "version-annotation";
public static final String COMP_CONTEXT = "ctxt"; //!
public static final String tx_status_msg_name = "status-msg-name";
public static final String tx_status_msg_value = "status-msg-value";
public static final String tx_val_sys_error = "val.sys.error";
public static final String tx_cs_special = "tx.cs.special";
public static final String TX_REQUEST = "source";
public static final String TX_ASSOCIATED_CODESYSTEM = "cs";
public static final String tx_cs_version_notes = "cs.version.notes";
public static final String tx_known_supplements = "supplements.installed";
public static final String validator_bundle_resolution = "validator.bundle.resolution";
public static final String validator_bundle_resolved = "validator.bundle.resolved";
public static final String validator_expression_cache = "validator.expression.cache";
public static final String validator_slice_expression_cache = "slice.expression.cache";
public static final String validator_entry_map = "validator.entrymap";
public static final String validator_entry_map_reverse = "validator.entrymapR";
public static final String validation_bundle_error = "bundle.error.noted";
public static final String map_profile = "profile";
public static final String map_validated = "structuremap.validated";
public static final String map_parameters = "structuremap.parameters";
public static final String map_source = "element.source";
public static final String MAP_slice_name = "map-slice-name";
public static final String Storage_key = "Storage.key";
public static final String db_key = "db.key";
public static final String db_columns = "columns";
public static final String db_column = "column";
public static final String db_forEach = "forEach";
public static final String db_forEachOrNull = "forEachOrNull";
public static final String db_path = "path";
public static final String db_name = "name";
public static final String db_value = "value";
public static final String xver_rows = "rows";
public static final String xver_links = "links";
public static final String xver_sed = "sed";
public static final String xver_desc = "desc";
public static final String xver_cm_used = "cm.used";
public static final String xver_sliceName = "sliceName";
public static final String xver_delete = "delete";
public static final String xver_abstract = "abstract";
public static final String xver_expression = "expression";
public static final String java_code = "java.code";
public static final String validator_source_msg = "source.msg";
public static final String validator_source_vm = "source.vm";
public static final String PUB_CS_CONVERTED = "conv-vs";
public static final String pub_xref_used = "xref.used";
public static final String pub_xref_sources = "xref.sources";
public static final String pub_resource_config = "config";
public static final String pub_excel_inv_context = "context";
public static final String pub_excel_sheet_id = "id";
public static final String pub_element = "element";
public static final String pub_loaded_resource = "loaded.resource";
public static final String pub_source_filename = "source.filename";
public static final String pub_imposes_compare_id = "imposes.compare.id";
public static final String pub_analysis = "analysis";
public static final String pub_logical = "logical";
public static final String pub_context_file = "igpub.context.file";
public static final String pub_context_resource = "igpub.context.resource";
public static final String pub_no_load_deps = "no-load-deps";
public static final String kindling_ballot_package = "ballot.package";
}

View File

@ -6,14 +6,15 @@ public class Column {
private int length;
private String type;
private ColumnKind kind;
private boolean isColl;
private Boolean isColl;
private boolean duplicateReported;
private String notes;
protected Column() {
super();
}
protected Column(String name, boolean isColl, String type, ColumnKind kind) {
public Column(String name, Boolean isColl, String type, ColumnKind kind) {
super();
this.name = name;
this.isColl = isColl;
@ -51,11 +52,11 @@ public class Column {
this.type = type;
}
public boolean isColl() {
public Boolean isColl() {
return isColl;
}
public void setColl(boolean isColl) {
public void setColl(Boolean isColl) {
this.isColl = isColl;
}
@ -94,6 +95,18 @@ public class Column {
return "Column [name=" + name + ", length=" + length + ", type=" + type + ", kind=" + kind + ", isColl=" + isColl
+ "]";
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public void addNote(String note) {
this.notes = notes == null ? note : notes+"; "+note;
}
}

View File

@ -8,6 +8,7 @@ import org.apache.commons.codec.binary.Base64;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.fhirpath.ExpressionNode;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r5.fhirpath.TypeDetails;
@ -23,6 +24,7 @@ import org.hl7.fhir.r5.model.IntegerType;
import org.hl7.fhir.r5.model.Property;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.json.model.JsonObject;
import org.hl7.fhir.utilities.validation.ValidationMessage;
@ -150,7 +152,7 @@ public class Runner implements IEvaluationContext {
validator.dump();
validator.check();
resourceName = validator.getResourceName();
wc.store = storage.createStore(wc.vd.asString("name"), (List<Column>) wc.vd.getUserData("columns"));
wc.store = storage.createStore(wc.vd.asString("name"), (List<Column>) wc.vd.getUserData(UserDataNames.db_columns));
return wc;
}
@ -200,7 +202,7 @@ public class Runner implements IEvaluationContext {
focus.addAll(executeForEachOrNull(vd, select, b));
if (focus.isEmpty()) {
List<Column> columns = (List<Column>) select.getUserData("columns");
List<Column> columns = (List<Column>) select.getUserData(UserDataNames.db_columns);
for (List<Cell> row : rows) {
for (Column c : columns) {
Cell cell = cell(row, c.getName());
@ -272,26 +274,26 @@ public class Runner implements IEvaluationContext {
}
private List<Base> executeForEach(JsonObject vd, JsonObject focus, Base b) {
ExpressionNode n = (ExpressionNode) focus.getUserData("forEach");
ExpressionNode n = (ExpressionNode) focus.getUserData(UserDataNames.db_forEach);
List<Base> result = new ArrayList<>();
result.addAll(fpe.evaluate(vd, b, n));
return result;
}
private List<Base> executeForEachOrNull(JsonObject vd, JsonObject focus, Base b) {
ExpressionNode n = (ExpressionNode) focus.getUserData("forEachOrNull");
ExpressionNode n = (ExpressionNode) focus.getUserData(UserDataNames.db_forEachOrNull);
List<Base> result = new ArrayList<>();
result.addAll(fpe.evaluate(vd, b, n));
return result;
}
private void executeColumn(JsonObject vd, JsonObject column, Base b, List<List<Cell>> rows) {
ExpressionNode n = (ExpressionNode) column.getUserData("path");
ExpressionNode n = (ExpressionNode) column.getUserData(UserDataNames.db_path);
List<Base> bl2 = new ArrayList<>();
if (b != null) {
bl2.addAll(fpe.evaluate(vd, b, n));
}
Column col = (Column) column.getUserData("column");
Column col = (Column) column.getUserData(UserDataNames.db_column);
if (col == null) {
System.out.println("Error");
} else {
@ -416,7 +418,7 @@ public class Runner implements IEvaluationContext {
JsonObject vd = (JsonObject) appContext;
JsonObject constant = findConstant(vd, name);
if (constant != null) {
Base b = (Base) constant.getUserData("value");
Base b = (Base) constant.getUserData(UserDataNames.db_value);
if (b != null) {
list.add(b);
}
@ -428,12 +430,23 @@ public class Runner implements IEvaluationContext {
@Override
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
if (explicitConstant) {
JsonObject vd = (JsonObject) appContext;
JsonObject constant = findConstant(vd, name.substring(1));
if (constant != null) {
Base b = (Base) constant.getUserData("value");
if (b != null) {
return new TypeDetails(CollectionStatus.SINGLETON, b.fhirType());
if (appContext instanceof JsonObject) {
JsonObject vd = (JsonObject) appContext;
JsonObject constant = findConstant(vd, name.substring(1));
if (constant != null) {
Base b = (Base) constant.getUserData(UserDataNames.db_value);
if (b != null) {
return new TypeDetails(CollectionStatus.SINGLETON, b.fhirType());
}
}
} else if (appContext instanceof Element) {
Element vd = (Element) appContext;
Element constant = findConstant(vd, name.substring(1));
if (constant != null) {
Element v = constant.getNamedChild("value");
if (v != null) {
return new TypeDetails(CollectionStatus.SINGLETON, v.fhirType());
}
}
}
}
@ -448,6 +461,16 @@ public class Runner implements IEvaluationContext {
}
return null;
}
private Element findConstant(Element vd, String name) {
for (Element o : vd.getChildren("constant")) {
if (name.equals(o.getNamedChildValue("name"))) {
return o;
}
}
return null;
}
@Override
public boolean log(String argument, List<Base> focus) {
throw new Error("Not implemented yet: log");
@ -483,15 +506,15 @@ public class Runner implements IEvaluationContext {
List<Base> base = new ArrayList<Base>();
if (focus.size() == 1) {
Base res = focus.get(0);
if (!res.hasUserData("Storage.key")) {
if (!res.hasUserData(UserDataNames.Storage_key)) {
String key = storage.getKeyForSourceResource(res);
if (key == null) {
throw new FHIRException("Unidentified resource: "+res.fhirType()+"/"+res.getIdBase());
} else {
res.setUserData("Storage.key", key);
res.setUserData(UserDataNames.Storage_key, key);
}
}
base.add(new StringType(res.getUserString("Storage.key")));
base.add(new StringType(res.getUserString(UserDataNames.Storage_key)));
}
return base;
}
@ -518,15 +541,15 @@ public class Runner implements IEvaluationContext {
if (ref != null) {
Base target = provider.resolveReference(rootResource, ref, rt);
if (target != null) {
if (!res.hasUserData("Storage.key")) {
if (!res.hasUserData(UserDataNames.Storage_key)) {
String key = storage.getKeyForTargetResource(target);
if (key == null) {
throw new FHIRException("Unidentified resource: "+res.fhirType()+"/"+res.getIdBase());
} else {
res.setUserData("Storage.key", key);
res.setUserData(UserDataNames.Storage_key, key);
}
}
base.add(new StringType(res.getUserString("Storage.key")));
base.add(new StringType(res.getUserString(UserDataNames.Storage_key)));
}
}
}

View File

@ -34,6 +34,7 @@ import org.hl7.fhir.r5.model.UnsignedIntType;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.UrlType;
import org.hl7.fhir.r5.model.UuidType;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.sql.Validator.TrueFalseOrUnknown;
import org.hl7.fhir.r5.fhirpath.ExpressionNode.CollectionStatus;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IssueMessage;
@ -50,6 +51,8 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
// see also org.hl7.fhir.validation.instance.type.ViewDefinitionValidator
public class Validator {
public enum TrueFalseOrUnknown {
@ -105,7 +108,7 @@ public class Validator {
}
List<Column> columns = new ArrayList<>();
viewDefinition.setUserData("columns", columns);
viewDefinition.setUserData(UserDataNames.db_columns, columns);
JsonElement resourceNameJ = viewDefinition.get("resource");
if (resourceNameJ == null) {
@ -149,7 +152,7 @@ public class Validator {
private List<Column> checkSelect(JsonObject vd, String path, JsonObject select, TypeDetails t) {
List<Column> columns = new ArrayList<>();
select.setUserData("columns", columns);
select.setUserData(UserDataNames.db_columns, columns);
checkProperties(select, path, "column", "select", "forEach", "forEachOrNull", "unionAll");
if (select.has("forEach")) {
@ -246,7 +249,7 @@ public class Validator {
error(path+".unionAll["+i+"]", ((JsonArray) a).get(ic), "unionAll["+i+"] column definitions do not match: "+diff, IssueType.INVALID);
}
}
a.setUserData("colunms", columns);
a.setUserData(UserDataNames.db_columns, columns);
return columns;
}
}
@ -287,7 +290,7 @@ public class Validator {
ExpressionNode node = null;
try {
node = fpe.parse(expr);
column.setUserData("path", node);
column.setUserData(UserDataNames.db_path, node);
td = fpe.checkOnTypes(vd, resourceName, t, node, warnings);
} catch (Exception e) {
error(path, expression, e.getMessage(), IssueType.INVALID);
@ -323,7 +326,7 @@ public class Validator {
}
// ok, name is sorted!
if (columnName != null) {
column.setUserData("name", columnName);
column.setUserData(UserDataNames.db_name, columnName);
boolean isColl = false;
if (column.has("collection")) {
JsonElement collectionJ = column.get("collection");
@ -396,7 +399,7 @@ public class Validator {
}
if (ok) {
Column col = new Column(columnName, isColl, type, kindForType(type));
column.setUserData("column", col);
column.setUserData(UserDataNames.db_column, col);
return col;
}
}
@ -429,7 +432,7 @@ public class Validator {
}
private boolean isSimpleType(String type) {
return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time", "canonical");
return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time", "canonical", "uri", "url");
}
private String simpleType(String type) {
@ -469,7 +472,7 @@ public class Validator {
TypeDetails td = null;
try {
ExpressionNode n = fpe.parse(expr);
focus.setUserData("forEach", n);
focus.setUserData(UserDataNames.db_forEach, n);
td = fpe.checkOnTypes(vd, resourceName, t, n, warnings);
} catch (Exception e) {
error(path, expression, e.getMessage(), IssueType.INVALID);
@ -494,7 +497,7 @@ public class Validator {
TypeDetails td = null;
try {
ExpressionNode n = fpe.parse(expr);
focus.setUserData("forEachOrNull", n);
focus.setUserData(UserDataNames.db_forEachOrNull, n);
td = fpe.checkOnTypes(vd, resourceName, t, n, warnings);
} catch (Exception e) {
error(path, expression, e.getMessage(), IssueType.INVALID);
@ -570,7 +573,7 @@ public class Validator {
error(path+"."+name, j, name+" must be a string", IssueType.INVALID);
} else {
value.setValueAsString(j.asString());
constant.setUserData("value", value);
constant.setUserData(UserDataNames.db_value, value);
}
}
@ -580,7 +583,7 @@ public class Validator {
error(path+"."+name, j, name+" must be a boolean", IssueType.INVALID);
} else {
value.setValueAsString(j.asString());
constant.setUserData("value", value);
constant.setUserData(UserDataNames.db_value, value);
}
}
@ -590,7 +593,7 @@ public class Validator {
error(path+"."+name, j, name+" must be a number", IssueType.INVALID);
} else {
value.setValueAsString(j.asString());
constant.setUserData("value", value);
constant.setUserData(UserDataNames.db_value, value);
}
}
@ -607,7 +610,7 @@ public class Validator {
TypeDetails td = null;
try {
ExpressionNode n = fpe.parse(expr);
where.setUserData("path", n);
where.setUserData(UserDataNames.db_path, n);
td = fpe.checkOnTypes(vd, resourceName, types, n, warnings);
} catch (Exception e) {
error(path, where.get("path"), e.getMessage(), IssueType.INVALID);

View File

@ -70,6 +70,7 @@ import org.hl7.fhir.r5.renderers.TerminologyRenderer;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.Utilities;
@ -1793,8 +1794,8 @@ public class StructureMapUtilities {
if (services != null)
res = services.createResource(context.getAppInfo(), res, root);
}
if (tgt.hasUserData("profile"))
res.setUserData("profile", tgt.getUserData("profile"));
if (tgt.hasUserData(UserDataNames.map_profile))
res.setUserData(UserDataNames.map_profile, tgt.getUserData(UserDataNames.map_profile));
return res;
case COPY:
return getParam(vars, tgt.getParameter().get(0));
@ -2468,7 +2469,7 @@ public class StructureMapUtilities {
StructureDefinition sd = var.getProperty().getProfileProperty().getStructure();
ElementDefinition ednew = sd.getDifferential().addElement();
ednew.setPath(var.getProperty().getProfileProperty().getDefinition().getPath() + "." + pc.getName());
ednew.setUserData("slice-name", sliceName);
ednew.setUserData(UserDataNames.MAP_slice_name, sliceName); // todo.. why do this?
ednew.setFixed(fixed);
for (ProfiledType pt : type.getProfiledTypes()) {
if (pt.hasBindings())
@ -2620,7 +2621,7 @@ public class StructureMapUtilities {
profile.setBaseDefinition(prop.getBaseProperty().getStructure().getUrl());
profile.setName("Profile for " + profile.getType() + " for " + sliceName);
profile.setUrl(map.getUrl().replace("StructureMap", "StructureDefinition") + "-" + profile.getType() + suffix);
ctxt.setUserData("profile", profile.getUrl()); // then we can easily assign this profile url for validation later when we actually transform
ctxt.setUserData(UserDataNames.map_profile, profile.getUrl()); // then we can easily assign this profile url for validation later when we actually transform
profile.setId(map.getId() + "-" + profile.getType() + suffix);
profile.setStatus(map.getStatus());
profile.setExperimental(map.getExperimental());

View File

@ -0,0 +1,35 @@
package org.hl7.fhir.r5.utils.validation;
import java.util.HashMap;
import java.util.Map;
import org.hl7.fhir.utilities.Utilities;
/**
* Used by the validation infrastructure to cache internal infrastructure that
* will be cast away when the session is closed by the application
*/
public class ValidatorSession {
public static final String VIEW_DEFINITION_CONTEXT = "VIEW_DEFINITION_CONTEXT";
private Map<String, Object> objects = new HashMap<>();
protected String sessionId;
public ValidatorSession() {
super();
sessionId = Utilities.makeUuidLC();
}
public String getSessionId() {
return sessionId;
}
public Map<String, Object> getObjects() {
return objects;
}
public void close() {
objects.clear();
}
}

View File

@ -1126,4 +1126,20 @@ public class I18nConstants {
public static final String SD_PATH_SLICING_DEPRECATED = "SD_PATH_SLICING_DEPRECATED";
public static final String SD_PATH_NOT_VALID = "SD_PATH_NOT_VALID";
public static final String SD_PATH_ERROR = "SD_PATH_ERROR";
public static final String VIEWDEFINITION_SHOULD_HAVE_NAME = "VIEWDEFINITION_SHOULD_HAVE_NAME";
public static final String VIEWDEFINITION_NAME_INVALID = "VIEWDEFINITION_NAME_INVALID";
public static final String VIEWDEFINITION_PATH_ERROR = "VIEWDEFINITION_PATH_ERROR";
public static final String VIEWDEFINITION_PATH_WRONG_RETURN = "VIEWDEFINITION_PATH_WRONG_RETURN";
public static final String VIEWDEFINITION_PATH_WARNING = "VIEWDEFINITION_PATH_WARNING";
public static final String VIEWDEFINITION_UNKNOWN_RESOURCE = "VIEWDEFINITION_UNKNOWN_RESOURCE";
public static final String VIEWDEFINITION_DUPL_COL_NAME = "VIEWDEFINITION_DUPL_COL_NAME";
public static final String VIEWDEFINITION_NAME_REQUIRED = "VIEWDEFINITION_NAME_REQUIRED";
public static final String VIEWDEFINITION_NAME_REQUIRED_HINT = "VIEWDEFINITION_NAME_REQUIRED_HINT";
public static final String VIEWDEFINITION_COLLECTION_NOT_NEEDED = "VIEWDEFINITION_COLLECTION_NOT_NEEDED";
public static final String VIEWDEFINITION_COLLECTION_NOT_ALWAYS = "VIEWDEFINITION_COLLECTION_NOT_ALWAYS";
public static final String VIEWDEFINITION_COLLECTION_NEEDED1 = "VIEWDEFINITION_COLLECTION_NEEDED1";
public static final String VIEWDEFINITION_COLLECTION_NEEDED2 = "VIEWDEFINITION_COLLECTION_NEEDED2";
public static final String VIEWDEFINITION_TYPE_MISMATCH = "VIEWDEFINITION_TYPE_MISMATCH";
public static final String VIEWDEFINITION_UNABLE_TO_TYPE = "VIEWDEFINITION_UNABLE_TO_TYPE";
public static final String VIEWDEFINITION_COMPLEX_TYPE = "VIEWDEFINITION_COMPLEX_TYPE";
}

View File

@ -119,6 +119,10 @@ public abstract class XhtmlFluent {
return addTag("ul");
}
public XhtmlNode ol() {
return addTag("ol");
}
public XhtmlNode li() {
return addTag("li");
}

View File

@ -586,7 +586,6 @@ public class XhtmlParser {
if (t.length() > 0)
{
lastText = t;
// System.out.println(t);
node.addText(t).setLocation(markLocation());
s.setLength(0);
}

View File

@ -1156,4 +1156,19 @@ CANONICAL_MULTIPLE_VERSIONS_KNOWN = The version {2} for the {0} {1} is not known
SD_PATH_SLICING_DEPRECATED = The discriminator type ''{0}'' has been deprecated. Use type=value with a pattern[x] instead
SD_PATH_NOT_VALID = The discriminator path ''{0}'' does not appear to be valid for the element that is being sliced ''{1}''
SD_PATH_ERROR = The discriminator path ''{0}'' does not appear to be valid for the element that is being sliced ''{1}'': {2}
VIEWDEFINITION_SHOULD_HAVE_NAME = No name provided. A name is required in many contexts where a ViewDefinition is used
VIEWDEFINITION_NAME_INVALID = The {0} name ''{1}'' is not valid
VIEWDEFINITION_PATH_ERROR = Expression Error: {0}{1}
VIEWDEFINITION_PATH_WRONG_RETURN = A where path must return a boolean, but the expression ''{0}'' returns a ''{1}''
VIEWDEFINITION_PATH_WARNING = Expression Warning: {0}
VIEWDEFINITION_UNKNOWN_RESOURCE = The name ''{0}'' is not a valid resource{1}
VIEWDEFINITION_DUPL_COL_NAME = Duplicate Column Name ''{0}''
VIEWDEFINITION_NAME_REQUIRED = A column name is required
VIEWDEFINITION_NAME_REQUIRED_HINT = A column name is required. The natural name to chose is ''{0}'' (from the path)
VIEWDEFINITION_COLLECTION_NOT_NEEDED = collection is true, but the path statement ''{0}'' can only return single values for the column ''{1}''{2}
VIEWDEFINITION_COLLECTION_NOT_ALWAYS = The column ''{0}'' is defined as a collection, but collections are not supported in all execution contexts
VIEWDEFINITION_COLLECTION_NEEDED1 = This column is not defined as a collection, but the path statement ''{0}'' might return multiple values for the column ''{1}'' for some inputs{2}
VIEWDEFINITION_COLLECTION_NEEDED2 = This column is defined to be not a collection, but the path statement ''{0}'' might return multiple values for the column ''{1}'' for some inputs{2}
VIEWDEFINITION_TYPE_MISMATCH = The path expression ''{0}'' does not return a value of the type ''{1}'' - found ''{2}''{3}
VIEWDEFINITION_UNABLE_TO_TYPE = Unable to determine a type (found ''{0}''){1}
VIEWDEFINITION_COMPLEX_TYPE = Column from path ''{0}'' is a complex type (''{1}''){2}. This is not supported in some Runners

View File

@ -65,12 +65,14 @@ import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus;
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier.IValidationContextResourceLoader;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
@ -168,7 +170,6 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
protected final String BUNDLE = "Bundle";
protected final String LAST_UPDATED = "lastUpdated";
protected String sessionId;
protected BaseValidator parent;
protected IWorkerContext context;
protected ValidationTimeTracker timeTracker = new ValidationTimeTracker();
@ -183,6 +184,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
// don't repeatedly raise the same warnings all the time
protected Set<String> statusWarnings = new HashSet<>();
protected ValidatorSession session;
protected Source source; // @configuration
protected ValidationLevel level = ValidationLevel.HINTS; // @configuration
protected Coding jurisdiction; // @configuration
@ -194,15 +196,18 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
protected List<UsageContext> usageContexts = new ArrayList<UsageContext>(); // @configuration
protected ValidationOptions baseOptions = new ValidationOptions(FhirPublication.R5); // @configuration
public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager, boolean debug) {
public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, ValidatorSession session) {
super();
this.context = context;
this.session = session;
if (this.session == null) {
this.session = new ValidatorSession();
}
this.xverManager = xverManager;
if (this.xverManager == null) {
this.xverManager = new XVerExtensionManager(context);
}
this.debug = debug;
sessionId = Utilities.makeUuidLC();
policyAdvisor = new BasePolicyAdvisorForFullValidation(ReferenceValidationPolicy.CHECK_VALID);
urlRegex = Constants.URI_REGEX_XVER.replace("$$", CommaSeparatedStringBuilder.join("|", context.getResourceNames()));
}
@ -210,6 +215,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
public BaseValidator(BaseValidator parent) {
super();
this.parent = parent;
this.session = parent.session;
this.context = parent.context;
this.xverManager = parent.xverManager;
this.debug = parent.debug;
@ -228,7 +234,6 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
this.usageContexts.addAll(parent.usageContexts);
this.baseOptions = parent.baseOptions;
this.fetcher = parent.fetcher;
this.sessionId = parent.sessionId;
this.policyAdvisor = parent.policyAdvisor;
}
@ -1022,16 +1027,16 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
protected Element resolveInBundle(Element bundle, List<Element> entries, String ref, String fullUrl, String type, String id, NodeStack stack, List<ValidationMessage> errors, String name, Element source, boolean isWarning, boolean isNLLink) {
@SuppressWarnings("unchecked")
Map<String, List<Element>> map = (Map<String, List<Element>>) bundle.getUserData("validator.entrymap");
Map<String, List<Element>> map = (Map<String, List<Element>>) bundle.getUserData(UserDataNames.validator_entry_map);
@SuppressWarnings("unchecked")
Map<String, List<Element>> relMap = (Map<String, List<Element>>) bundle.getUserData("validator.entrymapR");
Map<String, List<Element>> relMap = (Map<String, List<Element>>) bundle.getUserData(UserDataNames.validator_entry_map_reverse);
List<Element> list = null;
if (map == null) {
map = new HashMap<>();
bundle.setUserData("validator.entrymap", map);
bundle.setUserData(UserDataNames.validator_entry_map, map);
relMap = new HashMap<>();
bundle.setUserData("validator.entrymapR", relMap);
bundle.setUserData(UserDataNames.validator_entry_map_reverse, relMap);
for (Element entry : entries) {
String fu = entry.getNamedChildValue(FULL_URL, false);
list = map.get(fu);
@ -1075,8 +1080,8 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
String tt = extractResourceType(ref);
ok = VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(tt);
}
if (!ok && stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
source.setUserData("bundle.error.noted", sessionId);
if (!ok && stack != null && !session.getSessionId().equals(source.getUserString(UserDataNames.validation_bundle_error))) {
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
hintOrError(!isWarning, errors, NO_RULE_DATE, IssueType.NOTFOUND, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND, ref, name);
}
return null;
@ -1084,17 +1089,17 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
if (fragment != null) {
int i = countFragmentMatches(el.get(0), fragment);
if (i == 0) {
source.setUserData("bundle.error.noted", sessionId);
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
hintOrError(isNLLink, errors, NO_RULE_DATE, IssueType.NOTFOUND, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND_FRAGMENT, ref, fragment, name);
} else if (i > 1) {
source.setUserData("bundle.error.noted", sessionId);
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
rule(errors, "2023-11-15", IssueType.INVALID, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE_FRAGMENT, i, ref, fragment, name);
}
}
return el.get(0);
} else {
if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
source.setUserData("bundle.error.noted", sessionId);
if (stack != null && !session.getSessionId().equals(source.getUserString(UserDataNames.validation_bundle_error))) {
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
rule(errors, "2023-11-15", IssueType.INVALID, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE, el.size(), ref, name);
}
return null;
@ -1110,8 +1115,8 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
if (el.size() == 1) {
return el.get(0);
} else {
if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
source.setUserData("bundle.error.noted", sessionId);
if (stack != null && !session.getSessionId().equals(source.getUserString(UserDataNames.validation_bundle_error))) {
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
rule(errors, "2023-11-15", IssueType.INVALID, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_FOUND_MULTIPLE, el.size(), ref, name);
}
return null;
@ -1132,17 +1137,17 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
if (!VersionUtilities.isR4Plus(context.getVersion())) {
if (el.size() == 1) {
return el.get(0);
} else if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
source.setUserData("bundle.error.noted", sessionId);
} else if (stack != null && !session.getSessionId().equals(source.getUserString(UserDataNames.validation_bundle_error))) {
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
rulePlural(errors, "2023-11-15", IssueType.INVALID, stack, false, el.size(), I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND_APPARENT, ref, name, CommaSeparatedStringBuilder.join(",", Utilities.sorted(tl)));
}
} else if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
source.setUserData("bundle.error.noted", sessionId);
} else if (stack != null && !session.getSessionId().equals(source.getUserString(UserDataNames.validation_bundle_error))) {
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
rulePlural(errors, "2023-11-15", IssueType.INVALID, stack, false, el.size(), I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND_APPARENT, ref, name, CommaSeparatedStringBuilder.join(",", Utilities.sorted(tl)));
}
} else {
if (stack != null && !sessionId.equals(source.getUserString("bundle.error.noted"))) {
source.setUserData("bundle.error.noted", sessionId);
if (stack != null && !session.getSessionId().equals(source.getUserString(UserDataNames.validation_bundle_error))) {
source.setUserData(UserDataNames.validation_bundle_error, session.getSessionId());
hintOrError(!isWarning, errors, NO_RULE_DATE, IssueType.NOTFOUND, stack, false, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND, ref, name);
}
}

View File

@ -71,6 +71,7 @@ import org.hl7.fhir.r5.utils.validation.IMessagingServices;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
import org.hl7.fhir.r5.utils.validation.constants.CheckDisplayOption;
@ -865,7 +866,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
}
public InstanceValidator getValidator(FhirFormat format) throws FHIRException, IOException {
InstanceValidator validator = new InstanceValidator(context, null, null);
InstanceValidator validator = new InstanceValidator(context, null, null, new ValidatorSession());
context.getTxClientManager().setUsage("validation");
validator.setHintAboutNonMustSupport(hintAboutNonMustSupport);
validator.setAnyExtensionsAllowed(anyExtensionsAllowed);

View File

@ -5,6 +5,7 @@ import java.io.File;
import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.validation.ValidationMessage;
@ -35,7 +36,7 @@ public class DefaultRenderer extends ValidationOutputRenderer {
dst.println((error == 0 ? "Success" : "*FAILURE*") + ": " + Integer.toString(error) + " errors, " + Integer.toString(warn) + " warnings, " + Integer.toString(info) + " notes");
for (OperationOutcome.OperationOutcomeIssueComponent issue : oo.getIssue()) {
dst.println(getIssueSummary(issue)+renderMessageId(issue));
ValidationMessage vm = (ValidationMessage) issue.getUserData("source.msg");
ValidationMessage vm = (ValidationMessage) issue.getUserData(UserDataNames.validator_source_msg);
if (vm != null && vm.sliceText != null && (crumbTrails || vm.isCriticalSignpost())) {
for (String s : vm.sliceText) {
dst.println(" slice info: "+s);

View File

@ -5,14 +5,15 @@ import java.util.List;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyOperation;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyValidationRules;
public class BCP47Checker extends CodeSystemChecker {
public BCP47Checker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug, errors);
public BCP47Checker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
}

View File

@ -7,6 +7,7 @@ import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent;
import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.CodeValidationRule;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyFilterType;
@ -15,8 +16,8 @@ import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyValidatio
public class CPTChecker extends CodeSystemChecker {
public CPTChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug, errors);
public CPTChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
}
@Override

View File

@ -10,6 +10,7 @@ import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent;
import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent;
import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.CodeValidationRule;
@ -21,8 +22,8 @@ public class CodeSystemBasedChecker extends CodeSystemChecker {
private CodeSystem cs;
public CodeSystemBasedChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, CodeSystem cs) {
super(context, xverManager, debug, errors);
public CodeSystemBasedChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, CodeSystem cs, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
this.cs = cs;
}

View File

@ -6,6 +6,7 @@ import java.util.List;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.validation.ValidationMessage;
@ -23,8 +24,8 @@ public abstract class CodeSystemChecker extends BaseValidator {
private boolean hasDisplay = false;
protected List<ValidationMessage> errors;
protected CodeSystemChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug);
protected CodeSystemChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, session);
this.errors = errors;
}

View File

@ -14,6 +14,7 @@ import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.terminologies.utilities.CodingValidationRequest;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
@ -33,8 +34,8 @@ public class CodingsObserver extends BaseValidator {
}
}
public CodingsObserver(@Nonnull IWorkerContext context, @Nonnull XVerExtensionManager xverManager, boolean debug) {
super(context, xverManager, debug);
public CodingsObserver(@Nonnull IWorkerContext context, @Nonnull XVerExtensionManager xverManager, boolean debug, ValidatorSession session) {
super(context, xverManager, debug, session);
this.context = context;
}

View File

@ -4,12 +4,13 @@ import java.util.List;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.validation.ValidationMessage;
public class GeneralCodeSystemChecker extends CodeSystemChecker {
public GeneralCodeSystemChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug, errors);
public GeneralCodeSystemChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
// TODO Auto-generated constructor stub
}

View File

@ -5,6 +5,7 @@ import java.util.List;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.CodeValidationRule;
@ -14,8 +15,8 @@ import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyValidatio
public class LoincChecker extends CodeSystemChecker {
public LoincChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug, errors);
public LoincChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
}

View File

@ -5,6 +5,7 @@ import java.util.List;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.CodeValidationRule;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyFilterType;
@ -13,8 +14,8 @@ import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyValidatio
public class RxNormChecker extends CodeSystemChecker {
public RxNormChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug, errors);
public RxNormChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
}

View File

@ -7,6 +7,7 @@ import java.util.List;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.validation.ValidationMessage;
@ -23,8 +24,8 @@ public class SnomedCTChecker extends CodeSystemChecker {
private boolean hasTag = false;
private List<String> tags = new ArrayList<>();
public SnomedCTChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug, errors);
public SnomedCTChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
}
public void checkConcept(String code, String display) {

View File

@ -5,6 +5,7 @@ import java.util.List;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.CodeValidationRule;
import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyFilterType;
@ -13,8 +14,8 @@ import org.hl7.fhir.validation.instance.type.ValueSetValidator.PropertyValidatio
public class UcumChecker extends CodeSystemChecker {
public UcumChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors) {
super(context, xverManager, debug, errors);
public UcumChecker(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, List<ValidationMessage> errors, ValidatorSession session) {
super(context, xverManager, debug, errors, session);
}

View File

@ -161,6 +161,7 @@ import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.BuildExtensions;
import org.hl7.fhir.r5.utils.ResourceUtilities;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus;
import org.hl7.fhir.r5.utils.sql.Validator;
@ -171,6 +172,7 @@ import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.CodedContentVal
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.ElementValidationAction;
import org.hl7.fhir.r5.utils.validation.IValidationProfileUsageTracker;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
import org.hl7.fhir.r5.utils.validation.constants.CheckDisplayOption;
@ -216,6 +218,7 @@ import org.hl7.fhir.validation.instance.type.StructureMapValidator;
import org.hl7.fhir.validation.instance.type.StructureMapValidator.VariableDefn;
import org.hl7.fhir.validation.instance.type.StructureMapValidator.VariableSet;
import org.hl7.fhir.validation.instance.type.ValueSetValidator;
import org.hl7.fhir.validation.instance.type.ViewDefinitionValidator;
import org.hl7.fhir.validation.instance.utils.Base64Util;
import org.hl7.fhir.validation.instance.utils.CanonicalResourceLookupResult;
import org.hl7.fhir.validation.instance.utils.CanonicalTypeSorter;
@ -442,8 +445,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
ValidationContext c = (ValidationContext) appContext;
if (refContext != null && refContext.hasUserData("validator.bundle.resolution")) {
return (Base) refContext.getUserData("validator.bundle.resolution");
if (refContext != null && refContext.hasUserData(UserDataNames.validator_bundle_resolution)) {
return (Base) refContext.getUserData(UserDataNames.validator_bundle_resolution);
}
if (c.getAppContext() instanceof Element) {
@ -616,8 +619,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private boolean unknownCodeSystemsCauseErrors;
private boolean noExperimentalContent;
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
super(theContext, xverManager, false);
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager, ValidatorSession session) {
super(theContext, xverManager, false, session);
start = System.currentTimeMillis();
this.externalHostServices = hostServices;
this.profileUtilities = new ProfileUtilities(theContext, null, null);
@ -630,7 +633,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
source = Source.InstanceValidator;
fpe.setDoNotEnforceAsSingletonRule(!VersionUtilities.isR5VerOrLater(theContext.getVersion()));
fpe.setAllowDoubleQuotes(allowDoubleQuotesInFHIRPath);
codingObserver = new CodingsObserver(theContext, xverManager, debug);
codingObserver = new CodingsObserver(theContext, xverManager, debug, session);
}
@Override
@ -1023,9 +1026,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|| (element.getName().equals("id") && !element.getPath().substring(0, element.getPath().length()-3).contains("."))
|| (element.getName().equals("text") && !element.getPath().substring(0, element.getPath().length()-5).contains(".")))
return;
String hasFixed = element.getUserString("hasFixed");
String hasFixed = element.getUserString(UserDataNames.keyview_hasFixed);
if (element.getPath().contains(".") && (hasFixed== null || !hasFixed.equals("Y"))) {
String elementUsage = element.getUserString("elementSupported");
String elementUsage = element.getUserString(UserDataNames.keyview_elementSupported);
hint(errors, NO_RULE_DATE, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), elementUsage != null && (elementUsage.equals("Y") || elementUsage.equals("NA")), I18nConstants.MUSTSUPPORT_VAL_MUSTSUPPORT, element.getName(), element.getProperty().getStructure().getVersionedUrl());
if (elementUsage==null || !elementUsage.equals("Y"))
return;
@ -5112,7 +5115,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (!slicer.getSlicing().hasDiscriminator())
return false; // cannot validate in this case
ExpressionNode n = (ExpressionNode) ed.getUserData("slice.expression.cache");
ExpressionNode n = (ExpressionNode) ed.getUserData(UserDataNames.validator_slice_expression_cache);
if (n == null) {
long t = System.nanoTime();
// GG: this approach is flawed because it treats discriminators individually rather than collectively
@ -5230,7 +5233,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, expression, profile.getVersionedUrl(), path, e.getMessage()));
}
timeTracker.fpe(t);
ed.setUserData("slice.expression.cache", n);
ed.setUserData(UserDataNames.validator_slice_expression_cache, n);
} else {
}
@ -5780,8 +5783,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// }
private void resolveBundleReferences(Element element, List<Element> bundles) {
if (!element.hasUserData("validator.bundle.resolved")) {
element.setUserData("validator.bundle.resolved", true);
if (!element.hasUserData(UserDataNames.validator_bundle_resolved)) {
element.setUserData(UserDataNames.validator_bundle_resolved, true);
List<Element> list = new ArrayList<Element>();
list.addAll(bundles);
list.add(0, element);
@ -5814,7 +5817,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
List<Element> entries = bundle.getChildren(ENTRY);
Element tgt = resolveInBundle(bundle, entries, ref, fu, resource.fhirType(), resource.getIdBase(), null, null, null, element, false, false);
if (tgt != null) {
element.setUserData("validator.bundle.resolution", tgt.getNamedChild(RESOURCE, false));
element.setUserData(UserDataNames.validator_bundle_resolution, tgt.getNamedChild(RESOURCE, false));
return;
}
}
@ -5943,8 +5946,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return new StructureMapValidator(this, fpe, profileUtilities).validateStructureMap(valContext, errors, element, stack) && ok;
} else if (element.getType().equals("ValueSet")) {
return new ValueSetValidator(this).validateValueSet(valContext, errors, element, stack) && ok;
} else if (element.getType().equals("ViewDefinition")) {
return new ViewDefinitionValidator(this).validateViewDefinition(valContext, errors, element, stack) && ok;
} else if (element.getType().equals("ImplementationGuide")) {
return new ImplementationGuideValidator(this.context, xverManager, debug).validateImplementationGuide(valContext, errors, element, stack) && ok;
return new ImplementationGuideValidator(this.context, xverManager, debug, session).validateImplementationGuide(valContext, errors, element, stack) && ok;
} else if ("http://hl7.org/fhir/uv/sql-on-fhir/StructureDefinition/ViewDefinition".equals(element.getProperty().getStructure().getUrl())) {
if (element.getNativeObject() != null && element.getNativeObject() instanceof JsonObject) {
JsonObject json = (JsonObject) element.getNativeObject();
@ -6921,7 +6926,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
public void checkMustSupport(StructureDefinition profile, ElementInfo ei) {
String usesMustSupport = profile.getUserString("usesMustSupport");
String usesMustSupport = profile.getUserString(UserDataNames.keyview_usesMustSupport);
if (usesMustSupport == null) {
usesMustSupport = "N";
for (ElementDefinition pe : profile.getSnapshot().getElement()) {
@ -6930,18 +6935,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
break;
}
}
profile.setUserData("usesMustSupport", usesMustSupport);
profile.setUserData(UserDataNames.keyview_usesMustSupport, usesMustSupport);
}
String elementSupported = ei.getElement().getUserString("elementSupported");
String fixedValue = ei.getElement().getUserString("hasFixed");
String elementSupported = ei.getElement().getUserString(UserDataNames.keyview_elementSupported);
String fixedValue = ei.getElement().getUserString(UserDataNames.keyview_hasFixed);
if ((elementSupported == null || !elementSupported.equals("Y")) && ei.definition.getMustSupport()) {
if (ei.definition.getMustSupport()) {
ei.getElement().setUserData("elementSupported", "Y");
ei.getElement().setUserData(UserDataNames.keyview_elementSupported, "Y");
}
} else if (elementSupported == null && !usesMustSupport.equals("Y"))
ei.getElement().setUserData("elementSupported", "NA");
ei.getElement().setUserData(UserDataNames.keyview_elementSupported, "NA");
if (fixedValue==null && (ei.definition.hasFixed() || ei.definition.hasPattern()))
ei.getElement().setUserData("hasFixed", "Y");
ei.getElement().setUserData(UserDataNames.keyview_hasFixed, "Y");
}
public boolean checkCardinalities(List<ValidationMessage> errors, StructureDefinition profile, Element element, NodeStack stack,
@ -7352,7 +7357,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if ("dom-3".equals(inv.getKey())) {
return true;
}
ExpressionNode n = (ExpressionNode) inv.getUserData("validator.expression.cache");
ExpressionNode n = (ExpressionNode) inv.getUserData(UserDataNames.validator_expression_cache);
if (n == null) {
long t = System.nanoTime();
try {
@ -7363,7 +7368,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return false;
}
timeTracker.fpe(t);
inv.setUserData("validator.expression.cache", n);
inv.setUserData(UserDataNames.validator_expression_cache, n);
}
valContext.setProfile(profile);
@ -7665,10 +7670,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
for (ElementDefinitionConstraintComponent inv : ed.getConstraint()) {
if (inv.hasExpression()) {
try {
ExpressionNode n = (ExpressionNode) inv.getUserData("validator.expression.cache");
ExpressionNode n = (ExpressionNode) inv.getUserData(UserDataNames.validator_expression_cache);
if (n == null) {
n = fpe.parse(FHIRPathExpressionFixer.fixExpr(inv.getExpression(), inv.getKey(), context.getVersion()));
inv.setUserData("validator.expression.cache", n);
inv.setUserData(UserDataNames.validator_expression_cache, n);
}
fpe.check(null, sd.getKind() == StructureDefinitionKind.RESOURCE ? sd.getType() : "DomainResource", ed.getPath(), n);
} catch (Exception e) {

View File

@ -37,17 +37,18 @@ import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext.IValidatorFactory;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
public class InstanceValidatorFactory implements IValidatorFactory {
@Override
public IResourceValidator makeValidator(IWorkerContext ctxt, XVerExtensionManager xverManager) throws FHIRException {
return new InstanceValidator(ctxt, null, xverManager);
public IResourceValidator makeValidator(IWorkerContext ctxt, XVerExtensionManager xverManager, ValidatorSession session) throws FHIRException {
return new InstanceValidator(ctxt, null, xverManager, session);
}
@Override
public IResourceValidator makeValidator(IWorkerContext ctxt) throws FHIRException {
return new InstanceValidator(ctxt, null, null);
public IResourceValidator makeValidator(IWorkerContext ctxt, ValidatorSession session) throws FHIRException {
return new InstanceValidator(ctxt, null, null, session);
}
}

View File

@ -75,7 +75,6 @@ public class BundleValidator extends BaseValidator {
public boolean validateBundle(List<ValidationMessage> errors, Element bundle, NodeStack stack, boolean checkSpecials, ValidationContext hostContext, PercentageTracker pct, ValidationMode mode) {
boolean ok = true;
sessionId = Utilities.makeUuidLC();
String type = bundle.getNamedChildValue(TYPE, false);
type = StringUtils.defaultString(type);

View File

@ -29,6 +29,7 @@ import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier.ValidationContextResourceProxy;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.FhirPublication;
@ -53,8 +54,8 @@ import ca.uhn.fhir.util.ObjectUtil;
public class ImplementationGuideValidator extends BaseValidator {
public ImplementationGuideValidator(IWorkerContext context, XVerExtensionManager xverManager, boolean debug) {
super(context, xverManager, debug);
public ImplementationGuideValidator(IWorkerContext context, XVerExtensionManager xverManager, boolean debug, ValidatorSession session) {
super(context, xverManager, debug, session);
}
public boolean validateImplementationGuide(ValidationContext valContext, List<ValidationMessage> errors, Element ig, NodeStack stack) {

View File

@ -44,6 +44,7 @@ import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass;
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.Utilities;
@ -98,7 +99,7 @@ public class StructureDefinitionValidator extends BaseValidator {
ok = rule(errors, "2022-11-02", IssueType.NOTFOUND, stack.getLiteralPath(), bok, I18nConstants.SD_CONSTRAINED_KIND_NO_MATCH, sd.getKind().toCode(), base.getKind().toCode(), base.getType(), base.getUrl()) && ok;
if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT) {
ok = rule(errors, "2022-11-02", IssueType.NOTFOUND, stack.getLiteralPath(), sd.hasType() && sd.getType().equals(base.getType()), I18nConstants.SD_CONSTRAINED_TYPE_NO_MATCH, sd.getType(), base.getType()) && ok;
if (!src.hasUserData("profileutils.snapshot.errors")) { // if it does, we've already logged these errors elsewhere
if (!src.hasUserData(UserDataNames.SNAPSHOT_ERRORS)) { // if it does, we've already logged these errors elsewhere
List<ValidationMessage> msgs = new ArrayList<>();
ProfileUtilities pu = new ProfileUtilities(context, msgs, null);
pu.setForPublication(forPublication);

View File

@ -29,6 +29,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.terminologies.ConceptMapUtilities;
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.structuremap.ResolvedGroup;
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
@ -355,9 +356,9 @@ public class StructureMapValidator extends BaseValidator {
fired = false;
cc = 0;
for (Element group : groups) {
if (!group.hasUserData("structuremap.validated")) {
if (hasInputTypes(group) || group.hasUserData("structuremap.parameters")) {
group.setUserData("structuremap.validated", true);
if (!group.hasUserData(UserDataNames.map_validated)) {
if (hasInputTypes(group) || group.hasUserData(UserDataNames.map_parameters)) {
group.setUserData(UserDataNames.map_validated, true);
fired = true;
ok = validateGroup(valContext, errors, src, group, stack.push(group, cc, null, null), grpNames) && ok;
}
@ -368,7 +369,7 @@ public class StructureMapValidator extends BaseValidator {
cc = 0;
for (Element group : groups) {
if (!group.hasUserData("structuremap.validated")) {
if (!group.hasUserData(UserDataNames.map_validated)) {
hint(errors, "2023-03-01", IssueType.INFORMATIONAL, group.line(), group.col(), stack.push(group, cc, null, null).getLiteralPath(), ok, I18nConstants.SM_ORPHAN_GROUP, group.getChildValue("name"));
ok = validateGroup(valContext, errors, src, group, stack.push(group, cc, null, null), grpNames) && ok;
}
@ -421,7 +422,7 @@ public class StructureMapValidator extends BaseValidator {
}
VariableSet variables = new VariableSet();
VariableSet pvars = (VariableSet) group.getUserData("structuremap.parameters");
VariableSet pvars = (VariableSet) group.getUserData(UserDataNames.map_parameters);
// first, load all the inputs
List<Element> inputs = group.getChildrenByName("input");
@ -466,7 +467,7 @@ public class StructureMapValidator extends BaseValidator {
private StructureMapGroupComponent makeGroupComponent(Element group) {
StructureMapGroupComponent grp = new StructureMapGroupComponent();
grp.setUserData("element.source", group);
grp.setUserData(UserDataNames.map_source, group);
grp.setName(group.getChildValue("name"));
List<Element> inputs = group.getChildrenByName("input");
for (Element input : inputs) {
@ -1274,13 +1275,13 @@ public class StructureMapValidator extends BaseValidator {
}
cc++;
}
if (ok && grp.getTargetGroup().hasUserData("element.source")) {
Element g = (Element) grp.getTargetGroup().getUserData("element.source");
if (g.hasUserData("structuremap.parameters")) {
VariableSet pvars = (VariableSet) g.getUserData("structuremap.parameters");
if (ok && grp.getTargetGroup().hasUserData(UserDataNames.map_source)) {
Element g = (Element) grp.getTargetGroup().getUserData(UserDataNames.map_source);
if (g.hasUserData(UserDataNames.map_parameters)) {
VariableSet pvars = (VariableSet) g.getUserData(UserDataNames.map_parameters);
warning(errors, "2023-03-01", IssueType.INVALID, dependent.line(), dependent.col(), stack.getLiteralPath(), pvars.matches(lvars), I18nConstants.SM_DEPENDENT_PARAM_TYPE_MISMATCH_DUPLICATE, grp.getTargetGroup().getName(), pvars.summary(), lvars.summary());
} else {
g.setUserData("structuremap.parameters", lvars);
g.setUserData(UserDataNames.map_parameters, lvars);
}
}
}

View File

@ -132,21 +132,21 @@ public class ValueSetValidator extends BaseValidator {
private CodeSystemChecker getSystemValidator(String system, List<ValidationMessage> errors) {
if (system == null) {
return new GeneralCodeSystemChecker(context, xverManager, debug, errors);
return new GeneralCodeSystemChecker(context, xverManager, debug, errors, session);
}
switch (system) {
case "http://snomed.info/sct" :return new SnomedCTChecker(context, xverManager, debug, errors);
case "http://loinc.org": return new LoincChecker(context, xverManager, debug, errors);
case "http://www.nlm.nih.gov/research/umls/rxnorm": return new RxNormChecker(context, xverManager, debug, errors);
case "http://unitsofmeasure.org": return new UcumChecker(context, xverManager, debug, errors);
case "http://www.ama-assn.org/go/cpt": return new CPTChecker(context, xverManager, debug, errors);
case "urn:ietf:bcp:47": return new BCP47Checker(context, xverManager, debug, errors);
case "http://snomed.info/sct" :return new SnomedCTChecker(context, xverManager, debug, errors, session);
case "http://loinc.org": return new LoincChecker(context, xverManager, debug, errors, session);
case "http://www.nlm.nih.gov/research/umls/rxnorm": return new RxNormChecker(context, xverManager, debug, errors, session);
case "http://unitsofmeasure.org": return new UcumChecker(context, xverManager, debug, errors, session);
case "http://www.ama-assn.org/go/cpt": return new CPTChecker(context, xverManager, debug, errors, session);
case "urn:ietf:bcp:47": return new BCP47Checker(context, xverManager, debug, errors, session);
default:
CodeSystem cs = context.fetchCodeSystem(system);
if (cs != null) {
return new CodeSystemBasedChecker(context, xverManager, debug, errors, cs);
return new CodeSystemBasedChecker(context, xverManager, debug, errors, cs, session);
} else {
return new GeneralCodeSystemChecker(context, xverManager, debug, errors);
return new GeneralCodeSystemChecker(context, xverManager, debug, errors, session);
}
}
}

View File

@ -0,0 +1,531 @@
package org.hl7.fhir.validation.instance.type;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.fhirpath.ExpressionNode;
import org.hl7.fhir.r5.fhirpath.ExpressionNode.CollectionStatus;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IssueMessage;
import org.hl7.fhir.r5.fhirpath.TypeDetails;
import org.hl7.fhir.r5.utils.UserDataNames;
import org.hl7.fhir.r5.utils.sql.Column;
import org.hl7.fhir.r5.utils.sql.ColumnKind;
import org.hl7.fhir.r5.utils.sql.Runner;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.validation.BaseValidator;
import org.hl7.fhir.validation.instance.utils.NodeStack;
import org.hl7.fhir.validation.instance.utils.ValidationContext;
// see also org.hl7.fhir.r5.utils.sql.Validator
public class ViewDefinitionValidator extends BaseValidator {
private static class VersionEvaluationContext {
private IWorkerContext context;
private Runner runner;
private FHIRPathEngine fpe;
public VersionEvaluationContext(IWorkerContext context) {
this.context = context;
runner = new Runner();
runner.setContext(context);
fpe = new FHIRPathEngine(context); // we need our own customised one
fpe.setHostServices(runner);
fpe.setEmitSQLonFHIRWarning(true);
}
}
public ViewDefinitionValidator(BaseValidator parent) {
super(parent);
}
public boolean validateViewDefinition(ValidationContext hostContext, List<ValidationMessage> errors, Element vd, NodeStack stack) throws FHIRException {
boolean ok = true;
if (warning(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, vd.hasChild("name"), I18nConstants.VIEWDEFINITION_SHOULD_HAVE_NAME)) {
warning(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, isValidName(vd.getNamedChildValue("name")), I18nConstants.VIEWDEFINITION_NAME_INVALID, "view", vd.getNamedChildValue("name"));
}
List<Column> columns = new ArrayList<>();
vd.setUserData(UserDataNames.db_columns, columns);
List<VersionEvaluationContext> versions = new ArrayList<>();
if (vd.hasChildren("fhirVersion")) {
for (Element v : vd.getChildren("fhirVersion")) {
String ver = v.primitiveValue();
if (ver.equals(context.getVersion())) {
makeDefaultContext(versions);
} else {
try {
makeVersionSpecificContext(versions, ver);
} catch (IOException e) {
throw new FHIRException(e);
}
}
}
} else {
makeDefaultContext(versions);
}
boolean first = true;
for (VersionEvaluationContext vec : versions) {
String vdesc = versions.size() == 1 ? "" : " for version "+VersionUtilities.getNameForVersion(vec.context.getVersion());
String resourceName = vd.getNamedChildValue("resource");
if (resourceName != null) {
if (rule(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, context.getResourceNamesAsSet().contains(resourceName), I18nConstants.VIEWDEFINITION_UNKNOWN_RESOURCE, resourceName)) {
int i = 0;
if (first) {
for (Element constant : vd.getChildren("constant")) {
ok = checkConstant(hostContext, errors, stack.push(constant, i, null, null), constant) && ok;
i++;
}
}
i = 0;
for (Element where : vd.getChildren("where")) {
ok = checkWhere(hostContext, errors, vd, stack.push(where, i, null, null), where, resourceName, vec, vdesc, first) && ok;
i++;
}
TypeDetails t = new TypeDetails(CollectionStatus.SINGLETON, resourceName);
i = 0;
for (Element select : vd.getChildren("select")) {
ok = checkSelect(hostContext, errors, vd, vd, stack.push(select, i, null, null), select, resourceName, t, columns, vec, vdesc, first) && ok;
i++;
}
}
} else {
ok = false;
}
first = false;
}
return ok;
}
private void makeVersionSpecificContext(List<VersionEvaluationContext> versions, String ver) throws FHIRException, IOException {
if (session.getObjects().containsKey(ValidatorSession.VIEW_DEFINITION_CONTEXT+"."+ver)) {
versions.add((VersionEvaluationContext) session.getObjects().get(ValidatorSession.VIEW_DEFINITION_CONTEXT+"."+ver));
} else {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().build();
NpmPackage npm = pcm.loadPackage(VersionUtilities.packageForVersion(ver));
SimpleWorkerContext context = new SimpleWorkerContext.SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).fromPackage(npm);
var vec = new VersionEvaluationContext(context);
session.getObjects().put(ValidatorSession.VIEW_DEFINITION_CONTEXT+"."+context.getVersion(), vec);
versions.add(vec);
}
}
private void makeDefaultContext(List<VersionEvaluationContext> versions) {
if (session.getObjects().containsKey(ValidatorSession.VIEW_DEFINITION_CONTEXT+"."+context.getVersion())) {
versions.add((VersionEvaluationContext) session.getObjects().get(ValidatorSession.VIEW_DEFINITION_CONTEXT+"."+context.getVersion()));
} else {
var vec = new VersionEvaluationContext(context);
session.getObjects().put(ValidatorSession.VIEW_DEFINITION_CONTEXT+"."+context.getVersion(), vec);
versions.add(vec);
}
}
private boolean checkSelect(ValidationContext hostContext, List<ValidationMessage> errors, Element vd, Element parent, NodeStack stack, Element select,
String resourceName, TypeDetails t, List<Column> columns, VersionEvaluationContext vec, String vdesc, boolean first) {
select.setUserData(UserDataNames.db_columns, columns);
boolean ok = true;
if (select.hasChild("forEach")) {
Element e = select.getNamedChild("forEach");
t = checkForEach(hostContext, errors, vd, select, stack.push(e, -1, null, null), e, resourceName, t, vec, vdesc, first);
} else if (select.hasChild("forEachOrNull")) {
Element e = select.getNamedChild("forEachOrNull");
t = checkForEachOrNull(hostContext, errors, vd, select, stack.push(e, -1, null, null), e, resourceName, t, vec, vdesc, first);
}
if (t == null) {
ok = false;
} else {
if (select.hasChildren("column")) {
int i = 0;
for (Element e : select.getChildren("column")) {
ok = checkColumn(hostContext, errors, vd,select, stack.push(e, i, null, null), e, resourceName, t, columns, vec, vdesc, first) && ok;
i++;
}
}
if (select.hasChildren("select")) {
int i = 0;
for (Element e : select.getChildren("select")) {
ok = checkSelect(hostContext, errors, vd, select, stack.push(e, i, null, null), e, resourceName, t, columns, vec, vdesc, first) && ok;
i++;
}
}
if (select.hasChildren("unionAll")) {
int i = 0;
for (Element e : select.getChildren("unionAll")) {
ok = checkUnion(hostContext, errors, vd, parent, stack.push(e, i, null, null), e, resourceName, t, columns, vec, vdesc, first) && ok;
i++;
}
}
checkColumnNamesUnique(errors, stack, columns);
}
return ok;
}
private void checkColumnNamesUnique(List<ValidationMessage> errors, NodeStack stack, List<Column> columns) {
Set<String> names = new HashSet<>();
for (Column col : columns) {
if (col != null) {
String name = col.getName();
if (!names.contains(name)) {
names.add(name);
} else if (!col.isDuplicateReported()) {
col.setDuplicateReported(true);
rule(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, false, I18nConstants.VIEWDEFINITION_DUPL_COL_NAME, name);
}
}
}
}
private boolean checkUnion(ValidationContext hostContext, List<ValidationMessage> errors, Element vd, Element parent, NodeStack stack,
Element unionAll, String resourceName, TypeDetails t, List<Column> columns, VersionEvaluationContext vec, String vdesc, boolean first) {
return false;
// List<List<Column>> unionColumns = new ArrayList<>();
// int i = 0;
// for (JsonElement e : ((JsonArray) a)) {
// if (!(e instanceof JsonObject)) {
// error(path+".unionAll["+i+"]", e, "unionAll["+i+"] is not an object", IssueType.INVALID);
// } else {
// unionColumns.add(checkSelect(vd, path+".unionAll["+i+"]", (JsonObject) e, t));
// }
// i++;
// }
// if (i < 2) {
// warning(path+".unionAll", a, "unionAll should have more than one item");
// }
// if (unionColumns.size() > 1) {
// List<Column> columns = unionColumns.get(0);
// for (int ic = 1; ic < unionColumns.size(); ic++) {
// String diff = columnDiffs(columns, unionColumns.get(ic));
// if (diff != null) {
// error(path+".unionAll["+i+"]", ((JsonArray) a).get(ic), "unionAll["+i+"] column definitions do not match: "+diff, IssueType.INVALID);
// }
// }
// a.setUserData(UserDataNames.db_columns, columns);
// return columns;
// }
// }
// return null;
}
private String columnDiffs(List<Column> list1, List<Column> list2) {
if (list1.size() == list2.size()) {
for (int i = 0; i < list1.size(); i++) {
if (list1.get(i) == null || list2.get(i) == null) {
return null; // just suppress any addition errors
}
String diff = list1.get(i).diff(list2.get(i));
if (diff != null) {
return diff+" at #"+i;
}
}
return null;
} else {
return "Column counts differ: "+list1.size()+" vs "+list2.size();
}
}
private boolean checkColumn(ValidationContext hostContext, List<ValidationMessage> errors, Element vd, Element parent, NodeStack stack, Element column, String resourceName,
TypeDetails t, List<Column> columns, VersionEvaluationContext vec, String vdesc, boolean first) {
boolean ok = false;
String expr = column.getNamedChildValue("path");
if (expr != null) {
ExpressionNode n = getParsedExpression(column, vec.fpe, expr, errors, stack, UserDataNames.db_path);
if (n != null) {
ok = true;
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("; ");
List<IssueMessage> warnings = new ArrayList<>();
TypeDetails td = null;
try {
td = vec.fpe.checkOnTypes(vd, resourceName, t, n, warnings);
} catch (Exception e) {
rule(errors, "2024-11-14", IssueType.EXCEPTION, stack, false, I18nConstants.VIEWDEFINITION_PATH_ERROR, e.getMessage(), vdesc);
ok = false;
}
if (td != null) {
for (IssueMessage s : warnings) {
warning(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, false, I18nConstants.VIEWDEFINITION_PATH_WARNING, s.getMessage(), vdesc);
}
String columnName = column.getNamedChildValue("name");
if (columnName == null) {
List<String> names = n.getDistalNames();
if (names.size() == 1 && names.get(0) != null) {
columnName = names.get(0);
ok = rule(errors, "2024-11-14", IssueType.INVALID, stack, isValidName(columnName), I18nConstants.VIEWDEFINITION_NAME_REQUIRED_HINT, columnName) && ok;
} else {
ok = false;
rule(errors, "2024-11-14", IssueType.INVALID, stack, false, I18nConstants.VIEWDEFINITION_NAME_REQUIRED);
}
}
if (columnName != null) {
// ok = rule(errors, "2024-11-14", IssueType.INVALID, stack, false, I18nConstants.VIEWDEFINITION_NAME_ REQUIRED) && ok;
column.setUserData(UserDataNames.db_name, columnName);
Boolean isColl = null;
if (column.hasChild("collection")) {
isColl = "true".equals(column.getNamedChildValue("collection"));
}
if (isColl != null && isColl) {
if (td.getCollectionStatus() == CollectionStatus.SINGLETON) {
if (!hint(errors, "2024-11-14", IssueType.INFORMATIONAL, stack, false, I18nConstants.VIEWDEFINITION_COLLECTION_NOT_NEEDED, expr, columnName)) {
b.append(context.formatMessage(I18nConstants.VIEWDEFINITION_COLLECTION_NOT_NEEDED, expr, columnName));
}
}
if (!hint(errors, "2024-11-14", IssueType.INFORMATIONAL, stack, false, I18nConstants.VIEWDEFINITION_COLLECTION_NOT_ALWAYS)) {
b.append(context.formatMessage(I18nConstants.VIEWDEFINITION_COLLECTION_NOT_ALWAYS));
}
} else if (isColl == null) {
if (!hint(errors, "2024-11-14", IssueType.INFORMATIONAL, stack, td.getCollectionStatus() == CollectionStatus.SINGLETON, I18nConstants.VIEWDEFINITION_COLLECTION_NEEDED1, expr, columnName, vdesc)) {
b.append(context.formatMessage(I18nConstants.VIEWDEFINITION_COLLECTION_NEEDED1, expr, columnName, vdesc));
}
} else {
if (!hint(errors, "2024-11-14", IssueType.INFORMATIONAL, stack, td.getCollectionStatus() == CollectionStatus.SINGLETON, I18nConstants.VIEWDEFINITION_COLLECTION_NEEDED1, expr, columnName, vdesc)) {
b.append(context.formatMessage(I18nConstants.VIEWDEFINITION_COLLECTION_NEEDED2, expr, columnName, vdesc));
}
}
Set<String> types = new HashSet<>();
if (n.isNullSet()) {
types.add("null");
} else {
// ok collection is sorted
for (String type : td.getTypes()) {
types.add(simpleType(type));
}
String type = column.getNamedChildValue("type");
if (type != null) {
if (td.hasType(type)) {
types.clear();
types.add(simpleType(type));
} else {
ok = rule(errors, "2024-11-14", IssueType.INVALID, stack, false, I18nConstants.VIEWDEFINITION_TYPE_MISMATCH, expr, type, td.describe(), vdesc) && ok;
}
}
}
if (types.size() != 1) {
ok = rule(errors, "2024-11-14", IssueType.INVALID, stack, false, I18nConstants.VIEWDEFINITION_UNABLE_TO_TYPE, td.describe(), vdesc) && ok;
} else {
String type = types.iterator().next();
boolean tok = false;
if (!isSimpleType(type) && !"null".equals(type)) {
hint(errors, "2024-11-14", IssueType.INFORMATIONAL, stack, false, I18nConstants.VIEWDEFINITION_COMPLEX_TYPE, expr, type, vdesc);
} else {
tok = true;
}
if (tok) {
if (first) {
Column col = new Column(columnName, isColl, type, kindForType(type));
column.setUserData(UserDataNames.db_column, col);
col.setNotes(b.toString());
columns.add(col);
} else if (b.count() > 0){
Column col = null;
for (Column c : columns) {
if (c.getName().equals(columnName)) {
col = c;
}
}
if (col != null) {
col.addNote(b.toString());
}
}
} else {
ok = false;
}
}
}
}
}
}
return ok;
}
private ColumnKind kindForType(String type) {
switch (type) {
case "null": return ColumnKind.Null;
case "dateTime": return ColumnKind.DateTime;
case "boolean": return ColumnKind.Boolean;
case "integer": return ColumnKind.Integer;
case "decimal": return ColumnKind.Decimal;
case "string": return ColumnKind.String;
case "canonical": return ColumnKind.String;
case "url": return ColumnKind.String;
case "uri": return ColumnKind.String;
case "oid": return ColumnKind.String;
case "uuid": return ColumnKind.String;
case "id": return ColumnKind.String;
case "code": return ColumnKind.String;
case "base64Binary": return ColumnKind.Binary;
case "time": return ColumnKind.Time;
default: return ColumnKind.Complex;
}
}
private boolean isSimpleType(String type) {
return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time", "canonical", "uri", "url");
}
private String simpleType(String type) {
type = type.replace("http://hl7.org/fhirpath/System.", "").replace("http://hl7.org/fhir/StructureDefinition/", "");
if (Utilities.existsInList(type, "date", "dateTime", "instant")) {
return "dateTime";
}
if (Utilities.existsInList(type, "Boolean", "boolean")) {
return "boolean";
}
if (Utilities.existsInList(type, "Integer", "integer", "integer64")) {
return "integer";
}
if (Utilities.existsInList(type, "Decimal", "decimal")) {
return "decimal";
}
if (Utilities.existsInList(type, "String", "string", "code")) {
return "string";
}
if (Utilities.existsInList(type, "Time", "time")) {
return "time";
}
if (Utilities.existsInList(type, "base64Binary")) {
return "base64Binary";
}
return type;
}
private TypeDetails checkForEach(ValidationContext hostContext, List<ValidationMessage> errors, Element vd, Element parent, NodeStack stack,
Element expression, String resourceName, TypeDetails t, VersionEvaluationContext vec, String vdesc, boolean first) {
String expr = expression.primitiveValue();
if (expr != null) {
ExpressionNode n = getParsedExpression(parent, vec.fpe, expr, errors, stack, UserDataNames.db_forEach);
if (n != null) {
List<IssueMessage> warnings = new ArrayList<>();
TypeDetails td = null;
try {
td = vec.fpe.checkOnTypes(vd, resourceName, t, n, warnings);
} catch (Exception e) {
rule(errors, "2024-11-14", IssueType.EXCEPTION, stack, false, I18nConstants.VIEWDEFINITION_PATH_ERROR, e.getMessage(), vdesc);
return null;
}
if (td != null) {
for (IssueMessage s : warnings) {
warning(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, false, I18nConstants.VIEWDEFINITION_PATH_WARNING, s.getMessage(), vdesc);
}
}
return td;
}
}
return null;
}
private TypeDetails checkForEachOrNull(ValidationContext hostContext, List<ValidationMessage> errors, Element vd, Element parent, NodeStack stack,
Element expression, String resourceName, TypeDetails t, VersionEvaluationContext vec, String vdesc, boolean first) {
String expr = expression.primitiveValue();
if (expr != null) {
ExpressionNode n = getParsedExpression(parent, vec.fpe, expr, errors, stack, UserDataNames.db_forEachOrNull);
if (n != null) {
List<IssueMessage> warnings = new ArrayList<>();
TypeDetails td = null;
try {
td = vec.fpe.checkOnTypes(vd, resourceName, t, n, warnings);
} catch (Exception e) {
rule(errors, "2024-11-14", IssueType.EXCEPTION, stack, false, I18nConstants.VIEWDEFINITION_PATH_ERROR, e.getMessage(), vdesc);
return null;
}
if (td != null) {
for (IssueMessage s : warnings) {
warning(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, false, I18nConstants.VIEWDEFINITION_PATH_WARNING, s.getMessage(), vdesc);
}
}
return td;
}
}
return null;
}
private boolean checkConstant(ValidationContext hostContext, List<ValidationMessage> errors, NodeStack stack, Element constant) {
String name = constant.getNamedChildValue("name");
warning(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, isValidName(name), I18nConstants.VIEWDEFINITION_NAME_INVALID, "constant", name);
return true;
}
private boolean checkWhere(ValidationContext hostContext, List<ValidationMessage> errors, Element vd, NodeStack stack, Element where,
String resourceName, VersionEvaluationContext vec, String vdesc, boolean first) {
boolean ok = true;
String expr = where.getNamedChildValue("path");
if (expr != null) {
ExpressionNode n = getParsedExpression(where, vec.fpe, expr, errors, stack, UserDataNames.db_path);
if (n != null) {
List<String> types = new ArrayList<>();
List<IssueMessage> warnings = new ArrayList<>();
types.add(resourceName);
TypeDetails td = null;
try {
td = vec.fpe.checkOnTypes(vd, resourceName, types, n, warnings);}
catch (Exception e) {
rule(errors, "2024-11-14", IssueType.EXCEPTION, stack, false, I18nConstants.VIEWDEFINITION_PATH_ERROR, e.getMessage(), vdesc);
ok = false;
}
if (td != null) {
if (td.getCollectionStatus() != CollectionStatus.SINGLETON || td.getTypes().size() != 1 || !td.hasType("boolean")) {
rule(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, false, I18nConstants.VIEWDEFINITION_PATH_WRONG_RETURN, expr, td.describe(), vdesc);
ok = false;
} else {
for (IssueMessage s : warnings) {
warning(errors, "2024-11-14", IssueType.BUSINESSRULE, stack, false, I18nConstants.VIEWDEFINITION_PATH_WARNING, s.getMessage(), vdesc);
}
}
}
}
}
return ok;
}
private ExpressionNode getParsedExpression(Element focus, FHIRPathEngine fpe, String expr, List<ValidationMessage> errors, NodeStack stack, String udName) {
if (focus.hasUserData(UserDataNames.db_path)) {
return (ExpressionNode) focus.getUserData(udName);
}
ExpressionNode n = null;
try {
n = fpe.parse(expr);
} catch (Exception e) {
rule(errors, "2024-11-14", IssueType.EXCEPTION, stack, false, I18nConstants.VIEWDEFINITION_PATH_ERROR, e.getMessage(), "");
}
focus.setUserData(udName, n);
return n;
}
private boolean isValidName(String name) {
boolean first = true;
for (char c : name.toCharArray()) {
if (!(Character.isAlphabetic(c) || Character.isDigit(c) || (!first && c == '_'))) {
return false;
}
first = false;
}
return true;
}
}

View File

@ -42,6 +42,7 @@ import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
@ -54,8 +55,8 @@ public class ProfileValidator extends BaseValidator {
private boolean allowDoubleQuotesInFHIRPath = false;
private FHIRPathEngine fpe;
public ProfileValidator(IWorkerContext context, XVerExtensionManager xverManager) {
super(context, xverManager, false);
public ProfileValidator(IWorkerContext context, XVerExtensionManager xverManager, ValidatorSession session) {
super(context, xverManager, false, session);
fpe = new FHIRPathEngine(context);
fpe.setAllowDoubleQuotes(allowDoubleQuotesInFHIRPath);
}

View File

@ -187,7 +187,7 @@ public class R4R5MapTester implements IValidatorResourceFetcher {
loadPackage("hl7.fhir.r4.core#4.0.1", false);
loadPackage("hl7.fhir.r4b.core#4.3.0", false);
validator = new InstanceValidator(context, null, null);
validator = new InstanceValidator(context, null, null, null);
validator.setSuppressLoincSnomedMessages(true);
validator.setResourceIdRule(IdStatus.REQUIRED);
validator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);

View File

@ -37,7 +37,7 @@ class InstanceValidatorTests {
IWorkerContext context = mock(IWorkerContext.class);
when(context.getLocale()).thenReturn(Locale.KOREA);
when(context.getVersion()).thenReturn("5.0.1");
InstanceValidator instanceValidator = new InstanceValidator(context, null, null);
InstanceValidator instanceValidator = new InstanceValidator(context, null, null, null);
when(context.validateCode((ValidationOptions) any(ValidationOptions.class), (CodeableConcept) any(CodeableConcept.class), (ValueSet)any(ValueSet.class))).thenReturn(new ValidationResult(ValidationMessage.IssueSeverity.NULL, "Blah!", Collections.emptyList()));

View File

@ -11,6 +11,7 @@ import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.r5.utils.OperationOutcomeUtilities;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.FhirPublication;
import org.hl7.fhir.utilities.settings.FhirSettings;
@ -89,6 +90,7 @@ public class ValidationEngineTests {
} catch (Exception e) {
e.printStackTrace();
System.err.println("Thread " + index + " failed");
outcomes[index] = OperationOutcomeUtilities.outcomeFromTextError(e.getMessage());
}
});
t.start();