use of org.hl7.fhir.r4.model.UriType in project org.hl7.fhir.core by hapifhir.
the class ValueSetExpanderSimple method includeCodes.
private void includeCodes(ConceptSetComponent inc, List<ValueSetExpansionParameterComponent> params, Parameters expParams, boolean heirarchical) throws ETooCostly, FileNotFoundException, IOException, FHIRException {
inc.checkNoModifiers("Compose.include", "expanding");
List<ValueSet> imports = new ArrayList<ValueSet>();
for (UriType imp : inc.getValueSet()) {
imports.add(importValueSet(imp.getValue(), params, expParams));
}
if (!inc.hasSystem()) {
if (// though this is not supposed to be the case
imports.isEmpty())
return;
ValueSet base = imports.get(0);
imports.remove(0);
base.checkNoModifiers("Imported ValueSet", "expanding");
copyImportContains(base.getExpansion().getContains(), null, expParams, imports);
} else {
CodeSystem cs = context.fetchCodeSystem(inc.getSystem());
if ((cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE)) {
doServerIncludeCodes(inc, heirarchical, params, imports, expParams);
} else {
doInternalIncludeCodes(inc, params, expParams, imports, cs);
}
}
}
use of org.hl7.fhir.r4.model.UriType in project org.hl7.fhir.core by hapifhir.
the class ValueSetCheckerSimple method inComponent.
private boolean inComponent(ConceptSetComponent vsi, String system, String code, boolean only) throws FHIRException {
for (UriType uri : vsi.getValueSet()) {
if (inImport(uri.getValue(), system, code))
return true;
}
if (!vsi.hasSystem())
return false;
if (only && system == null) {
// whether we know the system or not, we'll accept the stated codes at face value
for (ConceptReferenceComponent cc : vsi.getConcept()) if (cc.getCode().equals(code))
return true;
}
if (!system.equals(vsi.getSystem()))
return false;
if (vsi.hasFilter()) {
boolean ok = true;
for (ConceptSetFilterComponent f : vsi.getFilter()) if (!codeInFilter(system, f, code)) {
ok = false;
break;
}
if (ok)
return true;
}
CodeSystem def = context.fetchCodeSystem(system);
if (def.getContent() != CodeSystemContentMode.COMPLETE)
throw new FHIRException("Unable to resolve system " + vsi.getSystem() + " - system is not complete");
List<ConceptDefinitionComponent> list = def.getConcept();
boolean ok = validateCodeInConceptList(code, def, list);
if (ok && vsi.hasConcept()) {
for (ConceptReferenceComponent cc : vsi.getConcept()) if (cc.getCode().equals(code))
return true;
return false;
} else
return ok;
}
use of org.hl7.fhir.r4.model.UriType in project org.hl7.fhir.core by hapifhir.
the class TerminologyCache method getIncSummary.
private String getIncSummary(ConceptSetComponent cc) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (UriType vs : cc.getValueSet()) b.append(vs.asStringValue());
String vsd = b.length() > 0 ? " where the codes are in the value sets (" + b.toString() + ")" : "";
String system = cc.getSystem();
if (cc.hasConcept())
return Integer.toString(cc.getConcept().size()) + " codes from " + system + vsd;
if (cc.hasFilter()) {
String s = "";
for (ConceptSetFilterComponent f : cc.getFilter()) {
if (!Utilities.noString(s))
s = s + " & ";
s = s + f.getProperty() + " " + (f.hasOp() ? f.getOp().toCode() : "?") + " " + f.getValue();
}
return "from " + system + " where " + s + vsd;
}
return "All codes from " + system + vsd;
}
use of org.hl7.fhir.r4.model.UriType in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method generateSnapshot.
/**
* Given a base (snapshot) profile structure, and a differential profile, generate a new snapshot profile
*
* @param base - the base structure on which the differential will be applied
* @param differential - the differential to apply to the base
* @param url - where the base has relative urls for profile references, these need to be converted to absolutes by prepending this URL (e.g. the canonical URL)
* @param webUrl - where the base has relative urls in markdown, these need to be converted to absolutes by prepending this URL (this is not the same as the canonical URL)
* @param trimDifferential - if this is true, then the snap short generator will remove any material in the element definitions that is not different to the base
* @return
* @throws FHIRException
* @throws DefinitionException
* @throws Exception
*/
public void generateSnapshot(StructureDefinition base, StructureDefinition derived, String url, String webUrl, String profileName) throws DefinitionException, FHIRException {
if (base == null) {
throw new DefinitionException(context.formatMessage(I18nConstants.NO_BASE_PROFILE_PROVIDED));
}
if (derived == null) {
throw new DefinitionException(context.formatMessage(I18nConstants.NO_DERIVED_STRUCTURE_PROVIDED));
}
checkNotGenerating(base, "Base for generating a snapshot for the profile " + derived.getUrl());
checkNotGenerating(derived, "Focus for generating a snapshot");
if (!base.hasType()) {
throw new DefinitionException(context.formatMessage(I18nConstants.BASE_PROFILE__HAS_NO_TYPE, base.getUrl()));
}
if (!derived.hasType()) {
throw new DefinitionException(context.formatMessage(I18nConstants.DERIVED_PROFILE__HAS_NO_TYPE, derived.getUrl()));
}
if (!derived.hasDerivation()) {
throw new DefinitionException(context.formatMessage(I18nConstants.DERIVED_PROFILE__HAS_NO_DERIVATION_VALUE_AND_SO_CANT_BE_PROCESSED, derived.getUrl()));
}
if (!base.getType().equals(derived.getType()) && derived.getDerivation() == TypeDerivationRule.CONSTRAINT) {
throw new DefinitionException(context.formatMessage(I18nConstants.BASE__DERIVED_PROFILES_HAVE_DIFFERENT_TYPES____VS___, base.getUrl(), base.getType(), derived.getUrl(), derived.getType()));
}
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);
snapshotStack.add(derived.getUrl());
try {
if (!Utilities.noString(webUrl) && !webUrl.endsWith("/"))
webUrl = webUrl + '/';
if (defWebRoot == null)
defWebRoot = webUrl;
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
try {
checkDifferential(derived.getDifferential().getElement(), typeName(derived.getType()), derived.getUrl());
checkDifferentialBaseType(derived);
// so we have two lists - the base list, and the differential list
// the differential list is only allowed to include things that are in the base list, but
// is allowed to include them multiple times - thereby slicing them
// our approach is to walk through the base list, and see whether the differential
// says anything about them.
int baseCursor = 0;
// we need a diff cursor because we can only look ahead, in the bound scoped by longer paths
int diffCursor = 0;
for (ElementDefinition e : derived.getDifferential().getElement()) e.clearUserData(GENERATED_IN_SNAPSHOT);
// we actually delegate the work to a subroutine so we can re-enter it with a different cursors
// we make a copy here because we're sometimes going to hack the differential while processing it. Have to migrate user data back afterwards
StructureDefinitionDifferentialComponent diff = cloneDiff(derived.getDifferential());
StructureDefinitionSnapshotComponent baseSnapshot = base.getSnapshot();
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
String derivedType = derived.getType();
if (StructureDefinitionKind.LOGICAL.equals(derived.getKind()) && derived.getType().contains("/")) {
derivedType = derivedType.substring(derivedType.lastIndexOf("/") + 1);
}
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
}
// if (derived.getId().equals("2.16.840.1.113883.10.20.22.2.1.1")) {
// debug = true;
// }
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size() - 1, derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size() - 1 : -1, url, webUrl, derived.present(), null, null, false, base.getUrl(), null, false, null, null, new ArrayList<ElementRedirection>(), base);
checkGroupConstraints(derived);
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
for (ElementDefinition e : diff.getElement()) {
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
ElementDefinition outcome = updateURLs(url, webUrl, e.copy());
e.setUserData(GENERATED_IN_SNAPSHOT, outcome);
derived.getSnapshot().addElement(outcome);
}
}
}
if (derived.getKind() != StructureDefinitionKind.LOGICAL && !derived.getSnapshot().getElementFirstRep().getType().isEmpty())
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_SNAPSHOT_ELEMENT_FOR__IN__FROM_, derived.getSnapshot().getElementFirstRep().getPath(), derived.getUrl(), base.getUrl()));
updateMaps(base, derived);
setIds(derived, false);
if (debug) {
System.out.println("Differential: ");
for (ElementDefinition ed : derived.getDifferential().getElement()) System.out.println(" " + ed.getId() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
System.out.println("Snapshot: ");
for (ElementDefinition ed : derived.getSnapshot().getElement()) System.out.println(" " + ed.getId() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
}
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
// Check that all differential elements have a corresponding snapshot element
int ce = 0;
for (ElementDefinition e : diff.getElement()) {
if (!e.hasUserData("diff-source"))
throw new Error(context.formatMessage(I18nConstants.UNXPECTED_INTERNAL_CONDITION__NO_SOURCE_ON_DIFF_ELEMENT));
else {
if (e.hasUserData(DERIVATION_EQUALS))
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_EQUALS, e.getUserData(DERIVATION_EQUALS));
if (e.hasUserData(DERIVATION_POINTER))
((Base) e.getUserData("diff-source")).setUserData(DERIVATION_POINTER, e.getUserData(DERIVATION_POINTER));
}
if (!e.hasUserData(GENERATED_IN_SNAPSHOT)) {
b.append(e.hasId() ? "id: " + e.getId() : "path: " + e.getPath());
ce++;
if (e.hasId()) {
String msg = "No match found in the generated snapshot: check that the path and definitions are legal in the differential (including order)";
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url + "#" + e.getId(), msg, ValidationMessage.IssueSeverity.ERROR));
}
}
}
if (!Utilities.noString(b.toString())) {
String msg = "The profile " + derived.getUrl() + " has " + ce + " " + Utilities.pluralize("element", ce) + " in the differential (" + b.toString() + ") that don't have a matching element in the snapshot: check that the path and definitions are legal in the differential (including order)";
System.out.println("Error in snapshot generation: " + msg);
if (!debug) {
System.out.println("Differential: ");
for (ElementDefinition ed : derived.getDifferential().getElement()) System.out.println(" " + ed.getId() + " = " + ed.getPath() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
System.out.println("Snapshot: ");
for (ElementDefinition ed : derived.getSnapshot().getElement()) System.out.println(" " + ed.getId() + " = " + ed.getPath() + " : " + typeSummaryWithProfile(ed) + "[" + ed.getMin() + ".." + ed.getMax() + "]" + sliceSummary(ed) + " " + constraintSummary(ed));
}
if (exception)
throw new DefinitionException(msg);
else
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url, msg, ValidationMessage.IssueSeverity.ERROR));
}
// hack around a problem in R4 definitions (somewhere?)
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
for (ElementDefinitionMappingComponent mm : ed.getMapping()) {
if (mm.hasMap()) {
mm.setMap(mm.getMap().trim());
}
}
for (ElementDefinitionConstraintComponent s : ed.getConstraint()) {
if (s.hasSource()) {
String ref = s.getSource();
if (!Utilities.isAbsoluteUrl(ref)) {
if (ref.contains(".")) {
s.setSource("http://hl7.org/fhir/StructureDefinition/" + ref.substring(0, ref.indexOf(".")) + "#" + ref);
} else {
s.setSource("http://hl7.org/fhir/StructureDefinition/" + ref);
}
}
}
}
}
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
if (!ed.hasBase()) {
ed.getBase().setPath(ed.getPath()).setMin(ed.getMin()).setMax(ed.getMax());
}
}
}
// last, check for wrong profiles or target profiles
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
for (TypeRefComponent t : ed.getType()) {
for (UriType u : t.getProfile()) {
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
if (sd == null) {
if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) {
sd = xver.makeDefinition(u.getValue());
}
}
if (sd == null) {
if (messages != null) {
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url + "#" + ed.getId(), "The type of profile " + u.getValue() + " cannot be checked as the profile is not known", IssueSeverity.WARNING));
}
} else {
String wt = t.getWorkingCode();
if (ed.getPath().equals("Bundle.entry.response.outcome")) {
wt = "OperationOutcome";
}
if (!sd.getType().equals(wt)) {
boolean ok = isCompatibleType(wt, sd);
if (!ok) {
String smsg = "The profile " + u.getValue() + " has type " + sd.getType() + " which is not consistent with the stated type " + wt;
if (exception)
throw new DefinitionException(smsg);
else
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.VALUE, url + "#" + ed.getId(), smsg, IssueSeverity.ERROR));
}
}
}
}
}
}
} 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");
throw e;
}
} finally {
derived.clearUserData("profileutils.snapshot.generating");
snapshotStack.remove(derived.getUrl());
}
}
use of org.hl7.fhir.r4.model.UriType in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method generateExtensionTable.
public XhtmlNode generateExtensionTable(String defFile, StructureDefinition ed, String imageFolder, boolean inlineGraphics, boolean full, String corePath, String imagePath, Set<String> outputTracker, RenderingContext rc) throws IOException, FHIRException {
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(imageFolder, inlineGraphics, true);
gen.setTranslator(getTranslator());
TableModel model = gen.initNormalTable(corePath, false, true, ed.getId() + (full ? "f" : "n"), true);
boolean deep = false;
String m = "";
boolean vdeep = false;
if (ed.getSnapshot().getElementFirstRep().getIsModifier())
m = "modifier_";
for (ElementDefinition eld : ed.getSnapshot().getElement()) {
deep = deep || eld.getPath().contains("Extension.extension.");
vdeep = vdeep || eld.getPath().contains("Extension.extension.extension.");
}
Row r = gen.new Row();
model.getRows().add(r);
String en;
if (!full)
en = ed.getName();
else if (ed.getSnapshot().getElement().get(0).getIsModifier())
en = "modifierExtension";
else
en = "extension";
r.getCells().add(gen.new Cell(null, defFile == null ? "" : defFile + "-definitions.html#extension." + ed.getName(), en, null, null));
r.getCells().add(gen.new Cell());
r.getCells().add(gen.new Cell(null, null, describeCardinality(ed.getSnapshot().getElement().get(0), null, new UnusedTracker()), null, null));
ElementDefinition ved = null;
if (full || vdeep) {
r.getCells().add(gen.new Cell("", "", "Extension", null, null));
r.setIcon(deep ? "icon_" + m + "extension_complex.png" : "icon_extension_simple.png", deep ? HierarchicalTableGenerator.TEXT_ICON_EXTENSION_COMPLEX : HierarchicalTableGenerator.TEXT_ICON_EXTENSION_SIMPLE);
List<ElementDefinition> children = getChildren(ed.getSnapshot().getElement(), ed.getSnapshot().getElement().get(0));
for (ElementDefinition child : children) if (!child.getPath().endsWith(".id")) {
List<StructureDefinition> sdl = new ArrayList<>();
sdl.add(ed);
genElement(defFile == null ? "" : defFile + "-definitions.html#extension.", gen, r.getSubRows(), child, ed.getSnapshot().getElement(), sdl, true, defFile, true, full, corePath, imagePath, true, false, false, false, null, false, rc);
}
} else if (deep) {
List<ElementDefinition> children = new ArrayList<ElementDefinition>();
for (ElementDefinition ted : ed.getSnapshot().getElement()) {
if (ted.getPath().equals("Extension.extension"))
children.add(ted);
}
r.getCells().add(gen.new Cell("", "", "Extension", null, null));
r.setIcon("icon_" + m + "extension_complex.png", HierarchicalTableGenerator.TEXT_ICON_EXTENSION_COMPLEX);
for (ElementDefinition c : children) {
ved = getValueFor(ed, c);
ElementDefinition ued = getUrlFor(ed, c);
if (ved != null && ued != null) {
Row r1 = gen.new Row();
r.getSubRows().add(r1);
r1.getCells().add(gen.new Cell(null, defFile == null ? "" : defFile + "-definitions.html#extension." + ed.getName(), ((UriType) ued.getFixed()).getValue(), null, null));
r1.getCells().add(gen.new Cell());
r1.getCells().add(gen.new Cell(null, null, describeCardinality(c, null, new UnusedTracker()), null, null));
genTypes(gen, r1, ved, defFile, ed, corePath, imagePath, false, false);
Cell cell = gen.new Cell();
cell.addMarkdown(c.getDefinition());
r1.getCells().add(cell);
r1.setIcon("icon_" + m + "extension_simple.png", HierarchicalTableGenerator.TEXT_ICON_EXTENSION_SIMPLE);
}
}
} else {
for (ElementDefinition ted : ed.getSnapshot().getElement()) {
if (ted.getPath().startsWith("Extension.value"))
ved = ted;
}
genTypes(gen, r, ved, defFile, ed, corePath, imagePath, false, false);
r.setIcon("icon_" + m + "extension_simple.png", HierarchicalTableGenerator.TEXT_ICON_EXTENSION_SIMPLE);
}
Cell c = gen.new Cell("", "", "URL = " + ed.getUrl(), null, null);
Piece cc = gen.new Piece(null, ed.getName() + ": ", null);
c.addPiece(gen.new Piece("br")).addPiece(cc);
c.addMarkdown(ed.getDescription());
if (!full && !(deep || vdeep) && ved != null && ved.hasBinding()) {
c.addPiece(gen.new Piece("br"));
BindingResolution br = pkp.resolveBinding(ed, ved.getBinding(), ved.getPath());
c.getPieces().add(checkForNoChange(ved.getBinding(), gen.new Piece(null, translate("sd.table", "Binding") + ": ", null).addStyle("font-weight:bold")));
c.getPieces().add(checkForNoChange(ved.getBinding(), gen.new Piece(br.url == null ? null : Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath + br.url, br.display, null)));
if (ved.getBinding().hasStrength()) {
c.getPieces().add(checkForNoChange(ved.getBinding(), gen.new Piece(null, " (", null)));
c.getPieces().add(checkForNoChange(ved.getBinding(), gen.new Piece(corePath + "terminologies.html#" + ved.getBinding().getStrength().toCode(), egt(ved.getBinding().getStrengthElement()), ved.getBinding().getStrength().getDefinition())));
c.getPieces().add(gen.new Piece(null, ")", null));
}
if (ved.getBinding().hasDescription() && MarkDownProcessor.isSimpleMarkdown(ved.getBinding().getDescription())) {
c.getPieces().add(gen.new Piece(null, ": ", null));
c.addMarkdownNoPara(PublicationHacker.fixBindingDescriptions(context, ved.getBinding().getDescriptionElement()).asStringValue());
}
}
c.addPiece(gen.new Piece("br")).addPiece(gen.new Piece(null, describeExtensionContext(ed), null));
r.getCells().add(c);
try {
return gen.generate(model, corePath, 0, outputTracker);
} catch (org.hl7.fhir.exceptions.FHIRException e) {
throw new FHIRException(e.getMessage(), e);
}
}
Aggregations