refactor resource reference resolution to use package dependencies whereever possible
This commit is contained in:
parent
d79ac9ba66
commit
fedfa88ffb
|
@ -483,7 +483,7 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
|||
if (sdFocus.getUrl().equals(sdOther.getUrl()) && sdFocus.getVersion().equals(sdOther.getVersion())) {
|
||||
return true;
|
||||
}
|
||||
sdFocus = ctxt.fetchResource(StructureDefinition.class, sdFocus.getBaseDefinition());
|
||||
sdFocus = ctxt.fetchResource(StructureDefinition.class, sdFocus.getBaseDefinition(), sdFocus);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -60,12 +60,12 @@ public class ComparisonSession {
|
|||
return title;
|
||||
}
|
||||
|
||||
public ResourceComparison compare(String left, String right) throws DefinitionException, FHIRFormatError, IOException {
|
||||
CanonicalResource l = (CanonicalResource) contextLeft.fetchResource(Resource.class, left);
|
||||
public ResourceComparison compare(String left, Resource leftSource, String right, Resource rightSource) throws DefinitionException, FHIRFormatError, IOException {
|
||||
CanonicalResource l = (CanonicalResource) contextLeft.fetchResource(Resource.class, left, leftSource);
|
||||
if (l == null) {
|
||||
throw new DefinitionException("Unable to resolve "+left);
|
||||
}
|
||||
CanonicalResource r = (CanonicalResource) contextRight.fetchResource(Resource.class, right);
|
||||
CanonicalResource r = (CanonicalResource) contextRight.fetchResource(Resource.class, right, rightSource);
|
||||
if (r == null) {
|
||||
throw new DefinitionException("Unable to resolve "+right);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.hl7.fhir.r5.model.Enumeration;
|
|||
import org.hl7.fhir.r5.model.Enumerations.BindingStrength;
|
||||
import org.hl7.fhir.r5.model.IntegerType;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
|
@ -226,7 +227,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
subset.setMin(intersectMin(leftMin, rightMin));
|
||||
subset.setMax(intersectMax(leftMax, rightMax, left.current().getMax(), right.current().getMax()));
|
||||
|
||||
superset.getType().addAll(unionTypes(comp, res, path, left.current().getType(), right.current().getType()));
|
||||
superset.getType().addAll(unionTypes(comp, res, path, left.current().getType(), right.current().getType(), left.getStructure(), right.getStructure()));
|
||||
subset.getType().addAll(intersectTypes(comp, res, subset, path, left.current().getType(), right.current().getType()));
|
||||
rule(comp, res, !subset.getType().isEmpty() || (!left.current().hasType() && !right.current().hasType()), path, "Type Mismatch: "+typeCode(left)+" vs "+typeCode(right));
|
||||
// <fixed[x]><!-- ?? 0..1 * Value must be exactly this --></fixed[x]>
|
||||
|
@ -234,7 +235,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
superset.setMaxLengthElement(unionMaxLength(left.current().getMaxLength(), right.current().getMaxLength()));
|
||||
subset.setMaxLengthElement(intersectMaxLength(left.current().getMaxLength(), right.current().getMaxLength()));
|
||||
if (left.current().hasBinding() || right.current().hasBinding()) {
|
||||
compareBindings(comp, res, subset, superset, path, left.current(), right.current());
|
||||
compareBindings(comp, res, subset, superset, path, left.current(), right.current(), left.getStructure(), right.getStructure());
|
||||
}
|
||||
// note these are backwards
|
||||
superset.getConstraint().addAll(intersectConstraints(path, left.current().getConstraint(), right.current().getConstraint()));
|
||||
|
@ -312,10 +313,10 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
// it's possible that one of these profiles walks into a data type and the other doesn't
|
||||
// if it does, we have to load the children for that data into the profile that doesn't
|
||||
// walk into it
|
||||
if (lc.isEmpty() && !rc.isEmpty() && right.current().getType().size() == 1 && left.hasTypeChildren(right.current().getType().get(0)))
|
||||
lc = left.childrenFromType(right.current().getType().get(0));
|
||||
if (rc.isEmpty() && !lc.isEmpty() && left.current().getType().size() == 1 && right.hasTypeChildren(left.current().getType().get(0)))
|
||||
rc = right.childrenFromType(left.current().getType().get(0));
|
||||
if (lc.isEmpty() && !rc.isEmpty() && right.current().getType().size() == 1 && left.hasTypeChildren(right.current().getType().get(0), left.getStructure()))
|
||||
lc = left.childrenFromType(right.current().getType().get(0), right.getStructure());
|
||||
if (rc.isEmpty() && !lc.isEmpty() && left.current().getType().size() == 1 && right.hasTypeChildren(left.current().getType().get(0), right.getStructure()))
|
||||
rc = right.childrenFromType(left.current().getType().get(0), left.getStructure());
|
||||
|
||||
List<DefinitionNavigator> matchR = new ArrayList<>();
|
||||
for (DefinitionNavigator l : lc) {
|
||||
|
@ -529,16 +530,16 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return Integer.toString(defn.current().getMin())+".."+defn.current().getMax();
|
||||
}
|
||||
|
||||
private Collection<? extends TypeRefComponent> unionTypes(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> left, List<TypeRefComponent> right) throws DefinitionException, IOException, FHIRFormatError {
|
||||
private Collection<? extends TypeRefComponent> unionTypes(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> left, List<TypeRefComponent> right, Resource leftSrc, Resource rightSrc) throws DefinitionException, IOException, FHIRFormatError {
|
||||
List<TypeRefComponent> result = new ArrayList<TypeRefComponent>();
|
||||
for (TypeRefComponent l : left)
|
||||
checkAddTypeUnion(comp, res, path, result, l, session.getContextLeft());
|
||||
checkAddTypeUnion(comp, res, path, result, l, session.getContextLeft(), leftSrc);
|
||||
for (TypeRefComponent r : right)
|
||||
checkAddTypeUnion(comp, res, path, result, r, session.getContextRight());
|
||||
checkAddTypeUnion(comp, res, path, result, r, session.getContextRight(), rightSrc);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> results, TypeRefComponent nw, IWorkerContext ctxt) throws DefinitionException, IOException, FHIRFormatError {
|
||||
private void checkAddTypeUnion(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, List<TypeRefComponent> results, TypeRefComponent nw, IWorkerContext ctxt, Resource nwSource) throws DefinitionException, IOException, FHIRFormatError {
|
||||
boolean pfound = false;
|
||||
boolean tfound = false;
|
||||
nw = nw.copy();
|
||||
|
@ -558,8 +559,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
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());
|
||||
StructureDefinition sdnw = ctxt.fetchResource(StructureDefinition.class, nw.getProfile().get(0).getValue());
|
||||
StructureDefinition sdex = ((IWorkerContext) ex.getUserData("ctxt")).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;
|
||||
|
@ -586,8 +587,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
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());
|
||||
StructureDefinition sdnw = ctxt.fetchResource(StructureDefinition.class, nw.getTargetProfile().get(0).getValue());
|
||||
StructureDefinition sdex = ((IWorkerContext) ex.getUserData("ctxt")).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;
|
||||
|
@ -633,7 +634,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (right.getUrl().equals(sd.getBaseDefinition())) {
|
||||
return true;
|
||||
}
|
||||
sd = sd.hasBaseDefinition() ? ctxt.fetchResource(StructureDefinition.class, sd.getBaseDefinition()) : null;
|
||||
sd = sd.hasBaseDefinition() ? ctxt.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd) : null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -653,8 +654,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
pfound = true;
|
||||
c.setProfile(r.getProfile());
|
||||
} else {
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getProfile().get(0).getValue(), comp.getLeft().getName(), session.getContextLeft());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getProfile().get(0).getValue(), comp.getRight().getName(), session.getContextRight());
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getProfile().get(0).getValue(), comp.getLeft().getName(), session.getContextLeft(), comp.getLeft());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getProfile().get(0).getValue(), comp.getRight().getName(), session.getContextRight(), comp.getRight());
|
||||
if (sdl != null && sdr != null) {
|
||||
if (sdl == sdr) {
|
||||
pfound = true;
|
||||
|
@ -680,8 +681,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
tfound = true;
|
||||
c.setTargetProfile(r.getTargetProfile());
|
||||
} else {
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getTargetProfile().get(0).getValue(), comp.getLeft().getName(), session.getContextLeft());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getTargetProfile().get(0).getValue(), comp.getRight().getName(), session.getContextRight());
|
||||
StructureDefinition sdl = resolveProfile(comp, res, path, l.getTargetProfile().get(0).getValue(), comp.getLeft().getName(), session.getContextLeft(), comp.getLeft());
|
||||
StructureDefinition sdr = resolveProfile(comp, res, path, r.getTargetProfile().get(0).getValue(), comp.getRight().getName(), session.getContextRight(), comp.getRight());
|
||||
if (sdl != null && sdr != null) {
|
||||
if (matches(sdl, sdr)) {
|
||||
tfound = true;
|
||||
|
@ -721,7 +722,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
private boolean compareBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, ElementDefinition subset, ElementDefinition superset, String path, ElementDefinition lDef, ElementDefinition rDef) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private boolean compareBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, ElementDefinition subset, ElementDefinition superset, String path, ElementDefinition lDef, ElementDefinition rDef, Resource leftSrc, Resource rightSrc) throws FHIRFormatError, DefinitionException, IOException {
|
||||
assert(lDef.hasBinding() || rDef.hasBinding());
|
||||
if (!lDef.hasBinding()) {
|
||||
subset.setBinding(rDef.getBinding());
|
||||
|
@ -750,25 +751,25 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (right.getStrength() == BindingStrength.PREFERRED && left.getStrength() == BindingStrength.EXAMPLE && !Base.compareDeep(left.getValueSet(), right.getValueSet(), false)) {
|
||||
vm(IssueSeverity.INFORMATION, "Example/preferred bindings differ at "+path+" using binding from "+comp.getRight().getName(), path, comp.getMessages(), res.getMessages());
|
||||
subset.setBinding(right);
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right));
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right, leftSrc, rightSrc));
|
||||
} else {
|
||||
if ((right.getStrength() != BindingStrength.EXAMPLE || left.getStrength() != BindingStrength.EXAMPLE) && !Base.compareDeep(left.getValueSet(), right.getValueSet(), false) ) {
|
||||
vm(IssueSeverity.INFORMATION, "Example/preferred bindings differ at "+path+" using binding from "+comp.getLeft().getName(), path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
subset.setBinding(left);
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right));
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right, leftSrc, rightSrc));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// if either of them are extensible/required, then it wins
|
||||
if (isPreferredOrExample(left)) {
|
||||
subset.setBinding(right);
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right));
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right, leftSrc, rightSrc));
|
||||
return true;
|
||||
}
|
||||
if (isPreferredOrExample(right)) {
|
||||
subset.setBinding(left);
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right));
|
||||
superset.setBinding(unionBindings(comp, res, path, left, right, leftSrc, rightSrc));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -800,8 +801,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return true;
|
||||
} else {
|
||||
// ok, now we compare the value sets. This may be unresolvable.
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet(), session.getContextLeft());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet(), session.getContextRight());
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet(), leftSrc, session.getContextLeft());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet(), rightSrc, session.getContextRight());
|
||||
if (lvs == null) {
|
||||
vm(IssueSeverity.ERROR, "Unable to resolve left value set "+left.getValueSet().toString()+" at "+path, path, comp.getMessages(), res.getMessages());
|
||||
return true;
|
||||
|
@ -885,8 +886,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return result;
|
||||
}
|
||||
|
||||
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String url, String name, IWorkerContext ctxt) {
|
||||
StructureDefinition sd = ctxt.fetchResource(StructureDefinition.class, url);
|
||||
private StructureDefinition resolveProfile(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String url, String name, IWorkerContext ctxt, Resource urlSource) {
|
||||
StructureDefinition sd = ctxt.fetchResource(StructureDefinition.class, url, urlSource);
|
||||
if (sd == null) {
|
||||
ValidationMessage vm = vmI(IssueSeverity.WARNING, "Unable to resolve profile "+url+" in profile "+name, path);
|
||||
}
|
||||
|
@ -897,7 +898,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return binding.getStrength() == BindingStrength.EXAMPLE || binding.getStrength() == BindingStrength.PREFERRED;
|
||||
}
|
||||
|
||||
private ElementDefinitionBindingComponent unionBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, ElementDefinitionBindingComponent left, ElementDefinitionBindingComponent right) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private ElementDefinitionBindingComponent unionBindings(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, ElementDefinitionBindingComponent left, ElementDefinitionBindingComponent right, Resource leftSrc, Resource rightSrc) throws FHIRFormatError, DefinitionException, IOException {
|
||||
ElementDefinitionBindingComponent union = new ElementDefinitionBindingComponent();
|
||||
if (left.getStrength().compareTo(right.getStrength()) < 0)
|
||||
union.setStrength(left.getStrength());
|
||||
|
@ -907,8 +908,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (Base.compareDeep(left.getValueSet(), right.getValueSet(), false))
|
||||
union.setValueSet(left.getValueSet());
|
||||
else {
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet(), session.getContextLeft());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet(), session.getContextRight());
|
||||
ValueSet lvs = resolveVS(comp.getLeft(), left.getValueSet(), leftSrc, session.getContextLeft());
|
||||
ValueSet rvs = resolveVS(comp.getRight(), right.getValueSet(), rightSrc, session.getContextRight());
|
||||
if (lvs != null && rvs != null) {
|
||||
ValueSetComparison compP = (ValueSetComparison) session.compare(lvs, rvs);
|
||||
if (compP != null) {
|
||||
|
@ -923,10 +924,10 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return union;
|
||||
}
|
||||
|
||||
private ValueSet resolveVS(StructureDefinition ctxtLeft, String vsRef, IWorkerContext ctxt) {
|
||||
private ValueSet resolveVS(StructureDefinition ctxtLeft, String vsRef, Resource src, IWorkerContext ctxt) {
|
||||
if (vsRef == null)
|
||||
return null;
|
||||
return ctxt.fetchResource(ValueSet.class, vsRef);
|
||||
return ctxt.fetchResource(ValueSet.class, vsRef, src);
|
||||
}
|
||||
|
||||
public XhtmlNode renderStructure(ProfileComparison comp, String id, String prefix, String corePath) throws FHIRException, IOException {
|
||||
|
|
|
@ -58,7 +58,6 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
|||
import org.hl7.fhir.r5.conformance.ProfileUtilities.SourcedChildDefinitions;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider.BindingResolution;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
||||
import org.hl7.fhir.r5.elementmodel.Property;
|
||||
|
@ -474,7 +473,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
} else if (element.getContentReference().contains("#")) {
|
||||
// external reference
|
||||
String ref = element.getContentReference();
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ref.substring(0, ref.indexOf("#")));
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ref.substring(0, ref.indexOf("#")), profile);
|
||||
if (sd == null) {
|
||||
throw new DefinitionException("unable to process contentReference '"+element.getContentReference()+"' on element '"+element.getId()+"'");
|
||||
}
|
||||
|
@ -578,7 +577,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return getChildList(profile, e.getContentReference().substring(1), null, diff);
|
||||
} else if (e.getContentReference().contains("#")) {
|
||||
String url = e.getContentReference().substring(0, e.getContentReference().indexOf("#"));
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url, profile);
|
||||
if (sd == null) {
|
||||
throw new DefinitionException("Unable to find Structure "+url);
|
||||
}
|
||||
|
@ -722,7 +721,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// 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);
|
||||
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, derived);
|
||||
checkGroupConstraints(derived);
|
||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||
for (ElementDefinition e : diff.getElement()) {
|
||||
|
@ -824,7 +823,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
for (ElementDefinition ed : derived.getSnapshot().getElement()) {
|
||||
for (TypeRefComponent t : ed.getType()) {
|
||||
for (UriType u : t.getProfile()) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue(), derived);
|
||||
if (sd == null) {
|
||||
if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) {
|
||||
sd = xver.makeDefinition(u.getValue());
|
||||
|
@ -922,7 +921,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
public void checkDifferentialBaseType(StructureDefinition derived) throws Error {
|
||||
if (derived.hasDifferential() && !derived.getDifferential().getElementFirstRep().getPath().contains(".") && !derived.getDifferential().getElementFirstRep().getType().isEmpty()) {
|
||||
if (wantFixDifferentialFirstElementType && typeMatchesAncestor(derived.getDifferential().getElementFirstRep().getType(), derived.getBaseDefinition())) {
|
||||
if (wantFixDifferentialFirstElementType && typeMatchesAncestor(derived.getDifferential().getElementFirstRep().getType(), derived.getBaseDefinition(), derived)) {
|
||||
derived.getDifferential().getElementFirstRep().getType().clear();
|
||||
} else if (derived.getKind() != StructureDefinitionKind.LOGICAL) {
|
||||
throw new Error(context.formatMessage(I18nConstants.TYPE_ON_FIRST_DIFFERENTIAL_ELEMENT));
|
||||
|
@ -930,8 +929,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean typeMatchesAncestor(List<TypeRefComponent> type, String baseDefinition) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, baseDefinition);
|
||||
private boolean typeMatchesAncestor(List<TypeRefComponent> type, String baseDefinition, Resource src) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, baseDefinition, src);
|
||||
return sd != null && type.size() == 1 && sd.getType().equals(type.get(0).getCode());
|
||||
}
|
||||
|
||||
|
@ -1072,7 +1071,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (sd.getUrl().equals(sdb.getUrl())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1179,11 +1178,12 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
/**
|
||||
* @param trimDifferential
|
||||
* @param srcSD
|
||||
* @param derived
|
||||
* @throws DefinitionException, FHIRException
|
||||
* @throws Exception
|
||||
*/
|
||||
private ElementDefinition processPaths(String indent, StructureDefinitionSnapshotComponent result, StructureDefinitionSnapshotComponent base, StructureDefinitionDifferentialComponent differential, int baseCursor, int diffCursor, int baseLimit,
|
||||
int diffLimit, String url, String webUrl, String profileName, String contextPathSrc, String contextPathDst, boolean trimDifferential, String contextName, String resultPathBase, boolean slicingDone, ElementDefinition slicer, String typeSlicingPath, List<ElementRedirection> redirector, StructureDefinition srcSD) throws DefinitionException, FHIRException {
|
||||
int diffLimit, String url, String webUrl, String profileName, String contextPathSrc, String contextPathDst, boolean trimDifferential, String contextName, String resultPathBase, boolean slicingDone, ElementDefinition slicer, String typeSlicingPath, List<ElementRedirection> redirector, StructureDefinition srcSD, StructureDefinition derived) throws DefinitionException, FHIRException {
|
||||
if (debug) {
|
||||
System.out.println(indent+"PP @ "+resultPathBase+" / "+contextPathSrc+" : base = "+baseCursor+" to "+baseLimit+", diff = "+diffCursor+" to "+diffLimit+" (slicing = "+slicingDone+", k "+(redirector == null ? "null" : redirector.toString())+")");
|
||||
}
|
||||
|
@ -1218,7 +1218,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// well, the profile walks into this, so we need to as well
|
||||
// did we implicitly step into a new type?
|
||||
if (baseHasChildren(base, currentBase)) { // not a new type here
|
||||
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor+1, baseLimit);
|
||||
} else {
|
||||
if (outcome.getType().size() == 0 && !outcome.hasContentReference()) {
|
||||
|
@ -1253,27 +1253,27 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
int nbl = nbc;
|
||||
while (nbl < base.getElement().size() && base.getElement().get(nbl).getPath().startsWith(tgt.getElement().getPath()+"."))
|
||||
nbl++;
|
||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), tgt.getSource());
|
||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), tgt.getSource(), derived);
|
||||
} else {
|
||||
int nbc = base.getElement().indexOf(tgt.getElement())+1;
|
||||
int nbl = nbc;
|
||||
while (nbl < base.getElement().size() && base.getElement().get(nbl).getPath().startsWith(tgt.getElement().getPath()+"."))
|
||||
nbl++;
|
||||
System.out.println("Test!");
|
||||
processPaths(indent+" ", result, base, differential, nbc, start, nbl-1, diffCursor-1, url, webUrl, profileName, tgt.getElement().getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
||||
processPaths(indent+" ", result, base, differential, nbc, start, nbl-1, diffCursor-1, url, webUrl, profileName, tgt.getElement().getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD, derived);
|
||||
}
|
||||
} else {
|
||||
StructureDefinition dt = outcome.getType().size() > 1 ? context.fetchTypeDefinition("Element") : getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||
StructureDefinition dt = outcome.getType().size() > 1 ? context.fetchTypeDefinition("Element") : getProfileForDataType(outcome.getType().get(0), webUrl, srcSD);
|
||||
if (dt == null) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), cpath));
|
||||
}
|
||||
contextName = dt.getUrl();
|
||||
if (redirector == null || redirector.isEmpty()) {
|
||||
processPaths(indent+" ", result, dt.getSnapshot(), differential, 1 /* starting again on the data type, but skip the root */, start, dt.getSnapshot().getElement().size()-1,
|
||||
diffCursor-1, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
diffCursor-1, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
} else {
|
||||
processPaths(indent+" ", result, dt.getSnapshot(), differential, 1 /* starting again on the data type, but skip the root */, start, dt.getSnapshot().getElement().size()-1,
|
||||
diffCursor-1, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, currentBase, cpath), srcSD);
|
||||
diffCursor-1, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, currentBase, cpath), srcSD, derived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1294,7 +1294,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
} else if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !"Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode())) {
|
||||
CanonicalType p = diffMatches.get(0).getType().get(0).getProfile().get(0);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue(), derived);
|
||||
if (sd == null && xver != null && xver.matchingUrl(p.getValue())) {
|
||||
switch (xver.status(p.getValue())) {
|
||||
case BadVersion: throw new FHIRException("Reference to invalid version in extension url "+p.getValue());
|
||||
|
@ -1316,7 +1316,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
throw new FHIRException(context.formatMessage(I18nConstants.ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED, sd.getUrl(), "Source for first element"));
|
||||
}
|
||||
} else if (!sd.hasSnapshot()) {
|
||||
StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
if (sdb == null)
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), sd.getUrl()));
|
||||
checkNotGenerating(sdb, "an extension base");
|
||||
|
@ -1362,7 +1362,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
}
|
||||
updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url, srcSD);
|
||||
updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url, srcSD, derived);
|
||||
removeStatusExtensions(outcome);
|
||||
// if (outcome.getPath().endsWith("[x]") && outcome.getType().size() == 1 && !outcome.getType().get(0).getCode().equals("*") && !diffMatches.get(0).hasSlicing()) // if the base profile allows multiple types, but the profile only allows one, rename it
|
||||
// outcome.setPath(outcome.getPath().substring(0, outcome.getPath().length()-3)+Utilities.capitalize(outcome.getType().get(0).getCode()));
|
||||
|
@ -1415,21 +1415,21 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
int nbl = nbc;
|
||||
while (nbl < base.getElement().size() && base.getElement().get(nbl).getPath().startsWith(tgt.getElement().getPath()+"."))
|
||||
nbl++;
|
||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), tgt.getSource());
|
||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), tgt.getSource(), derived);
|
||||
} else {
|
||||
int nbc = base.getElement().indexOf(tgt.getElement())+1;
|
||||
int nbl = nbc;
|
||||
while (nbl < base.getElement().size() && base.getElement().get(nbl).getPath().startsWith(tgt.getElement().getPath()+"."))
|
||||
nbl++;
|
||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD);
|
||||
processPaths(indent+" ", result, base, differential, nbc, start - 1, nbl-1, diffCursor - 1, url, webUrl, profileName, tgt.getElement().getPath(), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirectorStack(redirector, outcome, cpath), srcSD, derived);
|
||||
}
|
||||
} else {
|
||||
StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0), webUrl) : getProfileForDataType("Element");
|
||||
StructureDefinition dt = outcome.getType().size() == 1 ? getProfileForDataType(outcome.getType().get(0), webUrl, derived) : getProfileForDataType("Element");
|
||||
if (dt == null)
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE, diffMatches.isEmpty() ? "??" : diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
||||
contextName = dt.getUrl();
|
||||
processPaths(indent+" ", result, dt.getSnapshot(), differential, 1 /* starting again on the data type, but skip the root */, start, dt.getSnapshot().getElement().size()-1,
|
||||
diffCursor - 1, url, getWebUrl(dt, webUrl, indent), profileName+pathTail(diffMatches, 0), diffMatches.get(0).getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, new ArrayList<ElementRedirection>(), srcSD);
|
||||
diffCursor - 1, url, getWebUrl(dt, webUrl, indent), profileName+pathTail(diffMatches, 0), diffMatches.get(0).getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, new ArrayList<ElementRedirection>(), srcSD, derived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1515,7 +1515,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// ok passed the checks.
|
||||
// copy the root diff, and then process any children it has
|
||||
ElementDefinition e = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst,
|
||||
trimDifferential, contextName, resultPathBase, true, null, null, redirector, srcSD);
|
||||
trimDifferential, contextName, resultPathBase, true, null, null, redirector, srcSD, derived);
|
||||
if (e==null)
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.DID_NOT_FIND_TYPE_ROOT_, diffMatches.get(0).getPath()));
|
||||
// now set up slicing on the e (cause it was wiped by what we called.
|
||||
|
@ -1541,7 +1541,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
ndc = differential.getElement().indexOf(diffMatches.get(i));
|
||||
ndl = findEndOfElement(differential, ndc);
|
||||
ElementDefinition typeSliceElement = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, e, null, redirector, srcSD);
|
||||
ElementDefinition typeSliceElement = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, e, null, redirector, srcSD, derived);
|
||||
if (typeList.size() > start+1) {
|
||||
typeSliceElement.setMin(0);
|
||||
}
|
||||
|
@ -1606,7 +1606,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
int ndc = differential.getElement().indexOf(diffMatches.get(0));
|
||||
int ndl = findEndOfElement(differential, ndc);
|
||||
ElementDefinition e = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst,
|
||||
trimDifferential, contextName, resultPathBase, true, null, null, redirector, srcSD);
|
||||
trimDifferential, contextName, resultPathBase, true, null, null, redirector, srcSD, derived);
|
||||
if (e==null)
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.DID_NOT_FIND_SINGLE_SLICE_, diffMatches.get(0).getPath()));
|
||||
e.setSlicing(diffMatches.get(0).getSlicing());
|
||||
|
@ -1629,7 +1629,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
// differential - if the first one in the list has a name, we'll process it. Else we'll treat it as the base definition of the slice.
|
||||
if (!diffMatches.get(0).hasSliceName()) {
|
||||
updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url, srcSD);
|
||||
updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url, srcSD, derived);
|
||||
removeStatusExtensions(outcome);
|
||||
if (!outcome.hasContentReference() && !outcome.hasType()) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.NOT_DONE_YET));
|
||||
|
@ -1638,7 +1638,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (baseHasChildren(base, currentBase)) { // not a new type here
|
||||
throw new Error("This situation is not yet handled (constrain slicing to 1..1 and fix base slice for inline structure - please report issue to grahame@fhir.org along with a test case that reproduces this error (@ "+cpath+" | "+currentBase.getPath()+")");
|
||||
} else {
|
||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl);
|
||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl, srcSD);
|
||||
contextName = dt.getUrl();
|
||||
diffCursor++;
|
||||
start = diffCursor;
|
||||
|
@ -1646,7 +1646,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
diffCursor++;
|
||||
diffCursor--;
|
||||
processPaths(indent+" ", result, dt.getSnapshot(), differential, 1 /* starting again on the data type, but skip the root */, start, dt.getSnapshot().getElement().size()-1,
|
||||
diffCursor, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
diffCursor, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
}
|
||||
}
|
||||
start++;
|
||||
|
@ -1668,7 +1668,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
continue;
|
||||
}*/
|
||||
// now we process the base scope repeatedly for each instance of the item in the differential list
|
||||
processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, slicerElement, null, redirector, srcSD);
|
||||
processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, slicerElement, null, redirector, srcSD, derived);
|
||||
}
|
||||
// ok, done with that - next in the base list
|
||||
baseCursor = nbl+1;
|
||||
|
@ -1701,10 +1701,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// the profile walks into this, so we need to as well
|
||||
// did we implicitly step into a new type?
|
||||
if (baseHasChildren(base, currentBase)) { // not a new type here
|
||||
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
processPaths(indent+" ", result, base, differential, baseCursor+1, diffCursor, baseLimit, diffLimit, url, webUrl, profileName, contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
baseCursor = indexOfFirstNonChild(base, currentBase, baseCursor, baseLimit);
|
||||
} else {
|
||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl);
|
||||
StructureDefinition dt = getTypeForElement(differential, diffCursor, profileName, diffMatches, outcome, webUrl, srcSD);
|
||||
contextName = dt.getUrl();
|
||||
int start = diffCursor;
|
||||
if (differential.getElement().get(diffCursor).getPath().equals(cpath)) {
|
||||
|
@ -1715,7 +1715,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
if (diffCursor > start) {
|
||||
processPaths(indent+" ", result, dt.getSnapshot(), differential, 1 /* starting again on the data type, but skip the root */, start, dt.getSnapshot().getElement().size()-1,
|
||||
diffCursor-1, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
diffCursor-1, url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
}
|
||||
}
|
||||
baseCursor++;
|
||||
|
@ -1811,7 +1811,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// ok passed the checks.
|
||||
// copy the root diff, and then process any children it has
|
||||
ElementDefinition e = processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst,
|
||||
trimDifferential, contextName, resultPathBase, true, null, cpath, redirector, srcSD);
|
||||
trimDifferential, contextName, resultPathBase, true, null, cpath, redirector, srcSD, derived);
|
||||
if (e==null)
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.DID_NOT_FIND_TYPE_ROOT_, diffMatches.get(0).getPath()));
|
||||
// now set up slicing on the e (cause it was wiped by what we called.
|
||||
|
@ -1844,7 +1844,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
sEnd = bs.end;
|
||||
bs.handled = true;
|
||||
}
|
||||
processPaths(indent+" ", result, base, differential, sStart, ndc, sEnd, ndl, url, webUrl, profileName+pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, e, cpath, redirector, srcSD);
|
||||
processPaths(indent+" ", result, base, differential, sStart, ndc, sEnd, ndl, url, webUrl, profileName+pathTail(diffMatches, i), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, e, cpath, redirector, srcSD, derived);
|
||||
}
|
||||
if (elementToRemove != null) {
|
||||
differential.getElement().remove(elementToRemove);
|
||||
|
@ -1863,7 +1863,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// ok we gimme up a fake differential that says nothing, and run that against the slice.
|
||||
StructureDefinitionDifferentialComponent fakeDiff = new StructureDefinitionDifferentialComponent();
|
||||
fakeDiff.getElementFirstRep().setPath(bs.defn.getPath());
|
||||
processPaths(indent+" ", result, base, fakeDiff, bs.start, 0, bs.end, 0, url, webUrl, profileName+tail(bs.defn.getPath()), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, e, cpath, redirector, srcSD);
|
||||
processPaths(indent+" ", result, base, fakeDiff, bs.start, 0, bs.end, 0, url, webUrl, profileName+tail(bs.defn.getPath()), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, true, e, cpath, redirector, srcSD, derived);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1893,7 +1893,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
updateFromBase(outcome, currentBase, srcSD.getUrl());
|
||||
if (diffMatches.get(0).hasSlicing() || !diffMatches.get(0).hasSliceName()) {
|
||||
updateFromSlicing(outcome.getSlicing(), diffMatches.get(0).getSlicing());
|
||||
updateFromDefinition(outcome, diffMatches.get(0), profileName, closed, url, srcSD); // if there's no slice, we don't want to update the unsliced description
|
||||
updateFromDefinition(outcome, diffMatches.get(0), profileName, closed, url, srcSD, derived); // if there's no slice, we don't want to update the unsliced description
|
||||
removeStatusExtensions(outcome);
|
||||
} else if (!diffMatches.get(0).hasSliceName()) {
|
||||
diffMatches.get(0).setUserData(GENERATED_IN_SNAPSHOT, outcome); // because of updateFromDefinition isn't called
|
||||
|
@ -1913,7 +1913,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (base.getElement().get(baseCursor).getType().size() != 1) {
|
||||
throw new Error(context.formatMessage(I18nConstants.DIFFERENTIAL_WALKS_INTO____BUT_THE_BASE_DOES_NOT_AND_THERE_IS_NOT_A_SINGLE_FIXED_TYPE_THE_TYPE_IS__THIS_IS_NOT_HANDLED_YET, cpath, diffMatches.get(0).toString(), base.getElement().get(baseCursor).typeSummary()));
|
||||
}
|
||||
StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0), webUrl);
|
||||
StructureDefinition dt = getProfileForDataType(base.getElement().get(baseCursor).getType().get(0), webUrl, srcSD);
|
||||
if (dt == null) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath()));
|
||||
}
|
||||
|
@ -1921,10 +1921,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), cpath+"."))
|
||||
diffCursor++;
|
||||
processPaths(indent+" ", result, dt.getSnapshot(), differential, 1, ndc, dt.getSnapshot().getElement().size()-1, ndl,
|
||||
url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
url, getWebUrl(dt, webUrl, indent), profileName, cpath, outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
} else {
|
||||
processPaths(indent+" ", result, base, differential, baseCursor+1, ndc, nbl, ndl,
|
||||
url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, null, srcSD);
|
||||
url, webUrl, profileName+pathTail(diffMatches, 0), contextPathSrc, contextPathDst, trimDifferential, contextName, resultPathBase, false, null, null, null, srcSD, derived);
|
||||
}
|
||||
// throw new Error("Not done yet");
|
||||
// } else if (currentBase.getType().get(0).getCode().equals("BackboneElement") && diffMatches.size() > 0 && diffMatches.get(0).hasSliceName()) {
|
||||
|
@ -1955,7 +1955,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
int ndc = differential.getElement().indexOf(diffMatches.get(diffpos));
|
||||
int ndl = findEndOfElement(differential, ndc);
|
||||
// now we process the base scope repeatedly for each instance of the item in the differential list
|
||||
processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, diffpos), contextPathSrc, contextPathDst, closed, contextName, resultPathBase, true, null, null, redirector, srcSD);
|
||||
processPaths(indent+" ", result, base, differential, baseCursor, ndc, nbl, ndl, url, webUrl, profileName+pathTail(diffMatches, diffpos), contextPathSrc, contextPathDst, closed, contextName, resultPathBase, true, null, null, redirector, srcSD, derived);
|
||||
// ok, done with that - now set the cursors for if this is the end
|
||||
baseCursor = nbl;
|
||||
diffCursor = ndl+1;
|
||||
|
@ -2006,7 +2006,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!outcome.getPath().startsWith(resultPathBase))
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.ADDING_WRONG_PATH));
|
||||
result.getElement().add(outcome);
|
||||
updateFromDefinition(outcome, diffItem, profileName, trimDifferential, url, srcSD);
|
||||
updateFromDefinition(outcome, diffItem, profileName, trimDifferential, url, srcSD, derived);
|
||||
removeStatusExtensions(outcome);
|
||||
// --- LM Added this
|
||||
diffCursor = differential.getElement().indexOf(diffItem)+1;
|
||||
|
@ -2028,10 +2028,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath()+"."))
|
||||
diffCursor++;
|
||||
processPaths(indent+" ", result, base, differential, baseStart, start-1, baseMax-1,
|
||||
diffCursor - 1, url, webUrl, profileName+pathTail(diffMatches, 0), base.getElement().get(0).getPath(), base.getElement().get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
diffCursor - 1, url, webUrl, profileName+pathTail(diffMatches, 0), base.getElement().get(0).getPath(), base.getElement().get(0).getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
|
||||
} else {
|
||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl, derived);
|
||||
// if (t.getCode().equals("Extension") && t.hasProfile() && !t.getProfile().contains(":")) {
|
||||
// lloydfix dt =
|
||||
// }
|
||||
|
@ -2042,7 +2042,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath()+"."))
|
||||
diffCursor++;
|
||||
processPaths(indent+" ", result, dt.getSnapshot(), differential, 1 /* starting again on the data type, but skip the root */, start-1, dt.getSnapshot().getElement().size()-1,
|
||||
diffCursor - 1, url, getWebUrl(dt, webUrl, indent), profileName+pathTail(diffMatches, 0), diffMatches.get(0).getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD);
|
||||
diffCursor - 1, url, getWebUrl(dt, webUrl, indent), profileName+pathTail(diffMatches, 0), diffMatches.get(0).getPath(), outcome.getPath(), trimDifferential, contextName, resultPathBase, false, null, null, redirector, srcSD, derived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2092,7 +2092,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
public StructureDefinition getTypeForElement(StructureDefinitionDifferentialComponent differential, int diffCursor, String profileName,
|
||||
List<ElementDefinition> diffMatches, ElementDefinition outcome, String webUrl) {
|
||||
List<ElementDefinition> diffMatches, ElementDefinition outcome, String webUrl, Resource srcSD) {
|
||||
if (outcome.getType().size() == 0) {
|
||||
if (outcome.hasContentReference()) {
|
||||
throw new Error(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_CONTENT_REFERENCE_IN_THIS_CONTEXT, outcome.getContentReference(), outcome.getId(), outcome.getPath()));
|
||||
|
@ -2106,7 +2106,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
throw new DefinitionException(context.formatMessage(I18nConstants._HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_, diffMatches.get(0).getPath(), differential.getElement().get(diffCursor).getPath(), typeCode(outcome.getType()), profileName));
|
||||
}
|
||||
}
|
||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl);
|
||||
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0), webUrl, srcSD);
|
||||
if (dt == null)
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNKNOWN_TYPE__AT_, outcome.getType().get(0), diffMatches.get(0).getPath()));
|
||||
return dt;
|
||||
|
@ -2143,7 +2143,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
}
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2580,10 +2580,10 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return s;
|
||||
}
|
||||
|
||||
private StructureDefinition getProfileForDataType(TypeRefComponent type, String webUrl) {
|
||||
private StructureDefinition getProfileForDataType(TypeRefComponent type, String webUrl, Resource src) {
|
||||
StructureDefinition sd = null;
|
||||
if (type.hasProfile()) {
|
||||
sd = context.fetchResource(StructureDefinition.class, type.getProfile().get(0).getValue());
|
||||
sd = context.fetchResource(StructureDefinition.class, type.getProfile().get(0).getValue(), src);
|
||||
if (sd == null) {
|
||||
if (xver != null && xver.matchingUrl(type.getProfile().get(0).getValue()) && xver.status(type.getProfile().get(0).getValue()) == XVerExtensionStatus.Valid) {
|
||||
sd = xver.makeDefinition(type.getProfile().get(0).getValue());
|
||||
|
@ -2974,7 +2974,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void updateFromDefinition(ElementDefinition dest, ElementDefinition source, String pn, boolean trimDifferential, String purl, StructureDefinition srcSD) throws DefinitionException, FHIRException {
|
||||
private void updateFromDefinition(ElementDefinition dest, ElementDefinition source, String pn, boolean trimDifferential, String purl, StructureDefinition srcSD, StructureDefinition derivedSrc) throws DefinitionException, FHIRException {
|
||||
source.setUserData(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
|
||||
|
@ -2992,9 +2992,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// Before applying changes, apply them to what's in the profile
|
||||
StructureDefinition profile = null;
|
||||
if (base.hasSliceName())
|
||||
profile = base.getType().size() == 1 && base.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, base.getTypeFirstRep().getProfile().get(0).getValue()) : null;
|
||||
profile = base.getType().size() == 1 && base.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, base.getTypeFirstRep().getProfile().get(0).getValue(), srcSD) : null;
|
||||
if (profile==null)
|
||||
profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue()) : null;
|
||||
profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue(), derivedSrc) : null;
|
||||
if (profile != null) {
|
||||
ElementDefinition e = profile.getSnapshot().getElement().get(0);
|
||||
String webroot = profile.getUserString("webroot");
|
||||
|
@ -3208,8 +3208,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+derived.getPath(), "illegal attempt to change the binding on "+derived.getPath()+" from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode(), ValidationMessage.IssueSeverity.ERROR));
|
||||
// throw new DefinitionException("StructureDefinition "+pn+" at "+derived.getPath()+": illegal attempt to change a binding from "+base.getBinding().getStrength().toCode()+" to "+derived.getBinding().getStrength().toCode());
|
||||
else if (base.hasBinding() && derived.hasBinding() && base.getBinding().getStrength() == BindingStrength.REQUIRED && base.getBinding().hasValueSet() && derived.getBinding().hasValueSet()) {
|
||||
ValueSet baseVs = context.fetchResource(ValueSet.class, base.getBinding().getValueSet());
|
||||
ValueSet contextVs = context.fetchResource(ValueSet.class, derived.getBinding().getValueSet());
|
||||
ValueSet baseVs = context.fetchResource(ValueSet.class, base.getBinding().getValueSet(), srcSD);
|
||||
ValueSet contextVs = context.fetchResource(ValueSet.class, derived.getBinding().getValueSet(), derivedSrc);
|
||||
if (baseVs == null) {
|
||||
messages.add(new ValidationMessage(Source.ProfileValidator, ValidationMessage.IssueType.BUSINESSRULE, pn+"."+base.getPath(), "Binding "+base.getBinding().getValueSet()+" could not be located", ValidationMessage.IssueSeverity.WARNING));
|
||||
} else if (contextVs == null) {
|
||||
|
@ -3266,7 +3266,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!Base.compareDeep(derived.getType(), base.getType(), false)) {
|
||||
if (base.hasType()) {
|
||||
for (TypeRefComponent ts : derived.getType()) {
|
||||
checkTypeDerivation(purl, srcSD, base, derived, ts);
|
||||
checkTypeDerivation(purl, derivedSrc, base, derived, ts);
|
||||
}
|
||||
}
|
||||
base.getType().clear();
|
||||
|
@ -3338,7 +3338,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
// finally, we copy any extensions from source to dest
|
||||
for (Extension ex : derived.getExtension()) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ex.getUrl());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ex.getUrl(), derivedSrc);
|
||||
if (sd == null || sd.getSnapshot() == null || sd.getSnapshot().getElementFirstRep().getMax().equals("1")) {
|
||||
ToolingExtensions.removeExtension(dest, ex.getUrl());
|
||||
}
|
||||
|
@ -3369,7 +3369,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
StructureDefinition sdb = context.fetchTypeDefinition(t);
|
||||
while (sdb != null && !ok) {
|
||||
ok = sdb.getType().equals(sdt.getType());
|
||||
sdb = context.fetchResource(StructureDefinition.class, sdb.getBaseDefinition());
|
||||
sdb = context.fetchResource(StructureDefinition.class, sdb.getBaseDefinition(), sdb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3616,7 +3616,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
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, "");
|
||||
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, "", ed);
|
||||
}
|
||||
} else if (deep) {
|
||||
List<ElementDefinition> children = new ArrayList<ElementDefinition>();
|
||||
|
@ -3729,7 +3729,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
List<TypeRefComponent> types = e.getType();
|
||||
if (!e.hasType()) {
|
||||
if (root) { // we'll use base instead of types then
|
||||
StructureDefinition bsd = profile == null ? null : context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
|
||||
StructureDefinition bsd = profile == null ? null : context.fetchResource(StructureDefinition.class, profile.getBaseDefinition(), profile);
|
||||
if (bsd != null) {
|
||||
if (bsd.hasUserData("path")) {
|
||||
c.getPieces().add(gen.new Piece(Utilities.isAbsoluteUrl(bsd.getUserString("path")) ? bsd.getUserString("path") : imagePath +bsd.getUserString("path"), bsd.getName(), null));
|
||||
|
@ -3780,7 +3780,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
tfirst = false;
|
||||
else
|
||||
c.addPiece(gen.new Piece(null, " | ", null));
|
||||
genTargetLink(gen, profileBaseFileName, corePath, c, t, u.getValue());
|
||||
genTargetLink(gen, profileBaseFileName, corePath, c, t, u.getValue(), null);
|
||||
if (!mustSupportMode && isMustSupport(u) && e.getMustSupport()) {
|
||||
c.addPiece(gen.new Piece(null, " ", null));
|
||||
c.addStyledText(translate("sd.table", "This target must be supported"), "S", "white", "red", null, false);
|
||||
|
@ -3863,9 +3863,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return Utilities.isAbsoluteUrl(url) ? url : prefix + url;
|
||||
}
|
||||
|
||||
public void genTargetLink(HierarchicalTableGenerator gen, String profileBaseFileName, String corePath, Cell c, TypeRefComponent t, String u) {
|
||||
public void genTargetLink(HierarchicalTableGenerator gen, String profileBaseFileName, String corePath, Cell c, TypeRefComponent t, String u, Resource src) {
|
||||
if (u.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u, src);
|
||||
if (sd != null) {
|
||||
String disp = sd.hasTitle() ? sd.getTitle() : sd.getName();
|
||||
c.addPiece(checkForNoChange(t, gen.new Piece(checkPrepend(corePath, sd.getUserString("path")), disp, null)));
|
||||
|
@ -3874,7 +3874,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.addPiece(checkForNoChange(t, gen.new Piece(pkp.getLinkFor(corePath, rn), rn, null)));
|
||||
}
|
||||
} else if (Utilities.isAbsoluteUrl(u)) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, u, src);
|
||||
if (sd != null && pkp != null) {
|
||||
String disp = sd.hasTitle() ? sd.getTitle() : sd.getName();
|
||||
String ref = pkp.getLinkForProfile(null, sd.getUrl());
|
||||
|
@ -3949,7 +3949,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
url = source.getUrl();
|
||||
}
|
||||
if (!url.equals(source.getUrl())) {
|
||||
source = context.fetchResource(StructureDefinition.class, url);
|
||||
source = context.fetchResource(StructureDefinition.class, url, source);
|
||||
if (source == null) {
|
||||
throw new FHIRException("Unable to resolve StructureDefinition "+url+" resolving content reference "+contentReference);
|
||||
}
|
||||
|
@ -3973,7 +3973,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
String url = contentReference.substring(0, contentReference.indexOf("#"));
|
||||
contentReference = contentReference.substring(contentReference.indexOf("#"));
|
||||
if (!url.equals(source.getUrl())){
|
||||
source = context.fetchResource(StructureDefinition.class, url);
|
||||
source = context.fetchResource(StructureDefinition.class, url, source);
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -4148,7 +4148,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
profiles.add(profile);
|
||||
keyRows.clear();
|
||||
|
||||
genElement(defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null, mustSupport, rc, anchorPrefix);
|
||||
genElement(defFile == null ? null : defFile+"#", gen, model.getRows(), list.get(0), list, profiles, diff, profileBaseFileName, null, snapshot, corePath, imagePath, true, logicalModel, profile.getDerivation() == TypeDerivationRule.CONSTRAINT && usesMustSupport(list), allInvariants, null, mustSupport, rc, anchorPrefix, profile);
|
||||
try {
|
||||
return gen.generate(model, imagePath, 0, outputTracker);
|
||||
} catch (org.hl7.fhir.exceptions.FHIRException e) {
|
||||
|
@ -4244,7 +4244,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
|
||||
private Row genElement(String defPath, HierarchicalTableGenerator gen, List<Row> rows, ElementDefinition element, List<ElementDefinition> all, List<StructureDefinition> profiles, boolean showMissing, String profileBaseFileName, Boolean extensions,
|
||||
boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow, boolean mustSupport, RenderingContext rc, String anchorPrefix) throws IOException, FHIRException {
|
||||
boolean snapshot, String corePath, String imagePath, boolean root, boolean logicalModel, boolean isConstraintMode, boolean allInvariants, Row slicingRow, boolean mustSupport, RenderingContext rc, String anchorPrefix, Resource srcSD) throws IOException, FHIRException {
|
||||
Row originalRow = slicingRow;
|
||||
StructureDefinition profile = profiles == null ? null : profiles.get(profiles.size()-1);
|
||||
Row typesRow = null;
|
||||
|
@ -4393,7 +4393,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
Row childRow = chooseChildRowByGroup(gen, currRow, groups, child, element, isConstraintMode);
|
||||
|
||||
if (logicalModel || !child.getPath().endsWith(".id") || (child.getPath().endsWith(".id") && (profile != null) && (profile.getDerivation() == TypeDerivationRule.CONSTRAINT))) {
|
||||
currRow = genElement(defPath, gen, childRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport, rc, anchorPrefix);
|
||||
currRow = genElement(defPath, gen, childRow.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, isExtension, snapshot, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants, currRow, mustSupport, rc, anchorPrefix, srcSD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4403,7 +4403,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
// genElement(defPath, gen, row.getSubRows(), child, all, profiles, showMissing, profileBaseFileName, true, false, corePath, imagePath, false, logicalModel, isConstraintMode, allInvariants);
|
||||
}
|
||||
if (typesRow != null && !element.prohibited()) {
|
||||
makeChoiceRows(typesRow.getSubRows(), element, gen, corePath, profileBaseFileName, mustSupport);
|
||||
makeChoiceRows(typesRow.getSubRows(), element, gen, corePath, profileBaseFileName, mustSupport, srcSD);
|
||||
}
|
||||
}
|
||||
return slicingRow;
|
||||
|
@ -4600,7 +4600,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return key != null && key.startsWith("ele-") || key.startsWith("res-") || key.startsWith("ext-") || key.startsWith("dom-") || key.startsWith("dr-");
|
||||
}
|
||||
|
||||
private void makeChoiceRows(List<Row> subRows, ElementDefinition element, HierarchicalTableGenerator gen, String corePath, String profileBaseFileName, boolean mustSupportMode) {
|
||||
private void makeChoiceRows(List<Row> subRows, ElementDefinition element, HierarchicalTableGenerator gen, String corePath, String profileBaseFileName, boolean mustSupportMode, Resource src) {
|
||||
// create a child for each choice
|
||||
for (TypeRefComponent tr : element.getType()) {
|
||||
if (!mustSupportMode || allTypesMustSupport(element) || isMustSupport(tr)) {
|
||||
|
@ -4629,7 +4629,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!mustSupportMode || allProfilesMustSupport(tr.getTargetProfile()) || isMustSupport(rt)) {
|
||||
if (!first)
|
||||
c.getPieces().add(gen.new Piece(null, " | ", null));
|
||||
genTargetLink(gen, profileBaseFileName, corePath, c, tr, rt.getValue());
|
||||
genTargetLink(gen, profileBaseFileName, corePath, c, tr, rt.getValue(), src);
|
||||
if (!mustSupportMode && isMustSupport(rt) && element.getMustSupport()) {
|
||||
c.addPiece(gen.new Piece(null, " ", null));
|
||||
c.addStyledText(translate("sd.table", "This target must be supported"), "S", "white", "red", null, false);
|
||||
|
@ -4680,7 +4680,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
for (CanonicalType pt : tr.getProfile()) {
|
||||
if (!mustSupportMode || allProfilesMustSupport(tr.getProfile()) || isMustSupport(pt)) {
|
||||
if (first) first = false; else typeCell.addPiece(gen.new Piece(null, " | ", null));
|
||||
StructureDefinition psd = context.fetchResource(StructureDefinition.class, pt.getValue());
|
||||
StructureDefinition psd = context.fetchResource(StructureDefinition.class, pt.getValue(), src);
|
||||
if (psd == null)
|
||||
typeCell.addPiece(gen.new Piece(null, "?gen-e2?", null));
|
||||
else
|
||||
|
@ -4901,7 +4901,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!c.getPieces().isEmpty())
|
||||
c.addPiece(gen.new Piece("br"));
|
||||
String fullUrl = url.startsWith("#") ? baseURL+url : url;
|
||||
StructureDefinition ed = context.fetchResource(StructureDefinition.class, url);
|
||||
StructureDefinition ed = context.fetchResource(StructureDefinition.class, url, profile);
|
||||
String ref = null;
|
||||
String ref2 = null;
|
||||
String fixedUrl = null;
|
||||
|
@ -5417,7 +5417,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!c.getPieces().isEmpty())
|
||||
c.addPiece(gen.new Piece("br"));
|
||||
String fullUrl = url.startsWith("#") ? baseURL+url : url;
|
||||
StructureDefinition ed = context.fetchResource(StructureDefinition.class, url);
|
||||
StructureDefinition ed = context.fetchResource(StructureDefinition.class, url, profile);
|
||||
String ref = null;
|
||||
if (ed != null) {
|
||||
String p = ed.getUserString("path");
|
||||
|
@ -5661,7 +5661,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
code = url.substring(1);
|
||||
} else if (context != null) {
|
||||
String[] parts = url.split("\\#");
|
||||
profile = context.fetchResource(StructureDefinition.class, parts[0]);
|
||||
profile = context.fetchResource(StructureDefinition.class, parts[0], source);
|
||||
code = parts.length == 1 ? null : parts[1];
|
||||
}
|
||||
if (profile == null)
|
||||
|
@ -6075,7 +6075,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!structure.hasSnapshot())
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.NEEDS_A_SNAPSHOT));
|
||||
|
||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, structure.getBaseDefinition());
|
||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, structure.getBaseDefinition(), structure);
|
||||
|
||||
if (base != null) {
|
||||
SchematronWriter sch = new SchematronWriter(dest, SchematronType.PROFILE, base.getName());
|
||||
|
@ -6479,7 +6479,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
sd.getSnapshot().getElement().add(sd.getDifferential().getElementFirstRep().copy());
|
||||
|
||||
if (sd.hasBaseDefinition()) {
|
||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
if (base == null)
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_BASE_DEFINITION_FOR_LOGICAL_MODEL__FROM_, sd.getBaseDefinition(), sd.getUrl()));
|
||||
copyElements(sd, base.getSnapshot().getElement());
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
|||
import org.hl7.fhir.r5.conformance.R5ExtensionsLoader.Loadable;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
|
@ -22,6 +21,7 @@ import org.hl7.fhir.r5.model.ElementDefinition;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.r5.utils.ResourceSorters;
|
||||
|
@ -64,7 +64,7 @@ public class R5ExtensionsLoader {
|
|||
private Map<String, Loadable<CodeSystem>> codeSystems;
|
||||
private List<Loadable<StructureDefinition>> structures;
|
||||
private IWorkerContext context;
|
||||
private PackageVersion pd;
|
||||
private PackageInformation pd;
|
||||
private JsonParser json;
|
||||
|
||||
public R5ExtensionsLoader(BasePackageCacheManager pcm, IWorkerContext context) {
|
||||
|
@ -79,7 +79,7 @@ public class R5ExtensionsLoader {
|
|||
|
||||
public void load() throws FHIRException, IOException {
|
||||
pck = pcm.loadPackage("hl7.fhir.r5.core", "current");
|
||||
pd = new PackageVersion(pck.name(), pck.version(), pck.dateAsDate());
|
||||
pd = new PackageInformation(pck);
|
||||
|
||||
String[] types = new String[] { "StructureDefinition", "ValueSet", "CodeSystem" };
|
||||
json = new JsonParser();
|
||||
|
@ -140,7 +140,7 @@ public class R5ExtensionsLoader {
|
|||
}
|
||||
}
|
||||
|
||||
private void loadValueSet(String url, IWorkerContext context, Map<String, Loadable<ValueSet>> valueSets, Map<String, Loadable<CodeSystem>> codeSystems, PackageVersion pd) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||
private void loadValueSet(String url, IWorkerContext context, Map<String, Loadable<ValueSet>> valueSets, Map<String, Loadable<CodeSystem>> codeSystems, PackageInformation pd) throws FHIRFormatError, FileNotFoundException, IOException {
|
||||
if (valueSets.containsKey(url)) {
|
||||
ValueSet vs = valueSets.get(url).getResource();
|
||||
context.cacheResourceFromPackage(vs, pd);
|
||||
|
|
|
@ -84,6 +84,7 @@ import org.hl7.fhir.r5.model.NamingSystem.NamingSystemIdentifierType;
|
|||
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemUniqueIdComponent;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
|
||||
import org.hl7.fhir.r5.model.PlanDefinition;
|
||||
|
@ -115,6 +116,7 @@ import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorCla
|
|||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple;
|
||||
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.validation.ValidationContextCarrier;
|
||||
import org.hl7.fhir.utilities.OIDUtils;
|
||||
|
@ -137,6 +139,8 @@ import javax.annotation.Nonnull;
|
|||
|
||||
public abstract class BaseWorkerContext extends I18nBase implements IWorkerContext{
|
||||
|
||||
private static final boolean QA_CHECK_REFERENCE_SOURCE = true;
|
||||
|
||||
public class ResourceProxy {
|
||||
private Resource resource;
|
||||
private CanonicalResourceProxy proxy;
|
||||
|
@ -250,6 +254,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
protected ILoggingService logger = new SystemOutLoggingService();
|
||||
protected Parameters expParameters;
|
||||
private TranslationServices translator = new NullTranslator();
|
||||
private Map<String, PackageInformation> packages = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
protected TerminologyCache txCache;
|
||||
|
@ -336,10 +341,13 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
|
||||
|
||||
public void registerResourceFromPackage(CanonicalResourceProxy r, PackageVersion packageInfo) throws FHIRException {
|
||||
public void registerResourceFromPackage(CanonicalResourceProxy r, PackageInformation packageInfo) throws FHIRException {
|
||||
PackageHackerR5.fixLoadedResource(r, packageInfo);
|
||||
|
||||
synchronized (lock) {
|
||||
if (packageInfo != null) {
|
||||
packages.put(packageInfo.getVID(), packageInfo);
|
||||
}
|
||||
if (r.getId() != null) {
|
||||
Map<String, ResourceProxy> map = allResourcesById.get(r.getType());
|
||||
if (map == null) {
|
||||
|
@ -418,9 +426,13 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
}
|
||||
|
||||
public void cacheResourceFromPackage(Resource r, PackageVersion packageInfo) throws FHIRException {
|
||||
public void cacheResourceFromPackage(Resource r, PackageInformation packageInfo) throws FHIRException {
|
||||
|
||||
synchronized (lock) {
|
||||
if (packageInfo != null) {
|
||||
packages.put(packageInfo.getVID(), packageInfo);
|
||||
}
|
||||
|
||||
if (r.getId() != null) {
|
||||
Map<String, ResourceProxy> map = allResourcesById.get(r.fhirType());
|
||||
if (map == null) {
|
||||
|
@ -713,9 +725,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionOutcome expandVS(ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heirarchical) throws FHIRException {
|
||||
public ValueSetExpansionOutcome expandVS(Resource src, ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heirarchical) throws FHIRException {
|
||||
ValueSet vs = null;
|
||||
vs = fetchResource(ValueSet.class, binding.getValueSet());
|
||||
vs = fetchResource(ValueSet.class, binding.getValueSet(), src);
|
||||
if (vs == null) {
|
||||
throw new FHIRException(formatMessage(I18nConstants.UNABLE_TO_RESOLVE_VALUE_SET_, binding.getValueSet()));
|
||||
}
|
||||
|
@ -1239,18 +1251,18 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
private boolean addDependentResources(Parameters pin, ValueSet vs) {
|
||||
boolean cache = false;
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
cache = addDependentResources(pin, inc) || cache;
|
||||
cache = addDependentResources(pin, inc, vs) || cache;
|
||||
}
|
||||
for (ConceptSetComponent inc : vs.getCompose().getExclude()) {
|
||||
cache = addDependentResources(pin, inc) || cache;
|
||||
cache = addDependentResources(pin, inc, vs) || cache;
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
private boolean addDependentResources(Parameters pin, ConceptSetComponent inc) {
|
||||
private boolean addDependentResources(Parameters pin, ConceptSetComponent inc, Resource src) {
|
||||
boolean cache = false;
|
||||
for (CanonicalType c : inc.getValueSet()) {
|
||||
ValueSet vs = fetchResource(ValueSet.class, c.getValue());
|
||||
ValueSet vs = fetchResource(ValueSet.class, c.getValue(), src);
|
||||
if (vs != null) {
|
||||
pin.addParameter().setName("tx-resource").setResource(vs);
|
||||
if (isTxCaching && cacheId == null || !cached.contains(vs.getVUrl())) {
|
||||
|
@ -1260,7 +1272,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
addDependentResources(pin, vs);
|
||||
}
|
||||
}
|
||||
CodeSystem cs = fetchResource(CodeSystem.class, inc.getSystem());
|
||||
CodeSystem cs = fetchResource(CodeSystem.class, inc.getSystem(), src);
|
||||
if (cs != null && (cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == CodeSystemContentMode.FRAGMENT)) {
|
||||
pin.addParameter().setName("tx-resource").setResource(cs);
|
||||
if (isTxCaching && cacheId == null || !cached.contains(cs.getVUrl())) {
|
||||
|
@ -1397,16 +1409,33 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return fetchResourceWithExceptionByVersion(cls, uri, null, null);
|
||||
}
|
||||
|
||||
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri, CanonicalResource source) throws FHIRException {
|
||||
return fetchResourceWithExceptionByVersion(class_, uri, null, source);
|
||||
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri, Resource sourceForReference) throws FHIRException {
|
||||
return fetchResourceWithExceptionByVersion(class_, uri, null, sourceForReference);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Resource> T fetchResourceWithExceptionByVersion(Class<T> class_, String uri, String version, CanonicalResource source) throws FHIRException {
|
||||
public <T extends Resource> T fetchResourceWithExceptionByVersion(Class<T> class_, String uri, String version, Resource sourceForReference) throws FHIRException {
|
||||
if (uri == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (QA_CHECK_REFERENCE_SOURCE) {
|
||||
// it can be tricky to trace the source of a reference correctly. The code isn't water tight,
|
||||
// particularly around snapshot generation. Enable this code to check that the references are
|
||||
// correct (but it's slow)
|
||||
if (sourceForReference != null && uri.contains("ValueSet")) {
|
||||
if (!ResourceUtilities.hasURL(uri, sourceForReference)) {
|
||||
System.out.print("Claimed source doesn't have url in it: "+sourceForReference.fhirType()+"/"+sourceForReference.getIdPart()+" -> "+uri);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> pvlist = new ArrayList<>();
|
||||
if (sourceForReference != null && sourceForReference.getSourcePackage() != null) {
|
||||
populatePVList(pvlist, sourceForReference.getSourcePackage());
|
||||
}
|
||||
|
||||
if (class_ == StructureDefinition.class) {
|
||||
uri = ProfileUtilities.sdNs(uri, null);
|
||||
}
|
||||
|
@ -1425,49 +1454,49 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
if (class_ == Resource.class || class_ == null) {
|
||||
if (structures.has(uri)) {
|
||||
return (T) structures.get(uri, version);
|
||||
return (T) structures.get(uri, version, pvlist);
|
||||
}
|
||||
if (guides.has(uri)) {
|
||||
return (T) guides.get(uri, version);
|
||||
return (T) guides.get(uri, version, pvlist);
|
||||
}
|
||||
if (capstmts.has(uri)) {
|
||||
return (T) capstmts.get(uri, version);
|
||||
return (T) capstmts.get(uri, version, pvlist);
|
||||
}
|
||||
if (measures.has(uri)) {
|
||||
return (T) measures.get(uri, version);
|
||||
return (T) measures.get(uri, version, pvlist);
|
||||
}
|
||||
if (libraries.has(uri)) {
|
||||
return (T) libraries.get(uri, version);
|
||||
return (T) libraries.get(uri, version, pvlist);
|
||||
}
|
||||
if (valueSets.has(uri)) {
|
||||
return (T) valueSets.get(uri, version);
|
||||
return (T) valueSets.get(uri, version, pvlist);
|
||||
}
|
||||
if (codeSystems.has(uri)) {
|
||||
return (T) codeSystems.get(uri, version);
|
||||
return (T) codeSystems.get(uri, version, pvlist);
|
||||
}
|
||||
if (operations.has(uri)) {
|
||||
return (T) operations.get(uri, version);
|
||||
return (T) operations.get(uri, version, pvlist);
|
||||
}
|
||||
if (searchParameters.has(uri)) {
|
||||
return (T) searchParameters.get(uri, version);
|
||||
return (T) searchParameters.get(uri, version, pvlist);
|
||||
}
|
||||
if (plans.has(uri)) {
|
||||
return (T) plans.get(uri, version);
|
||||
return (T) plans.get(uri, version, pvlist);
|
||||
}
|
||||
if (maps.has(uri)) {
|
||||
return (T) maps.get(uri, version);
|
||||
return (T) maps.get(uri, version, pvlist);
|
||||
}
|
||||
if (transforms.has(uri)) {
|
||||
return (T) transforms.get(uri, version);
|
||||
return (T) transforms.get(uri, version, pvlist);
|
||||
}
|
||||
if (actors.has(uri)) {
|
||||
return (T) transforms.get(uri, version);
|
||||
return (T) transforms.get(uri, version, pvlist);
|
||||
}
|
||||
if (requirements.has(uri)) {
|
||||
return (T) transforms.get(uri, version);
|
||||
return (T) transforms.get(uri, version, pvlist);
|
||||
}
|
||||
if (questionnaires.has(uri)) {
|
||||
return (T) questionnaires.get(uri, version);
|
||||
return (T) questionnaires.get(uri, version, pvlist);
|
||||
}
|
||||
|
||||
for (Map<String, ResourceProxy> rt : allResourcesById.values()) {
|
||||
|
@ -1492,47 +1521,47 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
// }
|
||||
return null;
|
||||
} else if (class_ == ImplementationGuide.class) {
|
||||
return (T) guides.get(uri, version);
|
||||
return (T) guides.get(uri, version, pvlist);
|
||||
} else if (class_ == CapabilityStatement.class) {
|
||||
return (T) capstmts.get(uri, version);
|
||||
return (T) capstmts.get(uri, version, pvlist);
|
||||
} else if (class_ == Measure.class) {
|
||||
return (T) measures.get(uri, version);
|
||||
return (T) measures.get(uri, version, pvlist);
|
||||
} else if (class_ == Library.class) {
|
||||
return (T) libraries.get(uri, version);
|
||||
return (T) libraries.get(uri, version, pvlist);
|
||||
} else if (class_ == StructureDefinition.class) {
|
||||
return (T) structures.get(uri, version);
|
||||
return (T) structures.get(uri, version, pvlist);
|
||||
} else if (class_ == StructureMap.class) {
|
||||
return (T) transforms.get(uri, version);
|
||||
return (T) transforms.get(uri, version, pvlist);
|
||||
} else if (class_ == ValueSet.class) {
|
||||
return (T) valueSets.get(uri, version);
|
||||
return (T) valueSets.get(uri, version, pvlist);
|
||||
} else if (class_ == CodeSystem.class) {
|
||||
return (T) codeSystems.get(uri, version);
|
||||
return (T) codeSystems.get(uri, version, pvlist);
|
||||
} else if (class_ == ConceptMap.class) {
|
||||
return (T) maps.get(uri, version);
|
||||
return (T) maps.get(uri, version, pvlist);
|
||||
} else if (class_ == ActorDefinition.class) {
|
||||
return (T) actors.get(uri, version);
|
||||
return (T) actors.get(uri, version, pvlist);
|
||||
} else if (class_ == Requirements.class) {
|
||||
return (T) requirements.get(uri, version);
|
||||
return (T) requirements.get(uri, version, pvlist);
|
||||
} else if (class_ == PlanDefinition.class) {
|
||||
return (T) plans.get(uri, version);
|
||||
return (T) plans.get(uri, version, pvlist);
|
||||
} else if (class_ == OperationDefinition.class) {
|
||||
OperationDefinition od = operations.get(uri, version);
|
||||
return (T) od;
|
||||
} else if (class_ == Questionnaire.class) {
|
||||
return (T) questionnaires.get(uri, version);
|
||||
return (T) questionnaires.get(uri, version, pvlist);
|
||||
} else if (class_ == SearchParameter.class) {
|
||||
SearchParameter res = searchParameters.get(uri, version);
|
||||
SearchParameter res = searchParameters.get(uri, version, pvlist);
|
||||
return (T) res;
|
||||
}
|
||||
if (class_ == CodeSystem.class && codeSystems.has(uri)) {
|
||||
return (T) codeSystems.get(uri, version);
|
||||
return (T) codeSystems.get(uri, version, pvlist);
|
||||
}
|
||||
if (class_ == ValueSet.class && valueSets.has(uri)) {
|
||||
return (T) valueSets.get(uri, version);
|
||||
return (T) valueSets.get(uri, version, pvlist);
|
||||
}
|
||||
|
||||
if (class_ == Questionnaire.class) {
|
||||
return (T) questionnaires.get(uri, version);
|
||||
return (T) questionnaires.get(uri, version, pvlist);
|
||||
}
|
||||
if (supportedCodeSystems.contains(uri)) {
|
||||
return null;
|
||||
|
@ -1541,7 +1570,26 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
}
|
||||
|
||||
public PackageVersion getPackageForUrl(String uri) {
|
||||
private void populatePVList(List<String> pvlist, PackageInformation sourcePackage) {
|
||||
pvlist.add(sourcePackage.getVID());
|
||||
List<String> toadd = new ArrayList<>();
|
||||
do {
|
||||
toadd.clear();
|
||||
for (String s : pvlist) {
|
||||
PackageInformation pi = packages.get(s);
|
||||
if (pi != null) {
|
||||
for (String v : pi.getDependencies()) {
|
||||
if (!pvlist.contains(v) && !toadd.contains(v)) {
|
||||
toadd.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pvlist.addAll(toadd);
|
||||
} while (toadd.size() > 0);
|
||||
}
|
||||
|
||||
public PackageInformation getPackageForUrl(String uri) {
|
||||
if (uri == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1835,9 +1883,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
}
|
||||
|
||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri, CanonicalResource source) {
|
||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri, Resource sourceForReference) {
|
||||
try {
|
||||
return fetchResourceWithException(class_, uri, source);
|
||||
return fetchResourceWithException(class_, uri, sourceForReference);
|
||||
} catch (FHIRException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
|
@ -2345,7 +2393,4 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return this;
|
||||
}
|
||||
|
||||
public void registerVSACRule(boolean byVersion) {
|
||||
valueSets.registerSpecialRule(valueSets.new VSACRule(byVersion));
|
||||
}
|
||||
}
|
|
@ -3,9 +3,9 @@ package org.hl7.fhir.r5.context;
|
|||
import java.util.*;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
|
||||
|
@ -110,15 +110,15 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
private class CachedCanonicalResource<T1 extends CanonicalResource> {
|
||||
private T1 resource;
|
||||
private CanonicalResourceProxy proxy;
|
||||
private PackageVersion packageInfo;
|
||||
private PackageInformation packageInfo;
|
||||
|
||||
public CachedCanonicalResource(T1 resource, PackageVersion packageInfo) {
|
||||
public CachedCanonicalResource(T1 resource, PackageInformation packageInfo) {
|
||||
super();
|
||||
this.resource = resource;
|
||||
this.packageInfo = packageInfo;
|
||||
}
|
||||
|
||||
public CachedCanonicalResource(CanonicalResourceProxy proxy, PackageVersion packageInfo) {
|
||||
public CachedCanonicalResource(CanonicalResourceProxy proxy, PackageInformation packageInfo) {
|
||||
super();
|
||||
this.proxy = proxy;
|
||||
this.packageInfo = packageInfo;
|
||||
|
@ -134,13 +134,13 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
synchronized (this) {
|
||||
resource = res;
|
||||
}
|
||||
resource.setUserData("package", packageInfo);
|
||||
resource.setSourcePackage(packageInfo);
|
||||
proxy = null;
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
public PackageVersion getPackageInfo() {
|
||||
public PackageInformation getPackageInfo() {
|
||||
return packageInfo;
|
||||
}
|
||||
public String getUrl() {
|
||||
|
@ -158,7 +158,7 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return resource != null ? resource.fhirType()+"/"+resource.getId()+": "+resource.getUrl()+"|"+resource.getVersion() : proxy.toString();
|
||||
return resource != null ? resource.fhirType()+"/"+resource.getId()+"["+resource.getUrl()+"|"+resource.getVersion()+"]" : proxy.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -188,6 +188,8 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
|
||||
private boolean enforceUniqueId;
|
||||
private List<CachedCanonicalResource<T>> list = new ArrayList<>();
|
||||
private Map<String, List<CachedCanonicalResource<T>>> listForId = new HashMap<>();
|
||||
private Map<String, List<CachedCanonicalResource<T>>> listForUrl = new HashMap<>();
|
||||
private Map<String, CachedCanonicalResource<T>> map = new HashMap<>();
|
||||
private String version; // for debugging purposes
|
||||
|
||||
|
@ -215,7 +217,7 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
map.putAll(source.map);
|
||||
}
|
||||
|
||||
public void register(CanonicalResourceProxy r, PackageVersion packgeInfo) {
|
||||
public void register(CanonicalResourceProxy r, PackageInformation packgeInfo) {
|
||||
if (!r.hasId()) {
|
||||
throw new FHIRException("An id is required for a deferred load resource");
|
||||
}
|
||||
|
@ -223,7 +225,7 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
see(cr);
|
||||
}
|
||||
|
||||
public void see(T r, PackageVersion packgeInfo) {
|
||||
public void see(T r, PackageInformation packgeInfo) {
|
||||
if (r != null) {
|
||||
if (!r.hasId()) {
|
||||
r.setId(UUID.randomUUID().toString());
|
||||
|
@ -234,21 +236,27 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
}
|
||||
|
||||
public void see(CachedCanonicalResource<T> cr) {
|
||||
// -- 1. exit conditions -----------------------------------------------------------------------------
|
||||
|
||||
// ignore UTG NUCC erroneous code system
|
||||
if (cr.getPackageInfo() != null
|
||||
&& cr.getPackageInfo().getId() != null
|
||||
&& cr.getPackageInfo().getId().startsWith("hl7.terminology")
|
||||
&& Arrays.stream(INVALID_TERMINOLOGY_URLS).anyMatch((it)->it.equals(cr.getUrl()))
|
||||
) {
|
||||
&& Arrays.stream(INVALID_TERMINOLOGY_URLS).anyMatch((it)->it.equals(cr.getUrl()))) {
|
||||
return;
|
||||
}
|
||||
if (map.get(cr.getUrl()) != null && (cr.getPackageInfo() != null && cr.getPackageInfo().isExamplesPackage())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enforceUniqueId && map.containsKey(cr.getId())) {
|
||||
drop(cr.getId());
|
||||
}
|
||||
|
||||
// -- 2. preparation -----------------------------------------------------------------------------
|
||||
if (cr.resource != null) {
|
||||
cr.resource.setUserData("package", cr.getPackageInfo());
|
||||
cr.resource.setSourcePackage(cr.getPackageInfo());
|
||||
}
|
||||
|
||||
// -- 3. deleting existing content ---------------------------------------------------------------
|
||||
if (enforceUniqueId && map.containsKey(cr.getId())) {
|
||||
drop(cr.getId());
|
||||
}
|
||||
|
||||
// special case logic for UTG support prior to version 5
|
||||
|
@ -260,33 +268,104 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
}
|
||||
}
|
||||
for (CachedCanonicalResource<T> n : toDrop) {
|
||||
drop(n.getId());
|
||||
drop(n);
|
||||
}
|
||||
}
|
||||
CachedCanonicalResource<T> existing = cr.hasVersion() ? map.get(cr.getUrl()+"|"+cr.getVersion()) : map.get(cr.getUrl()+"|#0");
|
||||
if (map.get(cr.getUrl()) != null && (cr.getPackageInfo() != null && cr.getPackageInfo().isExamplesPackage())) {
|
||||
return;
|
||||
}
|
||||
if (existing != null) {
|
||||
list.remove(existing);
|
||||
}
|
||||
// CachedCanonicalResource<T> existing = cr.hasVersion() ? map.get(cr.getUrl()+"|"+cr.getVersion()) : map.get(cr.getUrl()+"|#0");
|
||||
// if (existing != null) {
|
||||
// drop(existing); // was list.remove(existing)
|
||||
// }
|
||||
|
||||
// -- 4. ok we add it to the list ---------------------------------------------------------------
|
||||
if (!enforceUniqueId) {
|
||||
if (!listForId.containsKey(cr.getId())) {
|
||||
listForId.put(cr.getId(), new ArrayList<>());
|
||||
}
|
||||
List<CachedCanonicalResource<T>> set = listForId.get(cr.getId());
|
||||
set.add(cr);
|
||||
}
|
||||
list.add(cr);
|
||||
map.put(cr.getId(), cr); // we do this so we can drop by id
|
||||
map.put(cr.getUrl(), cr);
|
||||
if (!listForUrl.containsKey(cr.getUrl())) {
|
||||
listForUrl.put(cr.getUrl(), new ArrayList<>());
|
||||
}
|
||||
List<CachedCanonicalResource<T>> set = listForUrl.get(cr.getUrl());
|
||||
set.add(cr);
|
||||
Collections.sort(set, new MetadataResourceVersionComparator<CachedCanonicalResource<T>>());
|
||||
|
||||
if (cr.getUrl() != null) {
|
||||
// first, this is the correct reosurce for this version (if it has a version)
|
||||
if (cr.hasVersion()) {
|
||||
map.put(cr.getUrl()+"|"+cr.getVersion(), cr);
|
||||
} else {
|
||||
map.put(cr.getUrl()+"|#0", cr);
|
||||
// -- 4. add to the map all the ways ---------------------------------------------------------------
|
||||
String pv = cr.getPackageInfo() != null ? cr.getPackageInfo().getVID() : null;
|
||||
map.put(cr.getId(), cr); // we do this so we can drop by id - if not enforcing id, it's just the most recent resource with this id
|
||||
map.put(cr.hasVersion() ? cr.getUrl()+"|"+cr.getVersion() : cr.getUrl()+"|#0", cr);
|
||||
if (pv != null) {
|
||||
map.put(pv+":"+(cr.hasVersion() ? cr.getUrl()+"|"+cr.getVersion() : cr.getUrl()+"|#0"), cr);
|
||||
}
|
||||
int ndx = set.indexOf(cr);
|
||||
if (ndx == set.size()-1) {
|
||||
map.put(cr.getUrl(), cr);
|
||||
if (pv != null) {
|
||||
map.put(pv+":"+cr.getUrl(), cr);
|
||||
}
|
||||
}
|
||||
String mm = VersionUtilities.getMajMin(cr.getVersion());
|
||||
if (mm != null) {
|
||||
if (pv != null) {
|
||||
map.put(pv+":"+cr.getUrl()+"|"+mm, cr);
|
||||
}
|
||||
if (set.size() - 1 == ndx) {
|
||||
map.put(cr.getUrl()+"|"+mm, cr);
|
||||
} else {
|
||||
for (int i = set.size() - 1; i > ndx; i--) {
|
||||
if (mm.equals(VersionUtilities.getMajMin(set.get(i).getVersion()))) {
|
||||
return;
|
||||
}
|
||||
map.put(cr.getUrl()+"|"+mm, cr);
|
||||
}
|
||||
}
|
||||
updateList(cr.getUrl(), cr.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBasePackage(PackageVersion packageInfo) {
|
||||
public void drop(CachedCanonicalResource<T> cr) {
|
||||
while (map.values().remove(cr));
|
||||
list.remove(cr);
|
||||
List<CachedCanonicalResource<T>> set = listForUrl.get(cr.getUrl());
|
||||
if (set != null) { // it really should be
|
||||
boolean last = set.indexOf(cr) == set.size()-1;
|
||||
set.remove(cr);
|
||||
if (!set.isEmpty()) {
|
||||
CachedCanonicalResource<T> crl = set.get(set.size()-1);
|
||||
if (last) {
|
||||
map.put(crl.getUrl(), crl);
|
||||
}
|
||||
String mm = VersionUtilities.getMajMin(cr.getVersion());
|
||||
if (mm != null) {
|
||||
for (int i = set.size()-1; i >= 0; i--) {
|
||||
if (mm.equals(VersionUtilities.getMajMin(set.get(i).getVersion()))) {
|
||||
map.put(cr.getUrl()+"|"+mm, set.get(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void drop(String id) {
|
||||
if (enforceUniqueId) {
|
||||
CachedCanonicalResource<T> cr = map.get(id);
|
||||
if (cr != null) {
|
||||
drop(cr);
|
||||
}
|
||||
} else {
|
||||
List<CachedCanonicalResource<T>> set = listForId.get(id);
|
||||
if (set != null) { // it really should be
|
||||
for (CachedCanonicalResource<T> i : set) {
|
||||
drop(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBasePackage(PackageInformation packageInfo) {
|
||||
return packageInfo == null ? false : VersionUtilities.isCorePackage(packageInfo.getId());
|
||||
}
|
||||
|
||||
|
@ -299,7 +378,6 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
}
|
||||
if (rl.size() > 0) {
|
||||
// sort by version as much as we are able
|
||||
Collections.sort(rl, new MetadataResourceVersionComparator<CachedCanonicalResource<T>>());
|
||||
// the current is the latest
|
||||
map.put(url, rl.get(rl.size()-1));
|
||||
// now, also, the latest for major/minor
|
||||
|
@ -320,27 +398,23 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
}
|
||||
|
||||
|
||||
public T get(String url) {
|
||||
return map.containsKey(url) ? map.get(url).getResource() : null;
|
||||
}
|
||||
|
||||
public PackageVersion getPackageInfo(String system, String version) {
|
||||
if (version == null) {
|
||||
return map.containsKey(system) ? map.get(system).getPackageInfo() : null;
|
||||
} else {
|
||||
if (map.containsKey(system+"|"+version))
|
||||
return map.get(system+"|"+version).getPackageInfo();
|
||||
String mm = VersionUtilities.getMajMin(version);
|
||||
if (mm != null && map.containsKey(system+"|"+mm))
|
||||
return map.get(system+"|"+mm).getPackageInfo();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean has(String url) {
|
||||
return map.containsKey(url);
|
||||
}
|
||||
|
||||
public boolean has(String system, String version) {
|
||||
if (map.containsKey(system+"|"+version))
|
||||
return true;
|
||||
String mm = VersionUtilities.getMajMin(version);
|
||||
if (mm != null)
|
||||
return map.containsKey(system+"|"+mm);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public T get(String url) {
|
||||
return map.containsKey(url) ? map.get(url).getResource() : null;
|
||||
}
|
||||
|
||||
public T get(String system, String version) {
|
||||
if (version == null) {
|
||||
|
@ -356,45 +430,75 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean has(String system, String version) {
|
||||
if (map.containsKey(system+"|"+version))
|
||||
return true;
|
||||
String mm = VersionUtilities.getMajMin(version);
|
||||
if (mm != null)
|
||||
return map.containsKey(system+"|"+mm);
|
||||
else
|
||||
return false;
|
||||
|
||||
/**
|
||||
* This is asking for a packaged version aware resolution
|
||||
*
|
||||
* if we can resolve the reference in the package dependencies, we will. if we can't
|
||||
* then we fall back to the non-package approach
|
||||
*
|
||||
* The context has to prepare the pvlist based on the original package
|
||||
* @param url
|
||||
* @param srcInfo
|
||||
* @return
|
||||
*/
|
||||
public T get(String url, List<String> pvlist) {
|
||||
for (String pv : pvlist) {
|
||||
if (map.containsKey(pv+":"+url)) {
|
||||
return map.get(pv+":"+url).getResource();
|
||||
}
|
||||
}
|
||||
return map.containsKey(url) ? map.get(url).getResource() : null;
|
||||
}
|
||||
|
||||
public T get(String system, String version, List<String> pvlist) {
|
||||
if (version == null) {
|
||||
return get(system, pvlist);
|
||||
} else {
|
||||
for (String pv : pvlist) {
|
||||
if (map.containsKey(pv+":"+system+"|"+version))
|
||||
return map.get(pv+":"+system+"|"+version).getResource();
|
||||
}
|
||||
String mm = VersionUtilities.getMajMin(version);
|
||||
if (mm != null && map.containsKey(system+"|"+mm))
|
||||
for (String pv : pvlist) {
|
||||
if (map.containsKey(pv+":"+system+"|"+mm))
|
||||
return map.get(pv+":"+system+"|"+mm).getResource();
|
||||
}
|
||||
|
||||
if (map.containsKey(system+"|"+version))
|
||||
return map.get(system+"|"+version).getResource();
|
||||
if (mm != null && map.containsKey(system+"|"+mm))
|
||||
return map.get(system+"|"+mm).getResource();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public PackageInformation getPackageInfo(String system, String version) {
|
||||
if (version == null) {
|
||||
return map.containsKey(system) ? map.get(system).getPackageInfo() : null;
|
||||
} else {
|
||||
if (map.containsKey(system+"|"+version))
|
||||
return map.get(system+"|"+version).getPackageInfo();
|
||||
String mm = VersionUtilities.getMajMin(version);
|
||||
if (mm != null && map.containsKey(system+"|"+mm))
|
||||
return map.get(system+"|"+mm).getPackageInfo();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public void drop(String id) {
|
||||
CachedCanonicalResource<T> res = null;
|
||||
do {
|
||||
res = null;
|
||||
for (CachedCanonicalResource<T> t : list) {
|
||||
if (t.getId().equals(id)) {
|
||||
res = t;
|
||||
}
|
||||
}
|
||||
if (res != null) {
|
||||
list.remove(res);
|
||||
map.remove(id);
|
||||
map.remove(res.getUrl());
|
||||
if (res.hasVersion()) {
|
||||
map.remove(res.getUrl()+"|"+res.getVersion());
|
||||
String mm = VersionUtilities.getMajMin(res.getVersion());
|
||||
if (mm != null) {
|
||||
map.remove(res.getUrl()+"|"+mm);
|
||||
}
|
||||
}
|
||||
updateList(res.getUrl(), res.getVersion());
|
||||
}
|
||||
} while (res != null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void listAll(List<T> result) {
|
||||
for (CachedCanonicalResource<T> t : list) {
|
||||
|
@ -437,5 +541,6 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
public boolean isEnforceUniqueId() {
|
||||
return enforceUniqueId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -239,7 +239,7 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
|
|||
if ((!p.hasSnapshot() || isProfileNeedsRegenerate(p) ) && (ifLogical || p.getKind() != StructureDefinitionKind.LOGICAL)) {
|
||||
if (!p.hasBaseDefinition())
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE___HAS_NO_BASE_AND_NO_SNAPSHOT, p.getName(), p.getUrl()));
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getBaseDefinition());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getBaseDefinition(), p);
|
||||
if (sd == null && "http://hl7.org/fhir/StructureDefinition/Base".equals(p.getBaseDefinition())) {
|
||||
sd = ProfileUtilities.makeBaseDefinition(p.getFhirVersion());
|
||||
}
|
||||
|
|
|
@ -8,19 +8,19 @@ import java.util.Date;
|
|||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
|
@ -31,7 +31,7 @@ import java.util.Date;
|
|||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
@ -58,6 +58,7 @@ import org.hl7.fhir.r5.model.Coding;
|
|||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
|
||||
import org.hl7.fhir.r5.model.NamingSystem;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
@ -102,7 +103,7 @@ import javax.annotation.Nonnull;
|
|||
*/
|
||||
|
||||
public interface IWorkerContext {
|
||||
|
||||
|
||||
class ValidationResult {
|
||||
private ConceptDefinitionComponent definition;
|
||||
private String system;
|
||||
|
@ -110,7 +111,7 @@ public interface IWorkerContext {
|
|||
private String message;
|
||||
private TerminologyServiceErrorClass errorClass;
|
||||
private String txLink;
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ValidationResult [definition=" + definition + ", system=" + system + ", severity=" + severity + ", message=" + message + ", errorClass="
|
||||
|
@ -121,7 +122,7 @@ public interface IWorkerContext {
|
|||
this.severity = severity;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
public ValidationResult(String system, ConceptDefinitionComponent definition) {
|
||||
this.system = system;
|
||||
this.definition = definition;
|
||||
|
@ -133,7 +134,7 @@ public interface IWorkerContext {
|
|||
this.system = system;
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
|
||||
public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) {
|
||||
this.severity = severity;
|
||||
this.message = message;
|
||||
|
@ -207,7 +208,7 @@ public interface IWorkerContext {
|
|||
public boolean hasMessage() {
|
||||
return message != null;
|
||||
}
|
||||
|
||||
|
||||
public Coding asCoding() {
|
||||
if (isOk() && definition != null && definition.getCode() != null) {
|
||||
return new Coding(system, definition.getCode(), definition.getDisplay());
|
||||
|
@ -221,7 +222,7 @@ public interface IWorkerContext {
|
|||
private Coding coding;
|
||||
private ValidationResult result;
|
||||
private CacheToken cacheToken;
|
||||
|
||||
|
||||
public CodingValidationRequest(Coding coding) {
|
||||
super();
|
||||
this.coding = coding;
|
||||
|
@ -260,86 +261,17 @@ public interface IWorkerContext {
|
|||
public void setCacheToken(CacheToken cacheToken) {
|
||||
this.cacheToken = cacheToken;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class PackageVersion {
|
||||
private String id;
|
||||
private String version;
|
||||
private Date date;
|
||||
|
||||
public PackageVersion(String source, Date date) {
|
||||
if (source == null) {
|
||||
throw new Error("Source cannot be null");
|
||||
}
|
||||
if (!source.contains("#")) {
|
||||
throw new FHIRException("Source ");
|
||||
}
|
||||
id = source.substring(0, source.indexOf("#"));
|
||||
version = source.substring(source.indexOf("#")+1);
|
||||
this.date = date;
|
||||
}
|
||||
public PackageVersion(String id, String version, Date date) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
public boolean isExamplesPackage() {
|
||||
boolean b = id.startsWith("hl7.fhir.") && id.endsWith(".examples");
|
||||
return b;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return id+"#"+version;
|
||||
}
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
public boolean isHTO() {
|
||||
boolean b = id.startsWith("hl7.terminology.r");
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class PackageDetails extends PackageVersion {
|
||||
private String name;
|
||||
private String canonical;
|
||||
private String web;
|
||||
|
||||
public PackageDetails(String id, String version, String name, String canonical, String web, Date date) {
|
||||
super(id, version, date);
|
||||
this.name = name;
|
||||
this.canonical = canonical;
|
||||
this.web = web;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public String getCanonical() {
|
||||
return canonical;
|
||||
}
|
||||
public String getWeb() {
|
||||
return web;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface IContextResourceLoader {
|
||||
/**
|
||||
* @return List of the resource types that should be loaded
|
||||
*/
|
||||
String[] getTypes();
|
||||
|
||||
|
||||
/**
|
||||
* Request to actually load the resources and do whatever is required
|
||||
*
|
||||
|
@ -350,7 +282,7 @@ public interface IWorkerContext {
|
|||
* @throws IOException
|
||||
*/
|
||||
Bundle loadBundle(InputStream stream, boolean isJson) throws FHIRException, IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Load a single resources (lazy load)
|
||||
*
|
||||
|
@ -361,7 +293,7 @@ public interface IWorkerContext {
|
|||
* @throws IOException
|
||||
*/
|
||||
Resource loadResource(InputStream stream, boolean isJson) throws FHIRException, IOException;
|
||||
|
||||
|
||||
/**
|
||||
* get the path for references to this resource.
|
||||
* @param resource
|
||||
|
@ -388,7 +320,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public String getVersion();
|
||||
|
||||
|
||||
/**
|
||||
* Get the UCUM service that provides access to units of measure reasoning services
|
||||
*
|
||||
|
@ -438,6 +370,7 @@ public interface IWorkerContext {
|
|||
*/
|
||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri);
|
||||
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException;
|
||||
public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri, Resource sourceOfReference) throws FHIRException;
|
||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri, String version);
|
||||
|
||||
/** has the same functionality as fetchResource, but passes in information about the source of the
|
||||
|
@ -449,7 +382,7 @@ public interface IWorkerContext {
|
|||
* @param canonicalForSource
|
||||
* @return
|
||||
*/
|
||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri, CanonicalResource canonicalForSource);
|
||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri, Resource sourceOfReference);
|
||||
|
||||
/**
|
||||
* Fetch all the resources of a particular type. if class == (null | Resource | DomainResource | CanonicalResource) return everything
|
||||
|
@ -477,7 +410,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public Resource fetchResourceById(String type, String uri);
|
||||
|
||||
|
||||
/**
|
||||
* find whether a resource is available.
|
||||
*
|
||||
|
@ -501,7 +434,7 @@ public interface IWorkerContext {
|
|||
* @throws FHIRException
|
||||
*/
|
||||
public void cacheResource(Resource res) throws FHIRException;
|
||||
|
||||
|
||||
/**
|
||||
* cache a resource for later retrieval using fetchResource.
|
||||
*
|
||||
|
@ -514,8 +447,8 @@ public interface IWorkerContext {
|
|||
* @param res
|
||||
* @throws FHIRException
|
||||
*/
|
||||
public void cacheResourceFromPackage(Resource res, PackageVersion packageDetails) throws FHIRException;
|
||||
|
||||
public void cacheResourceFromPackage(Resource res, PackageInformation packageInfo) throws FHIRException;
|
||||
|
||||
/**
|
||||
* Inform the cache about package dependencies. This can be used to help resolve references
|
||||
*
|
||||
|
@ -523,10 +456,10 @@ public interface IWorkerContext {
|
|||
*
|
||||
* @param packageInfo
|
||||
*/
|
||||
public void cachePackage(PackageDetails packageDetails, List<PackageVersion> dependencies);
|
||||
|
||||
public void cachePackage(PackageInformation packageInfo);
|
||||
|
||||
// -- profile services ---------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @return a list of the resource names defined for this version
|
||||
*/
|
||||
|
@ -590,7 +523,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical);
|
||||
|
||||
|
||||
/**
|
||||
* ValueSet Expansion - see $expand
|
||||
*
|
||||
|
@ -598,7 +531,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical, boolean incompleteOk);
|
||||
|
||||
|
||||
/**
|
||||
* ValueSet Expansion - see $expand, but resolves the binding first
|
||||
*
|
||||
|
@ -606,8 +539,8 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
* @throws FHIRException
|
||||
*/
|
||||
public ValueSetExpansionOutcome expandVS(ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heiarchical) throws FHIRException;
|
||||
|
||||
public ValueSetExpansionOutcome expandVS(Resource src, ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heiarchical) throws FHIRException;
|
||||
|
||||
/**
|
||||
* Value set expanion inside the internal expansion engine - used
|
||||
* for references to supported system (see "supportsSystem") for
|
||||
|
@ -656,7 +589,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(ValidationOptions options, String code, ValueSet vs);
|
||||
|
||||
|
||||
/**
|
||||
* Validation of a code - consult the terminology infrstructure and/or service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
|
@ -672,7 +605,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(ValidationOptions options, String system, String version, String code, String display);
|
||||
|
||||
|
||||
/**
|
||||
* Validation of a code - consult the terminology infrstructure and/or service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
|
@ -723,7 +656,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs);
|
||||
|
||||
|
||||
/**
|
||||
* See comments in ValidationContextCarrier. This is called when there might be additional value sets etc
|
||||
* available in the context, but we don't want to pre-process them.
|
||||
|
@ -745,10 +678,10 @@ public interface IWorkerContext {
|
|||
* @param vs
|
||||
*/
|
||||
public void validateCodeBatch(ValidationOptions options, List<? extends CodingValidationRequest> codes, ValueSet vs);
|
||||
|
||||
|
||||
|
||||
|
||||
// todo: figure these out
|
||||
public Map<String, NamingSystem> getNSUrlMap();
|
||||
public Map<String, NamingSystem> getNSUrlMap();
|
||||
public TranslationServices translator();
|
||||
|
||||
public interface ILoggingService {
|
||||
|
@ -770,7 +703,7 @@ public interface IWorkerContext {
|
|||
public Set<String> getCodeSystemsUsed();
|
||||
public int getClientRetryCount();
|
||||
public IWorkerContext setClientRetryCount(int value);
|
||||
|
||||
|
||||
public TimeTracker clock();
|
||||
|
||||
/**
|
||||
|
@ -782,7 +715,7 @@ public interface IWorkerContext {
|
|||
* @return
|
||||
*/
|
||||
public StructureDefinition fetchTypeDefinition(String typeName);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a set of keys that can be used to get binaries from this context.
|
||||
|
@ -849,14 +782,14 @@ public interface IWorkerContext {
|
|||
* @param pcm - used to find and load additional dependencies
|
||||
* @return the number of resources loaded
|
||||
*/
|
||||
int loadFromPackageAndDependencies(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm) throws FileNotFoundException, IOException, FHIRException;
|
||||
int loadFromPackageAndDependencies(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm) throws FileNotFoundException, IOException, FHIRException;
|
||||
|
||||
public boolean hasPackage(String id, String ver);
|
||||
public boolean hasPackage(PackageVersion pack);
|
||||
public PackageDetails getPackage(PackageVersion pack);
|
||||
public boolean hasPackage(String id, String ver);
|
||||
public boolean hasPackage(PackageInformation pack);
|
||||
public PackageInformation getPackage(String id, String ver);
|
||||
public PackageInformation getPackageForUrl(String url);
|
||||
|
||||
public IWorkerContextManager.IPackageLoadingTracker getPackageTracker();
|
||||
public IWorkerContext setPackageTracker(IWorkerContextManager.IPackageLoadingTracker packageTracker);
|
||||
|
||||
public PackageVersion getPackageForUrl(String url);
|
||||
}
|
|
@ -294,7 +294,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
return build(context);
|
||||
}
|
||||
|
||||
public SimpleWorkerContext fromDefinitions(Map<String, byte[]> source, IContextResourceLoader loader, PackageVersion pi) throws IOException, FHIRException {
|
||||
public SimpleWorkerContext fromDefinitions(Map<String, byte[]> source, IContextResourceLoader loader, PackageInformation pi) throws IOException, FHIRException {
|
||||
SimpleWorkerContext context = getSimpleWorkerContextInstance();
|
||||
for (String name : source.keySet()) {
|
||||
try {
|
||||
|
@ -311,7 +311,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
}
|
||||
}
|
||||
|
||||
private void loadDefinitionItem(String name, InputStream stream, IContextResourceLoader loader, ILoadFilter filter, PackageVersion pi) throws IOException, FHIRException {
|
||||
private void loadDefinitionItem(String name, InputStream stream, IContextResourceLoader loader, ILoadFilter filter, PackageInformation pi) throws IOException, FHIRException {
|
||||
if (name.endsWith(".xml"))
|
||||
loadFromFile(stream, name, loader, filter);
|
||||
else if (name.endsWith(".json"))
|
||||
|
@ -390,7 +390,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
}
|
||||
}
|
||||
|
||||
private void loadFromFileJson(InputStream stream, String name, IContextResourceLoader loader, ILoadFilter filter, PackageVersion pi) throws IOException, FHIRException {
|
||||
private void loadFromFileJson(InputStream stream, String name, IContextResourceLoader loader, ILoadFilter filter, PackageInformation pi) throws IOException, FHIRException {
|
||||
Bundle f = null;
|
||||
try {
|
||||
if (loader != null)
|
||||
|
@ -487,7 +487,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
}
|
||||
for (String s : pi.listResources(types)) {
|
||||
try {
|
||||
loadDefinitionItem(s, pi.load("package", s), loader, null, new PackageVersion(pi.id(), pi.version(), pi.dateAsDate()));
|
||||
loadDefinitionItem(s, pi.load("package", s), loader, null, new PackageInformation(pi));
|
||||
t++;
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException(formatMessage(I18nConstants.ERROR_READING__FROM_PACKAGE__, s, pi.name(), pi.version(), e.getMessage()), e);
|
||||
|
@ -500,7 +500,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
for (PackageResourceInformation pri : pi.listIndexedResources(types)) {
|
||||
if (!pri.getFilename().contains("ig-r4")) {
|
||||
try {
|
||||
registerResourceFromPackage(new PackageResourceLoader(pri, loader), new PackageVersion(pi.id(), pi.version(), pi.dateAsDate()));
|
||||
registerResourceFromPackage(new PackageResourceLoader(pri, loader), new PackageInformation(pi));
|
||||
t++;
|
||||
} catch (FHIRException e) {
|
||||
throw new FHIRException(formatMessage(I18nConstants.ERROR_READING__FROM_PACKAGE__, pri.getFilename(), pi.name(), pi.version(), e.getMessage()), e);
|
||||
|
@ -672,6 +672,21 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Resource> T fetchResource(Class<T> class_, String uri, Resource source) {
|
||||
T r = super.fetchResource(class_, uri, source);
|
||||
if (r instanceof StructureDefinition) {
|
||||
StructureDefinition p = (StructureDefinition)r;
|
||||
try {
|
||||
new ContextUtilities(this).generateSnapshot(p);
|
||||
} catch (Exception e) {
|
||||
// not sure what to do in this case?
|
||||
System.out.println("Unable to generate snapshot for "+uri+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -706,7 +721,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
return xverManager;
|
||||
}
|
||||
|
||||
public void cachePackage(PackageVersion packageDetails, List<PackageVersion> dependencies) {
|
||||
public void cachePackage(PackageInformation packageInfo) {
|
||||
// nothing yet
|
||||
}
|
||||
|
||||
|
@ -720,17 +735,12 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
}
|
||||
|
||||
@Override
|
||||
public void cachePackage(PackageDetails packageDetails, List<PackageVersion> dependencies) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPackage(PackageVersion pack) {
|
||||
public boolean hasPackage(PackageInformation pack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageDetails getPackage(PackageVersion pack) {
|
||||
public PackageInformation getPackage(String id, String ver) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -942,7 +942,7 @@ public class Element extends Base {
|
|||
return null;
|
||||
ICodingImpl c = new ICodingImpl(true, true, false, false);
|
||||
c.code = primitiveValue();
|
||||
ValueSetExpansionOutcome vse = property.getContext().expandVS(property.getDefinition().getBinding(), true, false);
|
||||
ValueSetExpansionOutcome vse = property.getContext().expandVS(property.getStructure(), property.getDefinition().getBinding(), true, false);
|
||||
if (vse.getValueset() == null)
|
||||
return null;
|
||||
for (ValueSetExpansionContainsComponent cc : vse.getValueset().getExpansion().getContains()) {
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package org.hl7.fhir.r5.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
|
||||
public class PackageInformation {
|
||||
private String id;
|
||||
private String version;
|
||||
private Date date;
|
||||
|
||||
private String name;
|
||||
private String canonical;
|
||||
private String web;
|
||||
|
||||
private List<String> dependencies = new ArrayList<>();
|
||||
|
||||
public PackageInformation(String id, String version, Date date, String name, String canonical, String web) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.date = date;
|
||||
this.name = name;
|
||||
this.canonical = canonical;
|
||||
this.web = web;
|
||||
}
|
||||
|
||||
public PackageInformation(String src, Date date) {
|
||||
super();
|
||||
this.id = src;
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public PackageInformation(NpmPackage pi) {
|
||||
super();
|
||||
this.id = pi.name();
|
||||
this.version = pi.version();
|
||||
this.date = pi.dateAsDate();
|
||||
this.name = pi.title();
|
||||
this.canonical = pi.canonical();
|
||||
this.web = pi.getWebLocation();
|
||||
dependencies.addAll(pi.dependencies());
|
||||
}
|
||||
|
||||
public PackageInformation(String id, String version, Date date) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getCanonical() {
|
||||
return canonical;
|
||||
}
|
||||
|
||||
public String getWeb() {
|
||||
return web;
|
||||
}
|
||||
|
||||
public List<String> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public boolean isExamplesPackage() {
|
||||
boolean b = id.startsWith("hl7.fhir.") && id.endsWith(".examples");
|
||||
return b;
|
||||
}
|
||||
|
||||
public boolean isHTO() {
|
||||
boolean b = id.startsWith("hl7.terminology.r");
|
||||
return b;
|
||||
}
|
||||
|
||||
public String getVID() {
|
||||
return id+"#"+version;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getVID();
|
||||
}
|
||||
}
|
|
@ -446,6 +446,24 @@ public abstract class Resource extends BaseResource implements IAnyResource {
|
|||
public String getLanguage(String defValue) {
|
||||
return hasLanguage() ? getLanguage() : defValue;
|
||||
}
|
||||
|
||||
// when possible, the source package is considered when performing reference resolution.
|
||||
|
||||
private PackageInformation sourcePackage;
|
||||
|
||||
public boolean hasSourcePackage() {
|
||||
return sourcePackage != null;
|
||||
}
|
||||
|
||||
public PackageInformation getSourcePackage() {
|
||||
return sourcePackage;
|
||||
}
|
||||
|
||||
public void setSourcePackage(PackageInformation sourcePackage) {
|
||||
this.sourcePackage = sourcePackage;
|
||||
}
|
||||
|
||||
|
||||
// end addition
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.hl7.fhir.r5.model.ContactPoint;
|
|||
import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.RestfulCapabilityMode;
|
||||
import org.hl7.fhir.r5.model.Enumerations.SearchParamType;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.SearchParameter;
|
||||
import org.hl7.fhir.r5.openapi.ParameterWriter.ParameterLocation;
|
||||
import org.hl7.fhir.r5.openapi.ParameterWriter.ParameterStyle;
|
||||
|
@ -84,7 +85,7 @@ public class OpenApiGenerator {
|
|||
|
||||
for (CapabilityStatementRestComponent csr : source.getRest()) {
|
||||
if (csr.getMode() == RestfulCapabilityMode.SERVER) {
|
||||
generatePaths(csr);
|
||||
generatePaths(csr, source);
|
||||
}
|
||||
}
|
||||
writeBaseParameters(dest.components());
|
||||
|
@ -115,21 +116,21 @@ public class OpenApiGenerator {
|
|||
.schema().type(SchemaType.number);
|
||||
}
|
||||
|
||||
private void generatePaths(CapabilityStatementRestComponent csr) {
|
||||
private void generatePaths(CapabilityStatementRestComponent csr, Resource cs) {
|
||||
generateMetadata();
|
||||
for (CapabilityStatementRestResourceComponent r : csr.getResource())
|
||||
generateResource(r);
|
||||
generateResource(r, cs);
|
||||
if (hasOp(csr, SystemRestfulInteraction.HISTORYSYSTEM))
|
||||
generateHistorySystem(csr);
|
||||
if (hasOp(csr, SystemRestfulInteraction.SEARCHSYSTEM))
|
||||
generateSearchSystem(csr);
|
||||
generateSearchSystem(csr, cs);
|
||||
if (hasOp(csr, SystemRestfulInteraction.BATCH) || hasOp(csr, SystemRestfulInteraction.TRANSACTION) )
|
||||
generateBatchTransaction(csr);
|
||||
}
|
||||
|
||||
private void generateResource(CapabilityStatementRestResourceComponent r) {
|
||||
private void generateResource(CapabilityStatementRestResourceComponent r, Resource cs) {
|
||||
if (hasOp(r, TypeRestfulInteraction.SEARCHTYPE))
|
||||
generateSearch(r);
|
||||
generateSearch(r, cs);
|
||||
if (hasOp(r, TypeRestfulInteraction.READ))
|
||||
generateRead(r);
|
||||
if (hasOp(r, TypeRestfulInteraction.CREATE))
|
||||
|
@ -189,7 +190,7 @@ public class OpenApiGenerator {
|
|||
op.paramRef("#/components/parameters/elements");
|
||||
}
|
||||
|
||||
private void generateSearch(CapabilityStatementRestResourceComponent r) {
|
||||
private void generateSearch(CapabilityStatementRestResourceComponent r, Resource cs) {
|
||||
OperationWriter op = makePathResType(r).operation("get");
|
||||
op.summary("Search all resources of type "+r.getType()+" based on a set of criteria");
|
||||
op.operationId("search"+r.getType());
|
||||
|
@ -213,7 +214,7 @@ public class OpenApiGenerator {
|
|||
p.in(ParameterLocation.query).description(spc.getDocumentation());
|
||||
p.schema().type(getSchemaType(spc.getType()));
|
||||
if (spc.hasDefinition()) {
|
||||
SearchParameter sp = context.fetchResource(SearchParameter.class, spc.getDefinition());
|
||||
SearchParameter sp = context.fetchResource(SearchParameter.class, spc.getDefinition(), cs);
|
||||
if (sp != null) {
|
||||
p.description(sp.getDescription());
|
||||
}
|
||||
|
@ -222,7 +223,7 @@ public class OpenApiGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private void generateSearchSystem(CapabilityStatementRestComponent csr) {
|
||||
private void generateSearchSystem(CapabilityStatementRestComponent csr, Resource cs) {
|
||||
OperationWriter op = makePathSystem().operation("get");
|
||||
op.summary("Search all resources of all types based on a set of criteria");
|
||||
op.operationId("searchAll");
|
||||
|
@ -250,7 +251,7 @@ public class OpenApiGenerator {
|
|||
p.in(ParameterLocation.query).description(spc.getDocumentation());
|
||||
p.schema().type(getSchemaType(spc.getType()));
|
||||
if (spc.hasDefinition()) {
|
||||
SearchParameter sp = context.fetchResource(SearchParameter.class, spc.getDefinition());
|
||||
SearchParameter sp = context.fetchResource(SearchParameter.class, spc.getDefinition(), cs);
|
||||
if (sp != null) {
|
||||
p.description(sp.getDescription());
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class ActorDefinitionRenderer extends ResourceRenderer {
|
|||
if (acd.hasCapabilities()) {
|
||||
tbl.tr().td().tx("Capabilities:");
|
||||
td = tr.td().colspan("2");
|
||||
CapabilityStatement cs = context.getWorker().fetchResource(CapabilityStatement.class, acd.getCapabilities());
|
||||
CapabilityStatement cs = context.getWorker().fetchResource(CapabilityStatement.class, acd.getCapabilities(), acd);
|
||||
if (cs != null) {
|
||||
td.ah(cs.getUserString("path")).tx(cs.present());
|
||||
} else {
|
||||
|
@ -63,7 +63,7 @@ public class ActorDefinitionRenderer extends ResourceRenderer {
|
|||
boolean first = true;
|
||||
for (UrlType t : acd.getReference()) {
|
||||
if (first) first = false; else x.br();
|
||||
ActorDefinition df = context.getWorker().fetchResource(ActorDefinition.class, t.getValue());
|
||||
ActorDefinition df = context.getWorker().fetchResource(ActorDefinition.class, t.getValue(), acd);
|
||||
if (df != null) {
|
||||
td.ah(df.getUserString("path")).tx(df.present());
|
||||
} else {
|
||||
|
|
|
@ -44,12 +44,12 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
XhtmlNode p = x.para();
|
||||
p.tx("Mapping from ");
|
||||
if (cm.hasSourceScope())
|
||||
AddVsRef(cm.getSourceScope().primitiveValue(), p);
|
||||
AddVsRef(cm.getSourceScope().primitiveValue(), p, cm);
|
||||
else
|
||||
p.tx("(not specified)");
|
||||
p.tx(" to ");
|
||||
if (cm.hasTargetScope())
|
||||
AddVsRef(cm.getTargetScope().primitiveValue(), p);
|
||||
AddVsRef(cm.getTargetScope().primitiveValue(), p, cm);
|
||||
else
|
||||
p.tx("(not specified)");
|
||||
|
||||
|
|
|
@ -763,7 +763,7 @@ public class DataRenderer extends Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
protected void renderUri(XhtmlNode x, UriType uri, String path, String id) {
|
||||
protected void renderUri(XhtmlNode x, UriType uri, String path, String id, Resource src) {
|
||||
if (isCanonical(path)) {
|
||||
x.code().tx(uri.getValue());
|
||||
} else {
|
||||
|
@ -773,7 +773,7 @@ public class DataRenderer extends Renderer {
|
|||
} else if (uri.getValue().startsWith("mailto:")) {
|
||||
x.ah(uri.getValue()).addText(uri.getValue().substring(7));
|
||||
} else {
|
||||
Resource target = context.getContext().fetchResource(Resource.class, uri.getValue());
|
||||
Resource target = context.getContext().fetchResource(Resource.class, uri.getValue(), src);
|
||||
if (target != null && target.hasUserData("path")) {
|
||||
String title = target instanceof CanonicalResource ? ((CanonicalResource) target).present() : uri.getValue();
|
||||
x.ah(target.getUserString("path")).addText(title);
|
||||
|
|
|
@ -52,7 +52,7 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
|
|||
if (opd.hasInputProfile()) {
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("Input parameters Profile: ");
|
||||
StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getInputProfile());
|
||||
StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getInputProfile(), opd);
|
||||
if (sd == null) {
|
||||
p.pre().tx(opd.getInputProfile());
|
||||
} else {
|
||||
|
@ -62,7 +62,7 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
|
|||
if (opd.hasOutputProfile()) {
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("Output parameters Profile: ");
|
||||
StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getOutputProfile());
|
||||
StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getOutputProfile(), opd);
|
||||
if (sd == null) {
|
||||
p.pre().tx(opd.getOutputProfile());
|
||||
} else {
|
||||
|
@ -79,7 +79,7 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
|
|||
tr.td().b().tx("Binding");
|
||||
tr.td().b().tx("Documentation");
|
||||
for (OperationDefinitionParameterComponent p : opd.getParameter()) {
|
||||
genOpParam(tbl, "", p);
|
||||
genOpParam(tbl, "", p, opd);
|
||||
}
|
||||
addMarkdown(x, opd.getComment());
|
||||
return true;
|
||||
|
@ -98,7 +98,7 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
|
|||
return ((OperationDefinition) r).present();
|
||||
}
|
||||
|
||||
private void genOpParam(XhtmlNode tbl, String path, OperationDefinitionParameterComponent p) throws EOperationOutcome, FHIRException, IOException {
|
||||
private void genOpParam(XhtmlNode tbl, String path, OperationDefinitionParameterComponent p, Resource opd) throws EOperationOutcome, FHIRException, IOException {
|
||||
XhtmlNode tr;
|
||||
tr = tbl.tr();
|
||||
tr.td().addText(p.getUse().toString());
|
||||
|
@ -129,13 +129,13 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
|
|||
}
|
||||
td = tr.td();
|
||||
if (p.hasBinding() && p.getBinding().hasValueSet()) {
|
||||
AddVsRef(p.getBinding().getValueSet(), td);
|
||||
AddVsRef(p.getBinding().getValueSet(), td, opd);
|
||||
td.tx(" ("+p.getBinding().getStrength().getDisplay()+")");
|
||||
}
|
||||
addMarkdown(tr.td(), p.getDocumentation());
|
||||
if (!p.hasType()) {
|
||||
for (OperationDefinitionParameterComponent pp : p.getPart()) {
|
||||
genOpParam(tbl, path+p.getName()+".", pp);
|
||||
genOpParam(tbl, path+p.getName()+".", pp, opd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -430,7 +430,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
renderContactPoint(x, c);
|
||||
}
|
||||
} else if (e instanceof UriType) {
|
||||
renderUri(x, (UriType) e, defn.getPath(), rcontext != null && rcontext.getResource() != null ? rcontext.getResource().getId() : null);
|
||||
renderUri(x, (UriType) e, defn.getPath(), rcontext != null && rcontext.getResource() != null ? rcontext.getResource().getId() : null, res.getResource());
|
||||
} else if (e instanceof Timing) {
|
||||
renderTiming(x, (Timing) e);
|
||||
} else if (e instanceof Range) {
|
||||
|
@ -795,7 +795,14 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
RenderingContext ctxt = context.copy();
|
||||
ctxt.setContained(true);
|
||||
ResourceRenderer rnd = RendererFactory.factory(v.fhirType(), ctxt);
|
||||
ResourceWrapper rw = new ElementWrappers.ResourceWrapperMetaElement(ctxt, (org.hl7.fhir.r5.elementmodel.Element) v.getBase());
|
||||
ResourceWrapper rw = null;
|
||||
if (v.getBase() instanceof org.hl7.fhir.r5.elementmodel.Element) {
|
||||
rw = new ElementWrappers.ResourceWrapperMetaElement(ctxt, (org.hl7.fhir.r5.elementmodel.Element) v.getBase());
|
||||
} else if (v.getBase() instanceof Resource){
|
||||
rw = new DirectWrappers.ResourceWrapperDirect(ctxt, (Resource) v.getBase());
|
||||
} else {
|
||||
throw new FHIRException("Not handled: base = "+v.getBase().getClass().getName());
|
||||
}
|
||||
rnd.render(x.blockquote(), rw);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (i.hasDefinition()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Definition: ", null));
|
||||
genDefinitionLink(gen, i, defn);
|
||||
genDefinitionLink(gen, i, defn, q);
|
||||
}
|
||||
if (i.hasEnableWhen()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
|
@ -318,7 +318,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
defn.getPieces().add(gen.new Piece(vs.getUserString("path"), vs.present(), null));
|
||||
}
|
||||
} else {
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet());
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet(), q);
|
||||
if (vs == null || !vs.hasUserData("path")) {
|
||||
defn.getPieces().add(gen.new Piece(null, i.getAnswerValueSet(), null));
|
||||
} else {
|
||||
|
@ -390,7 +390,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
return hasExt;
|
||||
}
|
||||
|
||||
public void genDefinitionLink(HierarchicalTableGenerator gen, QuestionnaireItemComponent i, Cell defn) {
|
||||
public void genDefinitionLink(HierarchicalTableGenerator gen, QuestionnaireItemComponent i, Cell defn, Questionnaire q) {
|
||||
// can we resolve the definition?
|
||||
String path = null;
|
||||
String d = i.getDefinition();
|
||||
|
@ -398,7 +398,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
path = d.substring(d.indexOf("#")+1);
|
||||
d = d.substring(0, d.indexOf("#"));
|
||||
}
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d);
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d, q);
|
||||
if (sd != null) {
|
||||
String url = sd.getUserString("path");
|
||||
if (url != null) {
|
||||
|
@ -411,7 +411,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
public void genDefinitionLink(XhtmlNode x, QuestionnaireItemComponent i) {
|
||||
public void genDefinitionLink(XhtmlNode x, QuestionnaireItemComponent i, Questionnaire q) {
|
||||
// can we resolve the definition?
|
||||
String path = null;
|
||||
String d = i.getDefinition();
|
||||
|
@ -419,7 +419,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
path = d.substring(d.indexOf("#")+1);
|
||||
d = d.substring(0, d.indexOf("#"));
|
||||
}
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d);
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d, q);
|
||||
if (sd != null) {
|
||||
String url = sd.getUserString("path");
|
||||
if (url != null) {
|
||||
|
@ -479,7 +479,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (i.hasDefinition()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Definition: ", null));
|
||||
genDefinitionLink(gen, i, defn);
|
||||
genDefinitionLink(gen, i, defn, q);
|
||||
}
|
||||
if (i.hasEnableWhen()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
|
@ -497,7 +497,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
defn.getPieces().add(gen.new Piece(vs.getUserString("path"), vs.present(), null));
|
||||
}
|
||||
} else {
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet());
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet(), q);
|
||||
if (vs == null || !vs.hasUserData("path")) {
|
||||
defn.getPieces().add(gen.new Piece(null, i.getAnswerValueSet(), null));
|
||||
} else {
|
||||
|
@ -716,7 +716,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
item(ul, "Max Length", Integer.toString(i.getMaxLength()));
|
||||
}
|
||||
if (i.hasDefinition()) {
|
||||
genDefinitionLink(item(ul, "Definition"), i);
|
||||
genDefinitionLink(item(ul, "Definition"), i, q);
|
||||
}
|
||||
if (i.hasEnableWhen()) {
|
||||
item(ul, "Enable When", "todo");
|
||||
|
@ -731,7 +731,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
ans.ah(vs.getUserString("path")).tx(vs.present());
|
||||
}
|
||||
} else {
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet());
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet(), q);
|
||||
if (vs == null || !vs.hasUserData("path")) {
|
||||
ans.tx(i.getAnswerValueSet());
|
||||
} else {
|
||||
|
@ -819,7 +819,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
vs.setUrl(q.getUrl()+"--"+q.getContained(i.getAnswerValueSet().substring(1)));
|
||||
}
|
||||
} else {
|
||||
vs = context.getContext().fetchResource(ValueSet.class, i.getAnswerValueSet());
|
||||
vs = context.getContext().fetchResource(ValueSet.class, i.getAnswerValueSet(), q);
|
||||
}
|
||||
if (vs != null) {
|
||||
ValueSetExpansionOutcome exp = context.getContext().expandVS(vs, true, false);
|
||||
|
@ -940,7 +940,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
// content control
|
||||
defn(tbl, "Max Length", qi.getMaxLength());
|
||||
if (qi.hasAnswerValueSet()) {
|
||||
defn(tbl, "Value Set", qi.getDefinition(), context.getWorker().fetchResource(ValueSet.class, qi.getAnswerValueSet()));
|
||||
defn(tbl, "Value Set", qi.getDefinition(), context.getWorker().fetchResource(ValueSet.class, qi.getAnswerValueSet(), q));
|
||||
}
|
||||
if (qi.hasAnswerOption()) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
|
@ -983,7 +983,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
|
||||
// formal definitions
|
||||
if (qi.hasDefinition()) {
|
||||
genDefinitionLink(defn(tbl, "Definition"), qi);
|
||||
genDefinitionLink(defn(tbl, "Definition"), qi, q);
|
||||
}
|
||||
|
||||
if (qi.hasCode()) {
|
||||
|
|
|
@ -225,7 +225,7 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
|
|||
return hasExt;
|
||||
}
|
||||
|
||||
public void genDefinitionLink(HierarchicalTableGenerator gen, QuestionnaireResponseItemComponent i, Cell defn) {
|
||||
public void genDefinitionLink(HierarchicalTableGenerator gen, QuestionnaireResponseItemComponent i, Cell defn, Resource src) {
|
||||
// can we resolve the definition?
|
||||
String path = null;
|
||||
String d = i.getDefinition();
|
||||
|
@ -233,7 +233,7 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
|
|||
path = d.substring(d.indexOf("#")+1);
|
||||
d = d.substring(0, d.indexOf("#"));
|
||||
}
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d);
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d, src);
|
||||
if (sd != null) {
|
||||
String url = sd.getUserString("path");
|
||||
if (url != null) {
|
||||
|
@ -246,7 +246,7 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
public void genDefinitionLink(XhtmlNode x, QuestionnaireResponseItemComponent i) {
|
||||
public void genDefinitionLink(XhtmlNode x, QuestionnaireResponseItemComponent i, Resource src) {
|
||||
// can we resolve the definition?
|
||||
String path = null;
|
||||
String d = i.getDefinition();
|
||||
|
@ -254,7 +254,7 @@ public class QuestionnaireResponseRenderer extends ResourceRenderer {
|
|||
path = d.substring(d.indexOf("#")+1);
|
||||
d = d.substring(0, d.indexOf("#"));
|
||||
}
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d);
|
||||
StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, d, src);
|
||||
if (sd != null) {
|
||||
String url = sd.getUserString("path");
|
||||
if (url != null) {
|
||||
|
|
|
@ -43,7 +43,7 @@ public class RequirementsRenderer extends ResourceRenderer {
|
|||
public boolean render(XhtmlNode x, Requirements req) throws FHIRFormatError, DefinitionException, IOException {
|
||||
if (req.hasActor()) {
|
||||
if (req.getActor().size() == 1) {
|
||||
ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, req.getActor().get(0).getValue());
|
||||
ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, req.getActor().get(0).getValue(), req);
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("These requirements apply to the actor ");
|
||||
if (acd == null) {
|
||||
|
@ -55,7 +55,7 @@ public class RequirementsRenderer extends ResourceRenderer {
|
|||
x.para().tx("These requirements apply to the following actors:");
|
||||
XhtmlNode ul = x.ul();
|
||||
for (CanonicalType a : req.getActor()) {
|
||||
ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, a.getValue());
|
||||
ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, a.getValue(), req);
|
||||
if (acd == null) {
|
||||
ul.li().code(a.getValue());
|
||||
} else {
|
||||
|
@ -66,7 +66,7 @@ public class RequirementsRenderer extends ResourceRenderer {
|
|||
}
|
||||
if (req.hasDerivedFrom()) {
|
||||
if (req.getDerivedFrom().size() == 1) {
|
||||
Requirements reqd = context.getWorker().fetchResource(Requirements.class, req.getDerivedFrom().get(0).getValue());
|
||||
Requirements reqd = context.getWorker().fetchResource(Requirements.class, req.getDerivedFrom().get(0).getValue(), req);
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("These requirements derive from ");
|
||||
if (reqd == null) {
|
||||
|
@ -78,7 +78,7 @@ public class RequirementsRenderer extends ResourceRenderer {
|
|||
x.para().tx("These requirements are derived from the following requirements:");
|
||||
XhtmlNode ul = x.ul();
|
||||
for (CanonicalType a : req.getDerivedFrom()) {
|
||||
Requirements reqd = context.getWorker().fetchResource(Requirements.class, a.getValue());
|
||||
Requirements reqd = context.getWorker().fetchResource(Requirements.class, a.getValue(), req);
|
||||
if (reqd == null) {
|
||||
ul.li().code(a.getValue());
|
||||
} else {
|
||||
|
@ -118,7 +118,7 @@ public class RequirementsRenderer extends ResourceRenderer {
|
|||
String url = stmt.getDerivedFrom();
|
||||
String key = url.contains("#") ? url.substring(url.indexOf("#")+1) : "";
|
||||
if (url.contains("#")) { url = url.substring(0, url.indexOf("#")); };
|
||||
Requirements reqr = context.getWorker().fetchResource(Requirements.class, url);
|
||||
Requirements reqr = context.getWorker().fetchResource(Requirements.class, url, req);
|
||||
if (reqr != null) {
|
||||
RequirementsStatementComponent stmtr = reqr.findStatement(key);
|
||||
if (stmtr != null) {
|
||||
|
@ -140,7 +140,7 @@ public class RequirementsRenderer extends ResourceRenderer {
|
|||
if (url.contains("#")) {
|
||||
url = url.substring(0, url.indexOf("#"));
|
||||
}
|
||||
Resource r = context.getWorker().fetchResource(Resource.class, url);
|
||||
Resource r = context.getWorker().fetchResource(Resource.class, url, req);
|
||||
if (r != null) {
|
||||
String desc = getResourceDescription(r, null);
|
||||
li.ah(c.getValue()).tx(desc);
|
||||
|
@ -174,7 +174,7 @@ public class RequirementsRenderer extends ResourceRenderer {
|
|||
if (url.contains("#")) {
|
||||
url = url.substring(0, url.indexOf("#"));
|
||||
}
|
||||
Resource r = context.getWorker().fetchResource(Resource.class, url);
|
||||
Resource r = context.getWorker().fetchResource(Resource.class, url, req);
|
||||
ResourceWithReference t = null;
|
||||
if (r == null) {
|
||||
t = context.getResolver().resolve(context, url);
|
||||
|
|
|
@ -142,14 +142,14 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
}
|
||||
|
||||
public void renderCanonical(ResourceWrapper rw, XhtmlNode x, String url) throws UnsupportedEncodingException, IOException {
|
||||
renderCanonical(rw, x, url, true);
|
||||
renderCanonical(rw, x, url, true, rw.getResource());
|
||||
}
|
||||
|
||||
public void renderCanonical(ResourceWrapper rw, XhtmlNode x, String url, boolean allowLinks) throws UnsupportedEncodingException, IOException {
|
||||
public void renderCanonical(ResourceWrapper rw, XhtmlNode x, String url, boolean allowLinks, Resource src) throws UnsupportedEncodingException, IOException {
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
Resource target = context.getWorker().fetchResource(Resource.class, url);
|
||||
Resource target = context.getWorker().fetchResource(Resource.class, url, src);
|
||||
if (target == null || !(target instanceof CanonicalResource)) {
|
||||
x.code().tx(url);
|
||||
} else {
|
||||
|
|
|
@ -135,7 +135,7 @@ public class SearchParameterRenderer extends TerminologyRenderer {
|
|||
tbl = x.table("grid");
|
||||
for (SearchParameterComponentComponent t : spd.getComponent()) {
|
||||
tr = tbl.tr();
|
||||
SearchParameter tsp = context.getWorker().fetchResource(SearchParameter.class, t.getDefinition());
|
||||
SearchParameter tsp = context.getWorker().fetchResource(SearchParameter.class, t.getDefinition(), spd);
|
||||
if (tsp != null && tsp.hasUserData("path")) {
|
||||
tr.td().ah(tsp.getUserString("path")).tx(tsp.present());
|
||||
} else {
|
||||
|
|
|
@ -269,7 +269,7 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
|
||||
protected void AddVsRef(String value, XhtmlNode li) {
|
||||
protected void AddVsRef(String value, XhtmlNode li, Resource source) {
|
||||
Resource res = null;
|
||||
if (rcontext != null) {
|
||||
BundleEntryComponent be = rcontext.resolve(value);
|
||||
|
@ -283,13 +283,11 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
|||
}
|
||||
CanonicalResource vs = (CanonicalResource) res;
|
||||
if (vs == null)
|
||||
vs = getContext().getWorker().fetchResource(ValueSet.class, value);
|
||||
vs = getContext().getWorker().fetchResource(ValueSet.class, value, source);
|
||||
if (vs == null)
|
||||
vs = getContext().getWorker().fetchResource(StructureDefinition.class, value);
|
||||
// if (vs == null)
|
||||
// vs = context.getWorker().fetchResource(DataElement.class, value);
|
||||
vs = getContext().getWorker().fetchResource(StructureDefinition.class, value, source);
|
||||
if (vs == null)
|
||||
vs = getContext().getWorker().fetchResource(Questionnaire.class, value);
|
||||
vs = getContext().getWorker().fetchResource(Questionnaire.class, value, source);
|
||||
if (vs != null) {
|
||||
String ref = (String) vs.getUserData("path");
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
re = new ConceptMapRenderInstructions(cm.present(), cm.getUrl(), false);
|
||||
}
|
||||
if (re != null) {
|
||||
ValueSet vst = cm.hasTargetScope() ? getContext().getWorker().fetchResource(ValueSet.class, cm.hasTargetScopeCanonicalType() ? cm.getTargetScopeCanonicalType().getValue() : cm.getTargetScopeUriType().asStringValue()) : null;
|
||||
ValueSet vst = cm.hasTargetScope() ? getContext().getWorker().fetchResource(ValueSet.class, cm.hasTargetScopeCanonicalType() ? cm.getTargetScopeCanonicalType().getValue() : cm.getTargetScopeUriType().asStringValue(), cm) : null;
|
||||
res.add(new UsedConceptMap(re, vst == null ? cm.getUserString("path") : vst.getUserString("path"), cm));
|
||||
}
|
||||
}
|
||||
|
@ -194,8 +194,8 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
x.para().tx("This value set contains "+count.toString()+" concepts");
|
||||
}
|
||||
|
||||
generateContentModeNotices(x, vs.getExpansion());
|
||||
generateVersionNotice(x, vs.getExpansion());
|
||||
generateContentModeNotices(x, vs.getExpansion(), vs);
|
||||
generateVersionNotice(x, vs.getExpansion(), vs);
|
||||
|
||||
CodeSystem allCS = null;
|
||||
boolean doLevel = false;
|
||||
|
@ -304,12 +304,12 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void generateContentModeNotices(XhtmlNode x, ValueSetExpansionComponent expansion) {
|
||||
generateContentModeNotice(x, expansion, "example", "Expansion based on example code system");
|
||||
generateContentModeNotice(x, expansion, "fragment", "Expansion based on code system fragment");
|
||||
private void generateContentModeNotices(XhtmlNode x, ValueSetExpansionComponent expansion, Resource vs) {
|
||||
generateContentModeNotice(x, expansion, "example", "Expansion based on example code system", vs);
|
||||
generateContentModeNotice(x, expansion, "fragment", "Expansion based on code system fragment", vs);
|
||||
}
|
||||
|
||||
private void generateContentModeNotice(XhtmlNode x, ValueSetExpansionComponent expansion, String mode, String text) {
|
||||
private void generateContentModeNotice(XhtmlNode x, ValueSetExpansionComponent expansion, String mode, String text, Resource vs) {
|
||||
Multimap<String, String> versions = HashMultimap.create();
|
||||
for (ValueSetExpansionParameterComponent p : expansion.getParameter()) {
|
||||
if (p.getName().equals(mode)) {
|
||||
|
@ -327,7 +327,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
for (String v : versions.get(s)) { // though there'll only be one
|
||||
XhtmlNode p = x.para().style("border: black 1px dotted; background-color: #ffcccc; padding: 8px; margin-bottom: 8px");
|
||||
p.tx(text+" ");
|
||||
expRef(p, s, v);
|
||||
expRef(p, s, v, vs);
|
||||
}
|
||||
} else {
|
||||
for (String v : versions.get(s)) {
|
||||
|
@ -337,7 +337,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
ul = div.ul();
|
||||
first = false;
|
||||
}
|
||||
expRef(ul.li(), s, v);
|
||||
expRef(ul.li(), s, v, vs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void generateVersionNotice(XhtmlNode x, ValueSetExpansionComponent expansion) {
|
||||
private void generateVersionNotice(XhtmlNode x, ValueSetExpansionComponent expansion, Resource vs) {
|
||||
Multimap<String, String> versions = HashMultimap.create();
|
||||
for (ValueSetExpansionParameterComponent p : expansion.getParameter()) {
|
||||
if (p.getName().equals("version")) {
|
||||
|
@ -453,7 +453,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
for (String v : versions.get(s)) { // though there'll only be one
|
||||
XhtmlNode p = x.para().style("border: black 1px dotted; background-color: #EEEEEE; padding: 8px; margin-bottom: 8px");
|
||||
p.tx("Expansion based on ");
|
||||
expRef(p, s, v);
|
||||
expRef(p, s, v, vs);
|
||||
}
|
||||
} else {
|
||||
for (String v : versions.get(s)) {
|
||||
|
@ -463,14 +463,14 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
ul = div.ul();
|
||||
first = false;
|
||||
}
|
||||
expRef(ul.li(), s, v);
|
||||
expRef(ul.li(), s, v, vs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void expRef(XhtmlNode x, String u, String v) {
|
||||
private void expRef(XhtmlNode x, String u, String v, Resource source) {
|
||||
// TODO Auto-generated method stub
|
||||
if (u.equals("http://snomed.info/sct")) {
|
||||
String[] parts = v.split("\\/");
|
||||
|
@ -492,7 +492,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
x.tx("Loinc v"+v);
|
||||
}
|
||||
} else {
|
||||
CanonicalResource cr = (CanonicalResource) getContext().getWorker().fetchResource(Resource.class, u+"|"+v);
|
||||
CanonicalResource cr = (CanonicalResource) getContext().getWorker().fetchResource(Resource.class, u+"|"+v, source);
|
||||
if (cr != null) {
|
||||
if (cr.hasUserData("path")) {
|
||||
x.ah(cr.getUserString("path")).tx(cr.present()+" v"+v+" ("+cr.fhirType()+")");
|
||||
|
@ -892,13 +892,13 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
int index = 0;
|
||||
if (vs.getCompose().getInclude().size() == 1 && vs.getCompose().getExclude().size() == 0) {
|
||||
hasExtensions = genInclude(x.ul(), vs.getCompose().getInclude().get(0), "Include", langs, doDesignations, maps, designations, index) || hasExtensions;
|
||||
hasExtensions = genInclude(x.ul(), vs.getCompose().getInclude().get(0), "Include", langs, doDesignations, maps, designations, index, vs) || hasExtensions;
|
||||
} else {
|
||||
XhtmlNode p = x.para();
|
||||
p.tx("This value set includes codes based on the following rules:");
|
||||
XhtmlNode ul = x.ul();
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
hasExtensions = genInclude(ul, inc, "Include", langs, doDesignations, maps, designations, index) || hasExtensions;
|
||||
hasExtensions = genInclude(ul, inc, "Include", langs, doDesignations, maps, designations, index, vs) || hasExtensions;
|
||||
index++;
|
||||
}
|
||||
if (vs.getCompose().hasExclude()) {
|
||||
|
@ -906,7 +906,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
p.tx("This value set excludes codes based on the following rules:");
|
||||
ul = x.ul();
|
||||
for (ConceptSetComponent exc : vs.getCompose().getExclude()) {
|
||||
hasExtensions = genInclude(ul, exc, "Exclude", langs, doDesignations, maps, designations, index) || hasExtensions;
|
||||
hasExtensions = genInclude(ul, exc, "Exclude", langs, doDesignations, maps, designations, index, vs) || hasExtensions;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
@ -1094,7 +1094,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, boolean doDesignations, List<UsedConceptMap> maps, Map<String, String> designations, int index) throws FHIRException, IOException {
|
||||
private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, boolean doDesignations, List<UsedConceptMap> maps, Map<String, String> designations, int index, Resource vsRes) throws FHIRException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
XhtmlNode li;
|
||||
li = ul.li();
|
||||
|
@ -1228,7 +1228,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
first = false;
|
||||
else
|
||||
li.tx(", ");
|
||||
AddVsRef(vs.asStringValue(), li);
|
||||
AddVsRef(vs.asStringValue(), li, vsRes);
|
||||
}
|
||||
}
|
||||
if (inc.hasExtension(ToolingExtensions.EXT_EXPAND_RULES) || inc.hasExtension(ToolingExtensions.EXT_EXPAND_GROUP)) {
|
||||
|
@ -1244,12 +1244,12 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
first = false;
|
||||
else
|
||||
li.tx(", ");
|
||||
AddVsRef(vs.asStringValue(), li);
|
||||
AddVsRef(vs.asStringValue(), li, vsRes);
|
||||
}
|
||||
} else {
|
||||
XhtmlNode xul = li.ul();
|
||||
for (UriType vs : inc.getValueSet()) {
|
||||
AddVsRef(vs.asStringValue(), xul.li());
|
||||
AddVsRef(vs.asStringValue(), xul.li(), vsRes);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.hl7.fhir.r5.model.Base;
|
|||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.ResourceRenderer;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
|
@ -56,6 +57,7 @@ public class BaseWrappers {
|
|||
public StructureDefinition getDefinition();
|
||||
public boolean hasNarrative();
|
||||
public String getNameFromResource();
|
||||
public Resource getResource(); // if there is one
|
||||
}
|
||||
|
||||
public interface BaseWrapper extends WrapperBase {
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.hl7.fhir.r5.formats.FormatUtilities;
|
|||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
|
@ -386,7 +387,7 @@ public class DOMWrappers {
|
|||
if ("DomainResource".equals(sd.getType())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -404,6 +405,11 @@ public class DOMWrappers {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ public class DirectWrappers {
|
|||
if ("DomainResource".equals(sd.getType())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
return false;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
|||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.Property;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
@ -266,7 +267,7 @@ public class ElementWrappers {
|
|||
if ("DomainResource".equals(sd.getType())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -288,6 +289,11 @@ public class ElementWrappers {
|
|||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PropertyWrapperMetaElement extends RendererWrapperImpl implements PropertyWrapper {
|
||||
|
|
|
@ -43,7 +43,6 @@ import java.util.Set;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.model.CanonicalType;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
|
@ -53,6 +52,7 @@ import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent;
|
|||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
|
||||
|
@ -751,7 +751,13 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||
ValidationResult res = context.validateCode(options.noClient(), new Coding(system, code, null), vs);
|
||||
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
|
||||
if (info != null && res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
||||
// server didn't know the code system either - we'll take it face value
|
||||
info.getWarnings().add(context.formatMessage(I18nConstants.TERMINOLOGY_TX_SYSTEM_NOTKNOWN, system));
|
||||
for (ConceptReferenceComponent cc : vsi.getConcept()) {
|
||||
if (cc.getCode().equals(code)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
info.setErr(TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED);
|
||||
}
|
||||
return null;
|
||||
|
@ -786,7 +792,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||
}
|
||||
|
||||
protected boolean isValueSetUnionImports() {
|
||||
PackageVersion p = (PackageVersion) valueset.getUserData("package");
|
||||
PackageInformation p = (PackageInformation) valueset.getSourcePackage();
|
||||
if (p != null) {
|
||||
return p.getDate().before(new GregorianCalendar(2022, Calendar.MARCH, 31).getTime());
|
||||
} else {
|
||||
|
@ -853,7 +859,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||
if (inner.containsKey(url)) {
|
||||
return inner.get(url);
|
||||
}
|
||||
ValueSet vs = context.fetchResource(ValueSet.class, url);
|
||||
ValueSet vs = context.fetchResource(ValueSet.class, url, valueset);
|
||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, context, localContext);
|
||||
inner.put(url, vsc);
|
||||
return vsc;
|
||||
|
|
|
@ -81,7 +81,6 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
|||
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.model.BooleanType;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.CodeSystem.CodeSystemContentMode;
|
||||
|
@ -95,6 +94,7 @@ import org.hl7.fhir.r5.model.DateTimeType;
|
|||
import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.Factory;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
|
@ -508,9 +508,9 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
private ValueSet importValueSet(String value, ValueSetExpansionComponent exp, Parameters expParams, boolean noInactive, ValueSet valueSet) throws ETooCostly, TerminologyServiceException, FileNotFoundException, IOException, FHIRFormatError {
|
||||
if (value == null)
|
||||
throw fail("unable to find value set with no identity");
|
||||
ValueSet vs = context.fetchResource(ValueSet.class, value);
|
||||
ValueSet vs = context.fetchResource(ValueSet.class, value, valueSet);
|
||||
if (vs == null) {
|
||||
if (context.fetchResource(CodeSystem.class, value) != null) {
|
||||
if (context.fetchResource(CodeSystem.class, value, valueSet) != null) {
|
||||
throw fail("Cannot include value set "+value+" because it's actually a code system");
|
||||
} else {
|
||||
throw fail("Unable to find imported value set " + value);
|
||||
|
@ -550,7 +550,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
|
||||
|
||||
protected boolean isValueSetUnionImports(ValueSet valueSet) {
|
||||
PackageVersion p = (PackageVersion) valueSet.getUserData("package");
|
||||
PackageInformation p = valueSet.getSourcePackage();
|
||||
if (p != null) {
|
||||
return p.getDate().before(new GregorianCalendar(2022, Calendar.MARCH, 31).getTime());
|
||||
} else {
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
|||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
||||
public class DefinitionNavigator {
|
||||
|
@ -164,19 +165,20 @@ public class DefinitionNavigator {
|
|||
*
|
||||
* you have to provide a type if there's more than one type
|
||||
* for current() since this library doesn't know how to choose
|
||||
* @param res
|
||||
* @throws DefinitionException
|
||||
* @
|
||||
*/
|
||||
public boolean hasTypeChildren(TypeRefComponent type) throws DefinitionException {
|
||||
public boolean hasTypeChildren(TypeRefComponent type, Resource res) throws DefinitionException {
|
||||
if (typeChildren == null || typeOfChildren != type) {
|
||||
loadTypedChildren(type);
|
||||
loadTypedChildren(type, res);
|
||||
}
|
||||
return !typeChildren.isEmpty();
|
||||
}
|
||||
|
||||
private void loadTypedChildren(TypeRefComponent type) throws DefinitionException {
|
||||
private void loadTypedChildren(TypeRefComponent type, Resource src) throws DefinitionException {
|
||||
typeOfChildren = null;
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, /* GF#13465 : this somehow needs to be revisited type.hasProfile() ? type.getProfile() : */ type.getWorkingCode());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, /* GF#13465 : this somehow needs to be revisited type.hasProfile() ? type.getProfile() : */ type.getWorkingCode(), src);
|
||||
if (sd != null) {
|
||||
DefinitionNavigator dn = new DefinitionNavigator(context, sd, 0, path, names, sd.getType());
|
||||
typeChildren = dn.children();
|
||||
|
@ -187,13 +189,14 @@ public class DefinitionNavigator {
|
|||
|
||||
/**
|
||||
*
|
||||
* @param res
|
||||
* @return
|
||||
* @throws DefinitionException
|
||||
* @
|
||||
*/
|
||||
public List<DefinitionNavigator> childrenFromType(TypeRefComponent type) throws DefinitionException {
|
||||
public List<DefinitionNavigator> childrenFromType(TypeRefComponent type, Resource res) throws DefinitionException {
|
||||
if (typeChildren == null || typeOfChildren != type) {
|
||||
loadTypedChildren(type);
|
||||
loadTypedChildren(type, res);
|
||||
}
|
||||
return typeChildren;
|
||||
}
|
||||
|
|
|
@ -209,10 +209,12 @@ public class FHIRPathEngine {
|
|||
public static class TypedElementDefinition {
|
||||
private ElementDefinition element;
|
||||
private String type;
|
||||
public TypedElementDefinition(ElementDefinition element, String type) {
|
||||
private StructureDefinition src;
|
||||
public TypedElementDefinition(StructureDefinition src, ElementDefinition element, String type) {
|
||||
super();
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.src = src;
|
||||
}
|
||||
public TypedElementDefinition(ElementDefinition element) {
|
||||
super();
|
||||
|
@ -245,6 +247,9 @@ public class FHIRPathEngine {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
public StructureDefinition getSrc() {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
private IWorkerContext worker;
|
||||
private IEvaluationContext hostServices;
|
||||
|
@ -1812,7 +1817,7 @@ public class FHIRPathEngine {
|
|||
if (tn.equals(sd.getType())) {
|
||||
return makeBoolean(true);
|
||||
}
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
return makeBoolean(false);
|
||||
}
|
||||
|
@ -2992,7 +2997,7 @@ public class FHIRPathEngine {
|
|||
result.add(item);
|
||||
break;
|
||||
}
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -4528,7 +4533,7 @@ public class FHIRPathEngine {
|
|||
if (n.equals(sd.getType())) {
|
||||
return makeBoolean(true);
|
||||
}
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
return makeBoolean(false);
|
||||
}
|
||||
|
@ -4565,7 +4570,7 @@ public class FHIRPathEngine {
|
|||
result.add(b);
|
||||
break;
|
||||
}
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5534,7 +5539,7 @@ public class FHIRPathEngine {
|
|||
m = getElementDefinition(sd, type.substring(type.indexOf("#")+1), false, expr);
|
||||
if (m != null && hasDataType(m.definition)) {
|
||||
if (m.fixedType != null) {
|
||||
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(m.fixedType, null));
|
||||
StructureDefinition dt = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(m.fixedType, null), sd);
|
||||
if (dt == null) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(m.fixedType, null), "getChildTypesByName");
|
||||
}
|
||||
|
@ -5693,7 +5698,7 @@ public class FHIRPathEngine {
|
|||
if (ed.getType().size() > 1) { // if there's more than one type, the test above would fail this
|
||||
throw new Error("Internal typing issue....");
|
||||
}
|
||||
StructureDefinition nsd = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getType().get(0).getCode(), null));
|
||||
StructureDefinition nsd = worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getType().get(0).getCode(), null), sd);
|
||||
if (nsd == null) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ed.getType().get(0).getCode(), "getElementDefinition");
|
||||
}
|
||||
|
@ -5808,7 +5813,7 @@ public class FHIRPathEngine {
|
|||
if (element.getTypes().get(0).getTargetProfile().size() > 1) {
|
||||
throw makeExceptionPlural(element.getTypes().get(0).getTargetProfile().size(), expr, I18nConstants.FHIRPATH_RESOLVE_DISCRIMINATOR_NO_TARGET, element.getElement().getId());
|
||||
}
|
||||
sd = worker.fetchResource(StructureDefinition.class, element.getTypes().get(0).getTargetProfile().get(0).getValue());
|
||||
sd = worker.fetchResource(StructureDefinition.class, element.getTypes().get(0).getTargetProfile().get(0).getValue(), profile);
|
||||
if (sd == null) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_RESOLVE_DISCRIMINATOR_CANT_FIND, element.getTypes().get(0).getTargetProfile(), element.getElement().getId());
|
||||
}
|
||||
|
@ -5820,9 +5825,9 @@ public class FHIRPathEngine {
|
|||
if (t.getPath().endsWith(".extension") && t.hasSliceName()) {
|
||||
System.out.println("t: "+t.getId());
|
||||
StructureDefinition exsd = (t.getType() == null || t.getType().isEmpty() || t.getType().get(0).getProfile().isEmpty()) ?
|
||||
null : worker.fetchResource(StructureDefinition.class, t.getType().get(0).getProfile().get(0).getValue());
|
||||
null : worker.fetchResource(StructureDefinition.class, t.getType().get(0).getProfile().get(0).getValue(), profile);
|
||||
while (exsd != null && !exsd.getBaseDefinition().equals("http://hl7.org/fhir/StructureDefinition/Extension")) {
|
||||
exsd = worker.fetchResource(StructureDefinition.class, exsd.getBaseDefinition());
|
||||
exsd = worker.fetchResource(StructureDefinition.class, exsd.getBaseDefinition(), exsd);
|
||||
}
|
||||
if (exsd != null && exsd.getUrl().equals(targetUrl)) {
|
||||
if (profileUtilities.getChildMap(sd, t).getList().isEmpty()) {
|
||||
|
@ -5851,7 +5856,7 @@ public class FHIRPathEngine {
|
|||
okToNotResolve = true;
|
||||
if ((atn.contains(stn))) {
|
||||
if (element.getTypes().size() > 1) {
|
||||
focus = new TypedElementDefinition(element.getElement(), stn);
|
||||
focus = new TypedElementDefinition( element.getSrc(), element.getElement(), stn);
|
||||
} else {
|
||||
focus = element;
|
||||
}
|
||||
|
@ -5909,9 +5914,9 @@ public class FHIRPathEngine {
|
|||
throw makeExceptionPlural(ed.getTypes().get(0).getProfile().size(), expr, I18nConstants.FHIRPATH_DISCRIMINATOR_MULTIPLE_PROFILES, ed.getElement().getId());
|
||||
}
|
||||
if (ed.getTypes().get(0).hasProfile()) {
|
||||
return worker.fetchResource(StructureDefinition.class, ed.getTypes().get(0).getProfile().get(0).getValue());
|
||||
return worker.fetchResource(StructureDefinition.class, ed.getTypes().get(0).getProfile().get(0).getValue(), ed.getSrc());
|
||||
} else {
|
||||
return worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getTypes().get(0).getCode(), null));
|
||||
return worker.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(ed.getTypes().get(0).getCode(), null), ed.getSrc());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
||||
public class PackageHackerR5 {
|
||||
|
||||
public static void fixLoadedResource(CanonicalResourceProxy r, PackageVersion packageInfo) {
|
||||
public static void fixLoadedResource(CanonicalResourceProxy r, PackageInformation packageInfo) {
|
||||
if ("http://terminology.hl7.org/CodeSystem/v2-0391|2.6".equals(r.getUrl())) {
|
||||
r.hack("http://terminology.hl7.org/CodeSystem/v2-0391-2.6", "2.6");
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleLinkComponent;
|
||||
|
@ -52,6 +53,7 @@ import org.hl7.fhir.r5.model.Meta;
|
|||
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.model.Property;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.ResourceType;
|
||||
|
@ -180,4 +182,28 @@ public class ResourceUtilities {
|
|||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static boolean hasURL(String uri, Resource src) {
|
||||
for (Property p : src.children()) {
|
||||
if (hasURL(uri, p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasURL(String uri, Property p) {
|
||||
for (Base b : p.getValues()) {
|
||||
if (b.isPrimitive()) {
|
||||
return uri.equals(b.primitiveValue());
|
||||
} else {
|
||||
for (Property c : b.children()) {
|
||||
if (hasURL(uri, c)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
package org.hl7.fhir.r5.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager;
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -428,12 +430,12 @@ public class CanonicalResourceManagerTests {
|
|||
vs2.setVersion("2000.0.0");
|
||||
vs2.setName("2");
|
||||
|
||||
mrm.see(vs1, new PackageVersion("hl7.fhir.r4.core", "4.0.1", new Date()));
|
||||
mrm.see(vs1, new PackageInformation("hl7.fhir.r4.core", "4.0.1", new Date()));
|
||||
Assertions.assertNotNull(mrm.get("http://terminology.hl7.org/ValueSet/234"));
|
||||
Assertions.assertNotNull(mrm.get("http://terminology.hl7.org/ValueSet/234", "2.0.0"));
|
||||
Assertions.assertTrue(mrm.get("http://terminology.hl7.org/ValueSet/234").getName().equals("1"));
|
||||
|
||||
mrm.see(vs2, new PackageVersion("hl7.terminology.r4", "4.0.1", new Date()));
|
||||
mrm.see(vs2, new PackageInformation("hl7.terminology.r4", "4.0.1", new Date()));
|
||||
Assertions.assertNotNull(mrm.get("http://terminology.hl7.org/ValueSet/234"));
|
||||
Assertions.assertTrue(mrm.get("http://terminology.hl7.org/ValueSet/234").getName().equals("2"));
|
||||
Assertions.assertNull(mrm.get("http://terminology.hl7.org/ValueSet/234", "2.0.0")); // this will get dropped completely because of UTG rules
|
||||
|
@ -809,5 +811,46 @@ public class CanonicalResourceManagerTests {
|
|||
Assertions.assertNull(mrm.get("http://url/ValueSet/234", "4.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageSpecificResolution1() {
|
||||
// we add 2 canonicals to the cache with the same identification, but different package information
|
||||
CanonicalResourceManager<ValueSet> mrm = new CanonicalResourceManager<>(false);
|
||||
ValueSet vs1 = new ValueSet();
|
||||
vs1.setId("2345");
|
||||
vs1.setUrl("http://url/ValueSet/234");
|
||||
vs1.setVersion("4.0.1");
|
||||
vs1.setName("1");
|
||||
DeferredLoadTestResource vs1d = new DeferredLoadTestResource(vs1);
|
||||
mrm.see(vs1, new PackageInformation("pid.one", "1.0.0", new Date()));
|
||||
|
||||
ValueSet vs2 = new ValueSet();
|
||||
vs2.setId("2346");
|
||||
vs2.setUrl("http://url/ValueSet/234");
|
||||
vs2.setVersion("4.0.1");
|
||||
vs2.setName("2");
|
||||
mrm.see(vs2, new PackageInformation("pid.two", "1.0.0", new Date()));
|
||||
|
||||
List<String> pvl1 = new ArrayList<>();
|
||||
pvl1.add("pid.one#1.0.0");
|
||||
|
||||
List<String> pvl2 = new ArrayList<>();
|
||||
pvl1.add("pid.two#1.0.0");
|
||||
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234").getName());
|
||||
Assertions.assertEquals("1", mrm.get("http://url/ValueSet/234", pvl1).getName());
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234", pvl2).getName());
|
||||
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234", "4.0.1").getName());
|
||||
Assertions.assertEquals("1", mrm.get("http://url/ValueSet/234", "4.0.1", pvl1).getName());
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234", "4.0.1", pvl2).getName());
|
||||
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234", "4.0").getName());
|
||||
Assertions.assertEquals("1", mrm.get("http://url/ValueSet/234", "4.0", pvl1).getName());
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234", "4.0", pvl2).getName());
|
||||
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234", "4.0.2").getName());
|
||||
Assertions.assertEquals("1", mrm.get("http://url/ValueSet/234", "4.0.2", pvl1).getName());
|
||||
Assertions.assertEquals("2", mrm.get("http://url/ValueSet/234", "4.0.2", pvl2).getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -817,12 +817,13 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
|
|||
return ruleDate;
|
||||
}
|
||||
|
||||
public void setRuleDate(Date ruleDate) {
|
||||
public ValidationMessage setRuleDate(Date ruleDate) {
|
||||
this.ruleDate = ruleDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void setRuleDate(String value) {
|
||||
public ValidationMessage setRuleDate(String value) {
|
||||
if (value == null) {
|
||||
ruleDate = null;
|
||||
} else {
|
||||
|
@ -834,5 +835,6 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
|
|||
}
|
||||
ruleDate = d;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.utilities;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
@ -10,6 +11,7 @@ import java.util.stream.Stream;
|
|||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
|
|
@ -801,7 +801,7 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
}
|
||||
|
||||
|
||||
protected ValueSet resolveBindingReference(DomainResource ctxt, String reference, String uri) {
|
||||
protected ValueSet resolveBindingReference(DomainResource ctxt, String reference, String uri, Resource src) {
|
||||
if (reference != null) {
|
||||
if (reference.equals("http://www.rfc-editor.org/bcp/bcp13.txt")) {
|
||||
reference = "http://hl7.org/fhir/ValueSet/mimetypes";
|
||||
|
@ -814,11 +814,11 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
return null;
|
||||
} else {
|
||||
long t = System.nanoTime();
|
||||
ValueSet fr = context.fetchResource(ValueSet.class, reference);
|
||||
ValueSet fr = context.fetchResource(ValueSet.class, reference, src);
|
||||
if (fr == null) {
|
||||
if (!Utilities.isAbsoluteUrl(reference)) {
|
||||
reference = resolve(uri, reference);
|
||||
fr = context.fetchResource(ValueSet.class, reference);
|
||||
fr = context.fetchResource(ValueSet.class, reference, src);
|
||||
}
|
||||
}
|
||||
if (fr == null) {
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
|
||||
import org.hl7.fhir.r5.context.IWorkerContextManager;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.context.SystemOutLoggingService;
|
||||
|
@ -52,6 +51,7 @@ import org.hl7.fhir.r5.model.ElementDefinition;
|
|||
import org.hl7.fhir.r5.model.ExpressionNode;
|
||||
import org.hl7.fhir.r5.model.ImplementationGuide;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||
import org.hl7.fhir.r5.model.PackageInformation;
|
||||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
@ -429,7 +429,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
if (userAgent != null) {
|
||||
contextBuilder.withUserAgent(userAgent);
|
||||
}
|
||||
context = contextBuilder.fromDefinitions(source, ValidatorUtils.loaderForVersion(version), new PackageVersion(src, new Date()));
|
||||
context = contextBuilder.fromDefinitions(source, ValidatorUtils.loaderForVersion(version), new PackageInformation(src, new Date()));
|
||||
ValidatorUtils.grabNatives(getBinaries(), source, "http://hl7.org/fhir");
|
||||
}
|
||||
// ucum-essence.xml should be in the class path. if it's not, ask about how to sort this out
|
||||
|
|
|
@ -864,7 +864,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
StructureDefinition sd = profiles.get(i);
|
||||
if (sd.hasExtension(ToolingExtensions.EXT_SD_DEPENDENCY)) {
|
||||
for (Extension ext : sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_DEPENDENCY)) {
|
||||
StructureDefinition dep = context.fetchResource( StructureDefinition.class, ext.getValue().primitiveValue());
|
||||
StructureDefinition dep = context.fetchResource( StructureDefinition.class, ext.getValue().primitiveValue(), sd);
|
||||
if (dep == null) {
|
||||
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_DEPENDS_NOT_RESOLVED, ext.getValue().primitiveValue(), sd.getVersionedUrl());
|
||||
} else if (!profiles.contains(dep)) {
|
||||
|
@ -1025,7 +1025,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return false;
|
||||
} else {
|
||||
try {
|
||||
if (context.fetchResourceWithException(ValueSet.class, system) != null) {
|
||||
if (context.fetchResourceWithException(ValueSet.class, system, element.getProperty().getStructure()) != null) {
|
||||
rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_SYSTEM_VALUESET, system);
|
||||
// Lloyd: This error used to prohibit checking for downstream issues, but there are some cases where that checking needs to occur. Please talk to me before changing the code back.
|
||||
}
|
||||
|
@ -1192,7 +1192,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, I18nConstants.TERMINOLOGY_TX_BINDING_MISSING, path)) {
|
||||
if (binding.hasValueSet()) {
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl(), profile);
|
||||
if (valueset == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(binding.getValueSet());
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(binding.getValueSet()))) {
|
||||
|
@ -1324,7 +1324,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, I18nConstants.TERMINOLOGY_TX_BINDING_MISSING, path)) {
|
||||
if (binding.hasValueSet()) {
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl(), profile);
|
||||
if (valueset == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(binding.getValueSet());
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(binding.getValueSet()))) {
|
||||
|
@ -1455,7 +1455,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, I18nConstants.TERMINOLOGY_TX_BINDING_MISSING2, path)) {
|
||||
if (binding.hasValueSet()) {
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl(), profile);
|
||||
if (valueset == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(binding.getValueSet());
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(binding.getValueSet()))) {
|
||||
|
@ -1600,7 +1600,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, CodeableConcept cc, NodeStack stack) {
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl(), profile);
|
||||
if (valueset == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(maxVSUrl);
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(maxVSUrl))) {
|
||||
|
@ -1635,7 +1635,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
|
||||
private boolean checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, Coding c, NodeStack stack) {
|
||||
boolean ok = true;
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl(), profile);
|
||||
if (valueset == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(maxVSUrl);
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(maxVSUrl))) {
|
||||
|
@ -1664,7 +1664,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
|
||||
private boolean checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, String value, NodeStack stack) {
|
||||
boolean ok = true;
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl(), profile);
|
||||
if (valueset == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(maxVSUrl);
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(maxVSUrl))) {
|
||||
|
@ -1732,7 +1732,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, I18nConstants.TERMINOLOGY_TX_BINDING_MISSING2, path)) {
|
||||
if (binding.hasValueSet()) {
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
|
||||
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl(), profile);
|
||||
if (valueset == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(binding.getValueSet());
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(binding.getValueSet()))) {
|
||||
|
@ -1977,7 +1977,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
break;
|
||||
}
|
||||
if (sd.getBaseDefinition() != null) {
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd);
|
||||
} else {
|
||||
sd = null;
|
||||
}
|
||||
|
@ -2533,7 +2533,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
} else {
|
||||
boolean tok = false;
|
||||
for (StructureDefinition t : context.fetchResourcesByType(StructureDefinition.class)) {
|
||||
if (t.hasUserData("package") && t.getUserString("package").startsWith("hl7.fhir.r") && v.equals(t.getType())) {
|
||||
if (t.hasSourcePackage() && t.getSourcePackage().getId().startsWith("hl7.fhir.r") && v.equals(t.getType())) {
|
||||
tok = true;
|
||||
}
|
||||
}
|
||||
|
@ -2921,7 +2921,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
// firstly, resolve the value set
|
||||
ElementDefinitionBindingComponent binding = elementContext.getBinding();
|
||||
if (binding.hasValueSet()) {
|
||||
ValueSet vs = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
|
||||
ValueSet vs = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl(), profile);
|
||||
if (vs == null) {
|
||||
CodeSystem cs = context.fetchCodeSystem(binding.getValueSet());
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, cs == null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND_CS, describeReference(binding.getValueSet()))) {
|
||||
|
@ -3442,7 +3442,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
StructureDefinition sdFT = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+ft);
|
||||
boolean rok = false;
|
||||
for (CanonicalType tp : type.getTargetProfile()) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, tp.getValue());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, tp.getValue(), profile);
|
||||
if (sd != null) {
|
||||
types.add(sd.getType());
|
||||
}
|
||||
|
@ -3452,7 +3452,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
rok = true;
|
||||
break;
|
||||
}
|
||||
sdF = sdF.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sdF.getBaseDefinition()) : null;
|
||||
sdF = sdF.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sdF.getBaseDefinition(), sdF) : null;
|
||||
}
|
||||
}
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), path, types.isEmpty() || rok,
|
||||
|
@ -3758,7 +3758,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
for (TypeRefComponent type : element.getType()) {
|
||||
for (CanonicalType p : type.getProfile()) {
|
||||
String id = p.hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT) ? p.getExtensionString(ToolingExtensions.EXT_PROFILE_ELEMENT) : null;
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue(), profile);
|
||||
if (sd == null)
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_PROFILE_, p));
|
||||
profile = sd;
|
||||
|
@ -3801,13 +3801,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return igs;
|
||||
}
|
||||
|
||||
private StructureDefinition getProfileForType(String type, List<TypeRefComponent> list) {
|
||||
private StructureDefinition getProfileForType(String type, List<TypeRefComponent> list, Resource src) {
|
||||
for (TypeRefComponent tr : list) {
|
||||
String url = tr.getWorkingCode();
|
||||
if (!Utilities.isAbsoluteUrl(url))
|
||||
url = "http://hl7.org/fhir/StructureDefinition/" + url;
|
||||
long t = System.nanoTime();
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url, src);
|
||||
timeTracker.sd(t);
|
||||
if (sd != null && (sd.getType().equals(type) || sd.getUrl().equals(type)) && sd.hasSnapshot()) {
|
||||
return sd;
|
||||
|
@ -4196,7 +4196,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return null;
|
||||
} else {
|
||||
long t = System.nanoTime();
|
||||
StructureDefinition fr = context.fetchResource(StructureDefinition.class, pr);
|
||||
StructureDefinition fr = context.fetchResource(StructureDefinition.class, pr, profile);
|
||||
timeTracker.sd(t);
|
||||
return fr;
|
||||
}
|
||||
|
@ -4800,7 +4800,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
for (ImplementationGuide ig : igs) {
|
||||
for (ImplementationGuideGlobalComponent gl : ig.getGlobal()) {
|
||||
if (rt.equals(gl.getType())) {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, gl.getProfile());
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, gl.getProfile(), ig);
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), sd != null, I18nConstants.VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN, gl.getProfile())) {
|
||||
if (crumbTrails) {
|
||||
element.addMessage(signpost(errors, NO_RULE_DATE, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL, sd.getVersionedUrl(), ig.getVersionedUrl()));
|
||||
|
@ -5132,7 +5132,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
|
||||
if (typeForResource.getProfile().size() == 1) {
|
||||
long t = System.nanoTime();
|
||||
StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, typeForResource.getProfile().get(0).asStringValue());
|
||||
StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, typeForResource.getProfile().get(0).asStringValue(), parentProfile);
|
||||
timeTracker.sd(t);
|
||||
trackUsage(profile, hostContext, element);
|
||||
if (rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(),
|
||||
|
@ -5165,7 +5165,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
} else {
|
||||
List<String> types = new ArrayList<>();
|
||||
for (UriType u : typeForResource.getProfile()) {
|
||||
StructureDefinition sd = this.context.fetchResource(StructureDefinition.class, u.getValue());
|
||||
StructureDefinition sd = this.context.fetchResource(StructureDefinition.class, u.getValue(), parentProfile);
|
||||
if (sd != null && !types.contains(sd.getType())) {
|
||||
types.add(sd.getType());
|
||||
}
|
||||
|
@ -5210,7 +5210,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
}
|
||||
sdt = context.fetchResource(StructureDefinition.class, sdt.getBaseDefinition());
|
||||
sdt = context.fetchResource(StructureDefinition.class, sdt.getBaseDefinition(), sdt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -5533,7 +5533,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
String tail = null;
|
||||
if (profiles.isEmpty()) {
|
||||
if (type != null) {
|
||||
p = getProfileForType(type, checkDefn.getType());
|
||||
p = getProfileForType(type, checkDefn.getType(), profile);
|
||||
|
||||
// If dealing with a primitive type, then we need to check the current child against
|
||||
// the invariants (constraints) on the current element, because otherwise it only gets
|
||||
|
@ -5550,7 +5550,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
tail = url.substring(url.indexOf("#") + 1);
|
||||
url = url.substring(0, url.indexOf("#"));
|
||||
}
|
||||
p = this.context.fetchResource(StructureDefinition.class, url);
|
||||
p = this.context.fetchResource(StructureDefinition.class, url, profile);
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, ei.line(), ei.col(), ei.getPath(), p != null, I18nConstants.VALIDATION_VAL_UNKNOWN_PROFILE, profiles.get(0)) && ok;
|
||||
} else {
|
||||
elementValidated = true;
|
||||
|
@ -6020,7 +6020,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return false;
|
||||
}
|
||||
while (profile != null) {
|
||||
profile = context.fetchResource(StructureDefinition.class, profile.getBaseDefinition());
|
||||
profile = context.fetchResource(StructureDefinition.class, profile.getBaseDefinition(), profile);
|
||||
if (profile != null) {
|
||||
if (source.equals(profile.getUrl())) {
|
||||
return true;
|
||||
|
|
|
@ -546,7 +546,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
if (ref.startsWith("#") && qSrc.container != null) {
|
||||
vs = (ValueSet) loadContainedResource(errors, qSrc.containerPath, qSrc.container, ref.substring(1), ValueSet.class);
|
||||
} else {
|
||||
vs = resolveBindingReference(qSrc.q(), ref, qSrc.q().getUrl());
|
||||
vs = resolveBindingReference(qSrc.q(), ref, qSrc.q().getUrl(), qSrc.q());
|
||||
}
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), vs != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(ref))) {
|
||||
try {
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -19,7 +19,7 @@
|
|||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.4.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.127</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.128-SNAPSHOT</validator_test_case_version>
|
||||
<junit_jupiter_version>5.7.1</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||
<maven_surefire_version>3.0.0-M5</maven_surefire_version>
|
||||
|
|
Loading…
Reference in New Issue