More work on comparison functionality
This commit is contained in:
parent
3beb0c78e2
commit
bf5a2ba768
|
@ -135,21 +135,21 @@ public abstract class CanonicalResourceComparer extends ResourceComparer {
|
||||||
changedContentInterpretation = updateState(state, changedContentInterpretation);
|
changedContentInterpretation = updateState(state, changedContentInterpretation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatedMetadataState(boolean state, List<String> chMetadataFields) {
|
public void updatedMetadataState(boolean changed, List<String> chMetadataFields) {
|
||||||
changedMetadata = updateState(state ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedMetadata);
|
changedMetadata = updateState(changed ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedMetadata);
|
||||||
this.chMetadataFields = chMetadataFields;
|
this.chMetadataFields = chMetadataFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDefinitionsState(boolean state) {
|
public void updateDefinitionsState(boolean changed) {
|
||||||
changedDefinitions = updateState(state ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedDefinitions);
|
changedDefinitions = updateState(changed ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateContentState(boolean state) {
|
public void updateContentState(boolean changed) {
|
||||||
changedContent = updateState(state ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedContent);
|
changedContent = updateState(changed ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateContentInterpretationState(boolean state) {
|
public void updateContentInterpretationState(boolean changed) {
|
||||||
changedContentInterpretation = updateState(state ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedContentInterpretation);
|
changedContentInterpretation = updateState(changed ? ChangeAnalysisState.Changed : ChangeAnalysisState.NotChanged, changedContentInterpretation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean anyUpdates() {
|
public boolean anyUpdates() {
|
||||||
|
@ -236,59 +236,74 @@ public abstract class CanonicalResourceComparer extends ResourceComparer {
|
||||||
public boolean noUpdates() {
|
public boolean noUpdates() {
|
||||||
return !(changedMetadata.noteable() || changedDefinitions.noteable() || !changedContent.noteable() || !changedContentInterpretation.noteable());
|
return !(changedMetadata.noteable() || changedDefinitions.noteable() || !changedContent.noteable() || !changedContentInterpretation.noteable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean noChangeOtherThanMetadata(String[] metadataFields) {
|
||||||
|
if (changedDefinitions.noteable() || changedContent.noteable() || changedContentInterpretation.noteable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!changedMetadata.noteable()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (String s : this.chMetadataFields) {
|
||||||
|
if (!Utilities.existsInList(s, metadataFields)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CanonicalResourceComparer(ComparisonSession session) {
|
public CanonicalResourceComparer(ComparisonSession session) {
|
||||||
super(session);
|
super(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean compareMetadata(CanonicalResource left, CanonicalResource right, Map<String, StructuralMatch<String>> comp, CanonicalResourceComparison<? extends CanonicalResource> res, List<String> changes) {
|
protected boolean compareMetadata(CanonicalResource left, CanonicalResource right, Map<String, StructuralMatch<String>> comp, CanonicalResourceComparison<? extends CanonicalResource> res, List<String> changes, Base parent, String version) {
|
||||||
var changed = false;
|
var changed = false;
|
||||||
if (comparePrimitives("url", left.getUrlElement(), right.getUrlElement(), comp, IssueSeverity.ERROR, res)) {
|
if (comparePrimitivesWithTracking("url", left.getUrlElement(), right.getUrlElement(), comp, IssueSeverity.ERROR, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("url");
|
changes.add("url");
|
||||||
}
|
}
|
||||||
if (session.getForVersion() == null) {
|
if (session.getForVersion() == null) {
|
||||||
if (comparePrimitives("version", left.getVersionElement(), right.getVersionElement(), comp, IssueSeverity.ERROR, res)) {
|
if (comparePrimitivesWithTracking("version", left.getVersionElement(), right.getVersionElement(), comp, IssueSeverity.ERROR, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("version");
|
changes.add("version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (comparePrimitives("name", left.getNameElement(), right.getNameElement(), comp, IssueSeverity.INFORMATION, res)) {
|
if (comparePrimitivesWithTracking("name", left.getNameElement(), right.getNameElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("name");
|
changes.add("name");
|
||||||
}
|
}
|
||||||
if (comparePrimitives("title", left.getTitleElement(), right.getTitleElement(), comp, IssueSeverity.INFORMATION, res)) {
|
if (comparePrimitivesWithTracking("title", left.getTitleElement(), right.getTitleElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("title");
|
changes.add("title");
|
||||||
}
|
}
|
||||||
if (comparePrimitives("status", left.getStatusElement(), right.getStatusElement(), comp, IssueSeverity.INFORMATION, res)) {
|
if (comparePrimitivesWithTracking("status", left.getStatusElement(), right.getStatusElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("status");
|
changes.add("status");
|
||||||
}
|
}
|
||||||
if (comparePrimitives("experimental", left.getExperimentalElement(), right.getExperimentalElement(), comp, IssueSeverity.WARNING, res)) {
|
if (comparePrimitivesWithTracking("experimental", left.getExperimentalElement(), right.getExperimentalElement(), comp, IssueSeverity.WARNING, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("experimental");
|
changes.add("experimental");
|
||||||
}
|
}
|
||||||
if (session.getForVersion() == null) {
|
if (session.getForVersion() == null) {
|
||||||
if (comparePrimitives("date", left.getDateElement(), right.getDateElement(), comp, IssueSeverity.INFORMATION, res)) {
|
if (comparePrimitivesWithTracking("date", left.getDateElement(), right.getDateElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("date");
|
changes.add("date");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (comparePrimitives("publisher", left.getPublisherElement(), right.getPublisherElement(), comp, IssueSeverity.INFORMATION, res)) {
|
if (comparePrimitivesWithTracking("publisher", left.getPublisherElement(), right.getPublisherElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("publisher");
|
changes.add("publisher");
|
||||||
}
|
}
|
||||||
if (comparePrimitives("description", left.getDescriptionElement(), right.getDescriptionElement(), comp, IssueSeverity.NULL, res)) {
|
if (comparePrimitivesWithTracking("description", left.getDescriptionElement(), right.getDescriptionElement(), comp, IssueSeverity.NULL, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("description");
|
changes.add("description");
|
||||||
}
|
}
|
||||||
if (comparePrimitives("purpose", left.getPurposeElement(), right.getPurposeElement(), comp, IssueSeverity.NULL, res)) {
|
if (comparePrimitivesWithTracking("purpose", left.getPurposeElement(), right.getPurposeElement(), comp, IssueSeverity.NULL, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("purpose");
|
changes.add("purpose");
|
||||||
}
|
}
|
||||||
if (comparePrimitives("copyright", left.getCopyrightElement(), right.getCopyrightElement(), comp, IssueSeverity.INFORMATION, res)) {
|
if (comparePrimitivesWithTracking("copyright", left.getCopyrightElement(), right.getCopyrightElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
|
||||||
changed = true;
|
changed = true;
|
||||||
changes.add("copyright");
|
changes.add("copyright");
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import java.util.Map;
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
import org.hl7.fhir.r5.comparison.StructureDefinitionComparer.ProfileComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.model.BackboneElement;
|
import org.hl7.fhir.r5.model.BackboneElement;
|
||||||
|
@ -114,7 +114,7 @@ public class CapabilityStatementComparer extends CanonicalResourceComparer {
|
||||||
cs1.setStatus(left.getStatus());
|
cs1.setStatus(left.getStatus());
|
||||||
cs1.setDate(new Date());
|
cs1.setDate(new Date());
|
||||||
|
|
||||||
compareMetadata(left, right, res.getMetadata(), res, new ArrayList<>());
|
compareMetadata(left, right, res.getMetadata(), res, new ArrayList<>(), right, session.getForVersion());
|
||||||
comparePrimitives("kind", left.getKindElement(), right.getKindElement(), res.getMetadata(), IssueSeverity.ERROR, res);
|
comparePrimitives("kind", left.getKindElement(), right.getKindElement(), res.getMetadata(), IssueSeverity.ERROR, res);
|
||||||
compareCanonicalList("instantiates", left.getInstantiates(), right.getInstantiates(), res.getMetadata(), IssueSeverity.ERROR, res, cs.getInstantiates(), cs1.getInstantiates());
|
compareCanonicalList("instantiates", left.getInstantiates(), right.getInstantiates(), res.getMetadata(), IssueSeverity.ERROR, res, cs.getInstantiates(), cs1.getInstantiates());
|
||||||
compareCanonicalList("imports", left.getImports(), right.getImports(), res.getMetadata(), IssueSeverity.ERROR, res, cs.getImports(), cs1.getImports());
|
compareCanonicalList("imports", left.getImports(), right.getImports(), res.getMetadata(), IssueSeverity.ERROR, res, cs.getImports(), cs1.getImports());
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class CodeSystemComparer extends CanonicalResourceComparer {
|
||||||
|
|
||||||
|
|
||||||
List<String> chMetadata = new ArrayList<>();
|
List<String> chMetadata = new ArrayList<>();
|
||||||
boolean ch = compareMetadata(left, right, res.getMetadata(), res, chMetadata);
|
boolean ch = compareMetadata(left, right, res.getMetadata(), res, chMetadata, right, session.getForVersion());
|
||||||
if (comparePrimitives("versionNeeded", left.getVersionNeededElement(), right.getVersionNeededElement(), res.getMetadata(), IssueSeverity.INFORMATION, res)) {
|
if (comparePrimitives("versionNeeded", left.getVersionNeededElement(), right.getVersionNeededElement(), res.getMetadata(), IssueSeverity.INFORMATION, res)) {
|
||||||
ch = true;
|
ch = true;
|
||||||
chMetadata.add("versionNeeded");
|
chMetadata.add("versionNeeded");
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
|
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
|
||||||
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
import org.hl7.fhir.r5.comparison.StructureDefinitionComparer.ProfileComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ResourceComparer.PlaceHolderComparison;
|
import org.hl7.fhir.r5.comparison.ResourceComparer.PlaceHolderComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||||
|
@ -213,7 +213,7 @@ public class ComparisonRenderer implements IEvaluationContext {
|
||||||
private void renderProfile(String id, ProfileComparison comp) throws IOException {
|
private void renderProfile(String id, ProfileComparison comp) throws IOException {
|
||||||
String template = templates.get("Profile");
|
String template = templates.get("Profile");
|
||||||
Map<String, Base> vars = new HashMap<>();
|
Map<String, Base> vars = new HashMap<>();
|
||||||
ProfileComparer cs = new ProfileComparer(session, new ProfileUtilities(session.getContextLeft(), null, session.getPkpLeft()),
|
StructureDefinitionComparer cs = new StructureDefinitionComparer(session, new ProfileUtilities(session.getContextLeft(), null, session.getPkpLeft()),
|
||||||
new ProfileUtilities(session.getContextRight(), null, session.getPkpRight()));
|
new ProfileUtilities(session.getContextRight(), null, session.getPkpRight()));
|
||||||
vars.put("left", new StringType(comp.getLeft().present()));
|
vars.put("left", new StringType(comp.getLeft().present()));
|
||||||
vars.put("right", new StringType(comp.getRight().present()));
|
vars.put("right", new StringType(comp.getRight().present()));
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
|
import org.hl7.fhir.r5.comparison.CapabilityStatementComparer.CapabilityStatementComparison;
|
||||||
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
import org.hl7.fhir.r5.comparison.StructureDefinitionComparer.ProfileComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||||
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
import org.hl7.fhir.r5.conformance.profile.ProfileKnowledgeProvider;
|
||||||
|
@ -94,7 +94,7 @@ public class ComparisonSession {
|
||||||
compares.put(key, csc);
|
compares.put(key, csc);
|
||||||
return csc;
|
return csc;
|
||||||
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
|
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
|
||||||
ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(contextLeft, null, pkpLeft), new ProfileUtilities(contextRight, null, pkpRight));
|
StructureDefinitionComparer cs = new StructureDefinitionComparer(this, new ProfileUtilities(contextLeft, null, pkpLeft), new ProfileUtilities(contextRight, null, pkpRight));
|
||||||
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
|
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
|
||||||
compares.put(key, csc);
|
compares.put(key, csc);
|
||||||
return csc;
|
return csc;
|
||||||
|
|
|
@ -56,7 +56,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
|
|
||||||
import kotlin.NotImplementedError;
|
import kotlin.NotImplementedError;
|
||||||
|
|
||||||
public class ProfileComparer extends CanonicalResourceComparer implements ProfileKnowledgeProvider {
|
public class StructureDefinitionComparer extends CanonicalResourceComparer implements ProfileKnowledgeProvider {
|
||||||
|
|
||||||
public class ProfileComparison extends CanonicalResourceComparison<StructureDefinition> {
|
public class ProfileComparison extends CanonicalResourceComparison<StructureDefinition> {
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public class ProfileComparer extends CanonicalResourceComparer implements Profil
|
||||||
private ProfileUtilities utilsLeft;
|
private ProfileUtilities utilsLeft;
|
||||||
private ProfileUtilities utilsRight;
|
private ProfileUtilities utilsRight;
|
||||||
|
|
||||||
public ProfileComparer(ComparisonSession session, ProfileUtilities utilsLeft, ProfileUtilities utilsRight) {
|
public StructureDefinitionComparer(ComparisonSession session, ProfileUtilities utilsLeft, ProfileUtilities utilsRight) {
|
||||||
super(session);
|
super(session);
|
||||||
this.utilsLeft = utilsLeft;
|
this.utilsLeft = utilsLeft;
|
||||||
this.utilsRight = utilsRight;
|
this.utilsRight = utilsRight;
|
||||||
|
@ -147,7 +147,7 @@ public class ProfileComparer extends CanonicalResourceComparer implements Profil
|
||||||
sd1.setDate(new Date());
|
sd1.setDate(new Date());
|
||||||
|
|
||||||
List<String> chMetadata = new ArrayList<>();
|
List<String> chMetadata = new ArrayList<>();
|
||||||
boolean ch = compareMetadata(left, right, res.getMetadata(), res, chMetadata);
|
boolean ch = compareMetadata(left, right, res.getMetadata(), res, chMetadata, right, session.getForVersion());
|
||||||
if (comparePrimitives("fhirVersion", left.getFhirVersionElement(), right.getFhirVersionElement(), res.getMetadata(), IssueSeverity.WARNING, res)) {
|
if (comparePrimitives("fhirVersion", left.getFhirVersionElement(), right.getFhirVersionElement(), res.getMetadata(), IssueSeverity.WARNING, res)) {
|
||||||
ch = true;
|
ch = true;
|
||||||
chMetadata.add("fhirVersion");
|
chMetadata.add("fhirVersion");
|
||||||
|
@ -173,7 +173,7 @@ public class ProfileComparer extends CanonicalResourceComparer implements Profil
|
||||||
res.combined = sm;
|
res.combined = sm;
|
||||||
ln = new DefinitionNavigator(session.getContextLeft(), left, true);
|
ln = new DefinitionNavigator(session.getContextLeft(), left, true);
|
||||||
rn = new DefinitionNavigator(session.getContextRight(), right, true);
|
rn = new DefinitionNavigator(session.getContextRight(), right, true);
|
||||||
ch = compareDiff(ln.path(), null, ln, rn, res) || ch;
|
ch = compareDiff(ln.path(), null, ln, rn, res, right) || ch;
|
||||||
// we don't preserve the differences - we only want the annotations
|
// we don't preserve the differences - we only want the annotations
|
||||||
}
|
}
|
||||||
res.updateDefinitionsState(ch);
|
res.updateDefinitionsState(ch);
|
||||||
|
@ -389,7 +389,7 @@ public class ProfileComparer extends CanonicalResourceComparer implements Profil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean compareDiff(String path, String sliceName, DefinitionNavigator left, DefinitionNavigator right, ProfileComparison res) throws DefinitionException, FHIRFormatError, IOException {
|
private boolean compareDiff(String path, String sliceName, DefinitionNavigator left, DefinitionNavigator right, ProfileComparison res, Base parent) throws DefinitionException, FHIRFormatError, IOException {
|
||||||
assert(path != null);
|
assert(path != null);
|
||||||
assert(left != null);
|
assert(left != null);
|
||||||
assert(right != null);
|
assert(right != null);
|
||||||
|
@ -403,6 +403,13 @@ public class ProfileComparer extends CanonicalResourceComparer implements Profil
|
||||||
// ruleEqual(comp, res, left.current().getIsModifierElement(), right.current().getIsModifierElement(), "isModifier", path); - this check belongs in the core
|
// ruleEqual(comp, res, left.current().getIsModifierElement(), right.current().getIsModifierElement(), "isModifier", path); - this check belongs in the core
|
||||||
// ruleEqual(comp, res, left.current().getIsSummaryElement(), right.current().getIsSummaryElement(), "isSummary", path); - so does this
|
// ruleEqual(comp, res, left.current().getIsSummaryElement(), right.current().getIsSummaryElement(), "isSummary", path); - so does this
|
||||||
|
|
||||||
|
if (left.current() == null && right.current() == null) {
|
||||||
|
// both are sparse at this point, do nothing
|
||||||
|
} else if (left.current() == null) {
|
||||||
|
VersionComparisonAnnotation.markAdded(right.current(), session.getForVersion());
|
||||||
|
} else if (right.current() == null) {
|
||||||
|
VersionComparisonAnnotation.markDeleted(right.parent(), session.getForVersion(), "element", left.current());
|
||||||
|
} else {
|
||||||
// descriptive properties from ElementDefinition - merge them:
|
// descriptive properties from ElementDefinition - merge them:
|
||||||
comparePrimitivesWithTracking("label", left.current().getLabelElement(), right.current().getLabelElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion());
|
comparePrimitivesWithTracking("label", left.current().getLabelElement(), right.current().getLabelElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion());
|
||||||
def = comparePrimitivesWithTracking("short", left.current().getShortElement(), right.current().getShortElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
def = comparePrimitivesWithTracking("short", left.current().getShortElement(), right.current().getShortElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
||||||
|
@ -412,9 +419,9 @@ public class ProfileComparer extends CanonicalResourceComparer implements Profil
|
||||||
def = comparePrimitivesWithTracking("mustSupport", left.current().getMustSupportElement(), right.current().getMustSupportElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
def = comparePrimitivesWithTracking("mustSupport", left.current().getMustSupportElement(), right.current().getMustSupportElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
||||||
def = comparePrimitivesWithTracking("min", left.current().getMinElement(), right.current().getMinElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
def = comparePrimitivesWithTracking("min", left.current().getMinElement(), right.current().getMinElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
||||||
def = comparePrimitivesWithTracking("max", left.current().getMaxElement(), right.current().getMaxElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
def = comparePrimitivesWithTracking("max", left.current().getMaxElement(), right.current().getMaxElement(), null, IssueSeverity.INFORMATION, null, right.current(), session.getForVersion()) || def;
|
||||||
|
}
|
||||||
// add the children
|
// add the children
|
||||||
def = compareDiffChildren(path, left, right, right.current(), res) || def;
|
def = compareDiffChildren(path, left, right, right.current() == null ? parent : right.current(), res) || def;
|
||||||
//
|
//
|
||||||
// // now process the slices
|
// // now process the slices
|
||||||
// if (left.current().hasSlicing() || right.current().hasSlicing()) {
|
// if (left.current().hasSlicing() || right.current().hasSlicing()) {
|
||||||
|
@ -491,7 +498,8 @@ public class ProfileComparer extends CanonicalResourceComparer implements Profil
|
||||||
VersionComparisonAnnotation.markDeleted(parent, session.getForVersion(), "element", l.current());
|
VersionComparisonAnnotation.markDeleted(parent, session.getForVersion(), "element", l.current());
|
||||||
res.updateContentState(true);
|
res.updateContentState(true);
|
||||||
} else {
|
} else {
|
||||||
def = compareDiff(l.path(), null, l, r, res) || def;
|
matchR.add(r);
|
||||||
|
def = compareDiff(l.path(), null, l, r, res, parent) || def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (DefinitionNavigator r : rc) {
|
for (DefinitionNavigator r : rc) {
|
|
@ -125,7 +125,7 @@ public class ValueSetComparer extends CanonicalResourceComparer {
|
||||||
vs1.setDate(new Date());
|
vs1.setDate(new Date());
|
||||||
|
|
||||||
List<String> chMetadata = new ArrayList<>();
|
List<String> chMetadata = new ArrayList<>();
|
||||||
var ch = compareMetadata(left, right, res.getMetadata(), res, chMetadata);
|
var ch = compareMetadata(left, right, res.getMetadata(), res, chMetadata, right, session.getForVersion());
|
||||||
var def = false;
|
var def = false;
|
||||||
if (comparePrimitives("immutable", left.getImmutableElement(), right.getImmutableElement(), res.getMetadata(), IssueSeverity.WARNING, res)) {
|
if (comparePrimitives("immutable", left.getImmutableElement(), right.getImmutableElement(), res.getMetadata(), IssueSeverity.WARNING, res)) {
|
||||||
ch = true;
|
ch = true;
|
||||||
|
|
|
@ -38,13 +38,15 @@ public class VersionComparisonAnnotation {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void annotate(Base base, String version, CanonicalResourceComparison<? extends CanonicalResource> comp) {
|
public static void annotate(Base base, String version, CanonicalResourceComparison<? extends CanonicalResource> comp) {
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
VersionComparisonAnnotation vca = new VersionComparisonAnnotation(comp.noUpdates() ? AnotationType.NoChange : AnotationType.Changed, version);
|
VersionComparisonAnnotation vca = (VersionComparisonAnnotation) base.getUserData(USER_DATA_NAME);
|
||||||
vca.comp = comp;
|
if (vca == null) {
|
||||||
|
vca = new VersionComparisonAnnotation(comp.noUpdates() ? AnotationType.NoChange : AnotationType.Changed, version);
|
||||||
base.setUserData(USER_DATA_NAME, vca);
|
base.setUserData(USER_DATA_NAME, vca);
|
||||||
}
|
}
|
||||||
|
vca.comp = comp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,7 +250,7 @@ public class VersionComparisonAnnotation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderSummary(Base base, XhtmlNode x, String version) {
|
public static void renderSummary(Base base, XhtmlNode x, String version, String... metadataFields) {
|
||||||
if (base.hasUserData(USER_DATA_NAME)) {
|
if (base.hasUserData(USER_DATA_NAME)) {
|
||||||
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(USER_DATA_NAME);
|
VersionComparisonAnnotation self = (VersionComparisonAnnotation) base.getUserData(USER_DATA_NAME);
|
||||||
switch (self.type) {
|
switch (self.type) {
|
||||||
|
@ -258,9 +260,14 @@ public class VersionComparisonAnnotation {
|
||||||
spanInner.tx(" Added");
|
spanInner.tx(" Added");
|
||||||
return;
|
return;
|
||||||
case Changed:
|
case Changed:
|
||||||
|
if (self.comp.noChangeOtherThanMetadata(metadataFields)) {
|
||||||
|
x.span("color: #eeeeee").tx("n/c");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
spanInner = x.span("background-color: #fff2ff; border-left: solid 3px #ffa0ff; margin: 2px; padding: 2px", "This content has been added since "+version);
|
spanInner = x.span("background-color: #fff2ff; border-left: solid 3px #ffa0ff; margin: 2px; padding: 2px", "This content has been added since "+version);
|
||||||
spanInner.img("icon-change-edit.png", "icon");
|
spanInner.img("icon-change-edit.png", "icon");
|
||||||
spanInner.tx(" Changed");
|
spanInner.tx(" Changed");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case Deleted:
|
case Deleted:
|
||||||
spanInner = x.span("background-color: #fff2ff; border-left: solid 3px #ffa0ff; margin: 2px; padding: 2px", "This content has been added since "+version);
|
spanInner = x.span("background-color: #fff2ff; border-left: solid 3px #ffa0ff; margin: 2px; padding: 2px", "This content has been added since "+version);
|
||||||
|
@ -277,4 +284,5 @@ public class VersionComparisonAnnotation {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -3094,7 +3094,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||||
List<String> anchors = makeAnchors(ec, anchorPrefix);
|
List<String> anchors = makeAnchors(ec, anchorPrefix);
|
||||||
String title = ec.getId();
|
String title = ec.getId();
|
||||||
XhtmlNode tr = t.tr();
|
XhtmlNode tr = t.tr();
|
||||||
XhtmlNode sp = tr.td("structure").colspan(2).spanClss("self-link-parent");
|
XhtmlNode sp = VersionComparisonAnnotation.render(ec, tr.td("structure").colspan(2).spanClss("self-link-parent"));
|
||||||
for (String s : anchors) {
|
for (String s : anchors) {
|
||||||
sp.an(s).tx(" ");
|
sp.an(s).tx(" ");
|
||||||
}
|
}
|
||||||
|
@ -3104,7 +3104,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||||
if (isProfiledExtension(ec)) {
|
if (isProfiledExtension(ec)) {
|
||||||
StructureDefinition extDefn = context.getContext().fetchResource(StructureDefinition.class, ec.getType().get(0).getProfile().get(0).getValue());
|
StructureDefinition extDefn = context.getContext().fetchResource(StructureDefinition.class, ec.getType().get(0).getProfile().get(0).getValue());
|
||||||
if (extDefn == null) {
|
if (extDefn == null) {
|
||||||
generateElementInner(t, sd, ec, 1, null, compareElement, null);
|
generateElementInner(t, sd, ec, 1, null, compareElement, null, false);
|
||||||
} else {
|
} else {
|
||||||
ElementDefinition valueDefn = getExtensionValueDefinition(extDefn);
|
ElementDefinition valueDefn = getExtensionValueDefinition(extDefn);
|
||||||
ElementDefinition compareValueDefn = null;
|
ElementDefinition compareValueDefn = null;
|
||||||
|
@ -3112,19 +3112,34 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||||
StructureDefinition compareExtDefn = context.getContext().fetchResource(StructureDefinition.class, compareElement.getType().get(0).getProfile().get(0).getValue());
|
StructureDefinition compareExtDefn = context.getContext().fetchResource(StructureDefinition.class, compareElement.getType().get(0).getProfile().get(0).getValue());
|
||||||
compareValueDefn = getExtensionValueDefinition(extDefn);
|
compareValueDefn = getExtensionValueDefinition(extDefn);
|
||||||
} catch (Exception except) {}
|
} catch (Exception except) {}
|
||||||
generateElementInner(t, sd, ec, valueDefn == null || valueDefn.prohibited() ? 2 : 3, valueDefn, compareElement, compareValueDefn);
|
generateElementInner(t, sd, ec, valueDefn == null || valueDefn.prohibited() ? 2 : 3, valueDefn, compareElement, compareValueDefn, false);
|
||||||
// generateElementInner(b, extDefn, extDefn.getSnapshot().getElement().get(0), valueDefn == null ? 2 : 3, valueDefn);
|
// generateElementInner(b, extDefn, extDefn.getSnapshot().getElement().get(0), valueDefn == null ? 2 : 3, valueDefn);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
generateElementInner(t, sd, ec, mode, null, compareElement, null);
|
generateElementInner(t, sd, ec, mode, null, compareElement, null, false);
|
||||||
if (ec.hasSlicing()) {
|
if (ec.hasSlicing()) {
|
||||||
generateSlicing(t, sd, ec, ec.getSlicing(), compareElement, mode);
|
generateSlicing(t, sd, ec, ec.getSlicing(), compareElement, mode, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.tx("\r\n");
|
t.tx("\r\n");
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
for (Base b : VersionComparisonAnnotation.getDeleted(sd, "element")) {
|
||||||
|
ElementDefinition ec = (ElementDefinition) b;
|
||||||
|
String title = ec.getId();
|
||||||
|
XhtmlNode tr = t.tr();
|
||||||
|
XhtmlNode sp = VersionComparisonAnnotation.render(ec, tr.td("structure").colspan(2).spanClss("self-link-parent"));
|
||||||
|
sp.span("color: grey", null).tx(Integer.toString(i++));
|
||||||
|
sp.b().tx(". "+title);
|
||||||
|
|
||||||
|
generateElementInner(t, sd, ec, mode, null, null, null, true);
|
||||||
|
if (ec.hasSlicing()) {
|
||||||
|
generateSlicing(t, sd, ec, ec.getSlicing(), null, mode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
t.tx("\r\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ElementDefinition getElementById(String url, String id) {
|
public ElementDefinition getElementById(String url, String id) {
|
||||||
|
@ -3416,106 +3431,106 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||||
return "color:DarkGray;text-decoration:line-through";
|
return "color:DarkGray;text-decoration:line-through";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateElementInner(XhtmlNode tbl, StructureDefinition sd, ElementDefinition d, int mode, ElementDefinition value, ElementDefinition compare, ElementDefinition compareValue) throws FHIRException, IOException {
|
private void generateElementInner(XhtmlNode tbl, StructureDefinition sd, ElementDefinition d, int mode, ElementDefinition value, ElementDefinition compare, ElementDefinition compareValue, boolean strikethrough) throws FHIRException, IOException {
|
||||||
boolean root = !d.getPath().contains(".");
|
boolean root = !d.getPath().contains(".");
|
||||||
boolean slicedExtension = d.hasSliceName() && (d.getPath().endsWith(".extension") || d.getPath().endsWith(".modifierExtension"));
|
boolean slicedExtension = d.hasSliceName() && (d.getPath().endsWith(".extension") || d.getPath().endsWith(".modifierExtension"));
|
||||||
// int slicedExtensionMode = (mode == GEN_MODE_KEY) && slicedExtension ? GEN_MODE_SNAP : mode; // see ProfileUtilities.checkExtensionDoco / Task 3970
|
// int slicedExtensionMode = (mode == GEN_MODE_KEY) && slicedExtension ? GEN_MODE_SNAP : mode; // see ProfileUtilities.checkExtensionDoco / Task 3970
|
||||||
if (d.hasSliceName()) {
|
if (d.hasSliceName()) {
|
||||||
tableRow(tbl, "SliceName", "profiling.html#slicing").tx(d.getSliceName());
|
tableRow(tbl, "SliceName", "profiling.html#slicing", strikethrough).tx(d.getSliceName());
|
||||||
}
|
}
|
||||||
tableRow(tbl, "Definition", null, compareMarkdown(sd.getName(), d.getDefinitionElement(), (compare==null) || slicedExtension ? null : compare.getDefinitionElement(), mode));
|
tableRow(tbl, "Definition", null, strikethrough, compareMarkdown(sd.getName(), d.getDefinitionElement(), (compare==null) || slicedExtension ? null : compare.getDefinitionElement(), mode));
|
||||||
tableRow(tbl, "Short", null, compareString(d.hasShort() ? d.getShort() : null, d.getShortElement(), null, "short", d, compare!= null && compare.hasShortElement() ? compare.getShort() : null, null, mode));
|
tableRow(tbl, "Short", null, strikethrough, compareString(d.hasShort() ? d.getShort() : null, d.getShortElement(), null, "short", d, compare!= null && compare.hasShortElement() ? compare.getShort() : null, null, mode));
|
||||||
tableRow(tbl, "Note", null, businessIdWarning(sd.getName(), tail(d.getPath())));
|
tableRow(tbl, "Note", null, strikethrough, businessIdWarning(sd.getName(), tail(d.getPath())));
|
||||||
tableRow(tbl, "Control", "conformance-rules.html#conformance", describeCardinality(d, compare, mode));
|
tableRow(tbl, "Control", "conformance-rules.html#conformance", strikethrough, describeCardinality(d, compare, mode));
|
||||||
tableRow(tbl, "Binding", "terminologies.html", describeBinding(sd, d, d.getPath(), compare, mode));
|
tableRow(tbl, "Binding", "terminologies.html", strikethrough, describeBinding(sd, d, d.getPath(), compare, mode));
|
||||||
if (d.hasContentReference()) {
|
if (d.hasContentReference()) {
|
||||||
tableRow(tbl, "Type", null, "See " + d.getContentReference().substring(1));
|
tableRow(tbl, "Type", null, strikethrough, "See " + d.getContentReference().substring(1));
|
||||||
} else {
|
} else {
|
||||||
tableRow(tbl, "Type", "datatypes.html", describeTypes(d.getType(), false, compare, mode, value, compareValue, sd));
|
tableRow(tbl, "Type", "datatypes.html", strikethrough, describeTypes(d.getType(), false, compare, mode, value, compareValue, sd));
|
||||||
}
|
}
|
||||||
if (d.hasExtension(ToolingExtensions.EXT_DEF_TYPE)) {
|
if (d.hasExtension(ToolingExtensions.EXT_DEF_TYPE)) {
|
||||||
tableRow(tbl, "Default Type", "datatypes.html", ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_DEF_TYPE));
|
tableRow(tbl, "Default Type", "datatypes.html", strikethrough, ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_DEF_TYPE));
|
||||||
}
|
}
|
||||||
if (d.hasExtension(ToolingExtensions.EXT_TYPE_SPEC)) {
|
if (d.hasExtension(ToolingExtensions.EXT_TYPE_SPEC)) {
|
||||||
tableRow(tbl, Utilities.pluralize("Type Specifier", d.getExtensionsByUrl(ToolingExtensions.EXT_TYPE_SPEC).size()), "datatypes.html", formatTypeSpecifiers(d));
|
tableRow(tbl, Utilities.pluralize("Type Specifier", d.getExtensionsByUrl(ToolingExtensions.EXT_TYPE_SPEC).size()), "datatypes.html", strikethrough, formatTypeSpecifiers(d));
|
||||||
}
|
}
|
||||||
if (d.getPath().endsWith("[x]") && !d.prohibited()) {
|
if (d.getPath().endsWith("[x]") && !d.prohibited()) {
|
||||||
tableRow(tbl, "[x] Note", null).ahWithText("See ", spec("formats.html#choice"), null, "Choice of Data Types", " for further information about how to use [x]");
|
tableRow(tbl, "[x] Note", null, strikethrough).ahWithText("See ", spec("formats.html#choice"), null, "Choice of Data Types", " for further information about how to use [x]");
|
||||||
}
|
}
|
||||||
tableRow(tbl, "Is Modifier", "conformance-rules.html#ismodifier", displayBoolean(d.getIsModifier(), d.getIsModifierElement(), "isModifier", d, null, mode));
|
tableRow(tbl, "Is Modifier", "conformance-rules.html#ismodifier", strikethrough, displayBoolean(d.getIsModifier(), d.getIsModifierElement(), "isModifier", d, null, mode));
|
||||||
if (d.getMustHaveValue()) {
|
if (d.getMustHaveValue()) {
|
||||||
tableRow(tbl, "Primitive Value", "elementdefinition.html#primitives", "This primitive type must have a value (the value must be present, and cannot be replaced by an extension)");
|
tableRow(tbl, "Primitive Value", "elementdefinition.html#primitives", strikethrough, "This primitive type must have a value (the value must be present, and cannot be replaced by an extension)");
|
||||||
} else if (d.hasValueAlternatives()) {
|
} else if (d.hasValueAlternatives()) {
|
||||||
tableRow(tbl, "Primitive Value", "elementdefinition.html#primitives", renderCanonicalList(d.getValueAlternatives()));
|
tableRow(tbl, "Primitive Value", "elementdefinition.html#primitives", strikethrough, renderCanonicalList(d.getValueAlternatives()));
|
||||||
} else if (hasPrimitiveTypes(d)) {
|
} else if (hasPrimitiveTypes(d)) {
|
||||||
tableRow(tbl, "Primitive Value", "elementdefinition.html#primitives", "This primitive element may be present, or absent, or replaced by an extension");
|
tableRow(tbl, "Primitive Value", "elementdefinition.html#primitives", strikethrough, "This primitive element may be present, or absent, or replaced by an extension");
|
||||||
}
|
}
|
||||||
if (ToolingExtensions.hasAllowedUnits(d)) {
|
if (ToolingExtensions.hasAllowedUnits(d)) {
|
||||||
tableRow(tbl, "Allowed Units", "http://hl7.org/fhir/extensions/StructureDefinition-elementdefinition-allowedUnits.html", describeAllowedUnits(d));
|
tableRow(tbl, "Allowed Units", "http://hl7.org/fhir/extensions/StructureDefinition-elementdefinition-allowedUnits.html", strikethrough, describeAllowedUnits(d));
|
||||||
}
|
}
|
||||||
tableRow(tbl, "Must Support", "conformance-rules.html#mustSupport", displayBoolean(d.getMustSupport(), d.getMustSupportElement(), "mustSupport", d, compare==null ? null : compare.getMustSupportElement(), mode));
|
tableRow(tbl, "Must Support", "conformance-rules.html#mustSupport", strikethrough, displayBoolean(d.getMustSupport(), d.getMustSupportElement(), "mustSupport", d, compare==null ? null : compare.getMustSupportElement(), mode));
|
||||||
if (d.getMustSupport()) {
|
if (d.getMustSupport()) {
|
||||||
if (hasMustSupportTypes(d.getType())) {
|
if (hasMustSupportTypes(d.getType())) {
|
||||||
tableRow(tbl, "Must Support Types", "datatypes.html", describeTypes(d.getType(), true, compare, mode, null, null, sd));
|
tableRow(tbl, "Must Support Types", "datatypes.html", strikethrough, describeTypes(d.getType(), true, compare, mode, null, null, sd));
|
||||||
} else if (hasChoices(d.getType())) {
|
} else if (hasChoices(d.getType())) {
|
||||||
tableRow(tbl, "Must Support Types", "datatypes.html", "No must-support rules about the choice of types/profiles");
|
tableRow(tbl, "Must Support Types", "datatypes.html", strikethrough, "No must-support rules about the choice of types/profiles");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (root && sd.getKind() == StructureDefinitionKind.LOGICAL) {
|
if (root && sd.getKind() == StructureDefinitionKind.LOGICAL) {
|
||||||
tableRow(tbl, "Logical Model", null, ToolingExtensions.readBoolExtension(sd, ToolingExtensions.EXT_LOGICAL_TARGET) ? "This logical model can be the target of a reference" : "This logical model cannot be the target of a reference");
|
tableRow(tbl, "Logical Model", null, strikethrough, ToolingExtensions.readBoolExtension(sd, ToolingExtensions.EXT_LOGICAL_TARGET) ? "This logical model can be the target of a reference" : "This logical model cannot be the target of a reference");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root && sd.hasExtension(ToolingExtensions.EXT_SD_IMPOSE_PROFILE)) {
|
if (root && sd.hasExtension(ToolingExtensions.EXT_SD_IMPOSE_PROFILE)) {
|
||||||
tableRow(tbl, "Impose Profile", "http://hl7.org/fhir/extensions/StructureDefinition-structuredefinition-imposeProfile.html",
|
tableRow(tbl, "Impose Profile", "http://hl7.org/fhir/extensions/StructureDefinition-structuredefinition-imposeProfile.html", strikethrough,
|
||||||
renderCanonicalListExt(sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_IMPOSE_PROFILE)));
|
renderCanonicalListExt(sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_IMPOSE_PROFILE)));
|
||||||
}
|
}
|
||||||
if (root && sd.hasExtension(ToolingExtensions.EXT_SD_COMPLIES_WITH_PROFILE)) {
|
if (root && sd.hasExtension(ToolingExtensions.EXT_SD_COMPLIES_WITH_PROFILE)) {
|
||||||
tableRow(tbl, "Complies with Profile", "http://hl7.org/fhir/extensions/StructureDefinition-structuredefinition-compliesWithProfile.html",
|
tableRow(tbl, "Complies with Profile", "http://hl7.org/fhir/extensions/StructureDefinition-structuredefinition-compliesWithProfile.html", strikethrough,
|
||||||
renderCanonicalListExt(sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_COMPLIES_WITH_PROFILE)));
|
renderCanonicalListExt(sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_COMPLIES_WITH_PROFILE)));
|
||||||
}
|
}
|
||||||
tableRow(tbl, "Obligations", null, describeObligations(d, root, sd));
|
tableRow(tbl, "Obligations", null, strikethrough, describeObligations(d, root, sd));
|
||||||
|
|
||||||
if (d.hasExtension(ToolingExtensions.EXT_EXTENSION_STYLE)) {
|
if (d.hasExtension(ToolingExtensions.EXT_EXTENSION_STYLE)) {
|
||||||
String es = d.getExtensionString(ToolingExtensions.EXT_EXTENSION_STYLE);
|
String es = d.getExtensionString(ToolingExtensions.EXT_EXTENSION_STYLE);
|
||||||
if ("named-elements".equals(es)) {
|
if ("named-elements".equals(es)) {
|
||||||
if (context.hasLink(KnownLinkType.JSON_NAMES)) {
|
if (context.hasLink(KnownLinkType.JSON_NAMES)) {
|
||||||
tableRow(tbl, "Extension Style", context.getLink(KnownLinkType.JSON_NAMES), "This element can be extended by named JSON elements");
|
tableRow(tbl, "Extension Style", context.getLink(KnownLinkType.JSON_NAMES), strikethrough, "This element can be extended by named JSON elements");
|
||||||
} else {
|
} else {
|
||||||
tableRow(tbl, "Extension Style", ToolingExtensions.WEB_EXTENSION_STYLE, "This element can be extended by named JSON elements");
|
tableRow(tbl, "Extension Style", ToolingExtensions.WEB_EXTENSION_STYLE, strikethrough, "This element can be extended by named JSON elements");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d.getPath().contains(".") && ToolingExtensions.hasExtension(sd, ToolingExtensions.EXT_BINDING_STYLE)) {
|
if (!d.getPath().contains(".") && ToolingExtensions.hasExtension(sd, ToolingExtensions.EXT_BINDING_STYLE)) {
|
||||||
tableRow(tbl, "Binding Style", ToolingExtensions.WEB_BINDING_STYLE,
|
tableRow(tbl, "Binding Style", ToolingExtensions.WEB_BINDING_STYLE, strikethrough,
|
||||||
"This type can be bound to a value set using the " + ToolingExtensions.readStringExtension(sd, ToolingExtensions.EXT_BINDING_STYLE)+" binding style");
|
"This type can be bound to a value set using the " + ToolingExtensions.readStringExtension(sd, ToolingExtensions.EXT_BINDING_STYLE)+" binding style");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.hasExtension(ToolingExtensions.EXT_DATE_FORMAT)) {
|
if (d.hasExtension(ToolingExtensions.EXT_DATE_FORMAT)) {
|
||||||
tableRow(tbl, "Date Format", null, ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_DATE_FORMAT));
|
tableRow(tbl, "Date Format", null, strikethrough, ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_DATE_FORMAT));
|
||||||
}
|
}
|
||||||
String ide = ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_ID_EXPECTATION);
|
String ide = ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_ID_EXPECTATION);
|
||||||
if (ide != null) {
|
if (ide != null) {
|
||||||
if (ide.equals("optional")) {
|
if (ide.equals("optional")) {
|
||||||
tableRow(tbl, "ID Expectation", null, "Id may or not be present (this is the default for elements but not resources)");
|
tableRow(tbl, "ID Expectation", null, strikethrough, "Id may or not be present (this is the default for elements but not resources)");
|
||||||
} else if (ide.equals("required")) {
|
} else if (ide.equals("required")) {
|
||||||
tableRow(tbl, "ID Expectation", null, "Id is required to be present (this is the default for resources but not elements)");
|
tableRow(tbl, "ID Expectation", null, strikethrough, "Id is required to be present (this is the default for resources but not elements)");
|
||||||
} else if (ide.equals("required")) {
|
} else if (ide.equals("required")) {
|
||||||
tableRow(tbl, "ID Expectation", null, "An ID is not allowed in this context");
|
tableRow(tbl, "ID Expectation", null, strikethrough, "An ID is not allowed in this context");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tooling extensions for formats
|
// tooling extensions for formats
|
||||||
if (ToolingExtensions.hasExtensions(d, ToolingExtensions.EXT_JSON_EMPTY, ToolingExtensions.EXT_JSON_PROP_KEY, ToolingExtensions.EXT_JSON_NULLABLE,
|
if (ToolingExtensions.hasExtensions(d, ToolingExtensions.EXT_JSON_EMPTY, ToolingExtensions.EXT_JSON_PROP_KEY, ToolingExtensions.EXT_JSON_NULLABLE,
|
||||||
ToolingExtensions.EXT_JSON_NAME, ToolingExtensions.EXT_JSON_PRIMITIVE_CHOICE)) {
|
ToolingExtensions.EXT_JSON_NAME, ToolingExtensions.EXT_JSON_PRIMITIVE_CHOICE)) {
|
||||||
tableRow(tbl, "JSON Format", null, describeJson(d));
|
tableRow(tbl, "JSON Format", null, strikethrough, describeJson(d));
|
||||||
}
|
}
|
||||||
if (d.hasExtension(ToolingExtensions.EXT_XML_NAMESPACE) || sd.hasExtension(ToolingExtensions.EXT_XML_NAMESPACE) || d.hasExtension(ToolingExtensions.EXT_XML_NAME) || (root && sd.hasExtension(ToolingExtensions.EXT_XML_NO_ORDER)) ||
|
if (d.hasExtension(ToolingExtensions.EXT_XML_NAMESPACE) || sd.hasExtension(ToolingExtensions.EXT_XML_NAMESPACE) || d.hasExtension(ToolingExtensions.EXT_XML_NAME) || (root && sd.hasExtension(ToolingExtensions.EXT_XML_NO_ORDER)) ||
|
||||||
d.hasRepresentation()) {
|
d.hasRepresentation()) {
|
||||||
tableRow(tbl, "XML Format", null, describeXml(sd, d, root));
|
tableRow(tbl, "XML Format", null, strikethrough, describeXml(sd, d, root));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.hasExtension(ToolingExtensions.EXT_IMPLIED_PREFIX)) {
|
if (d.hasExtension(ToolingExtensions.EXT_IMPLIED_PREFIX)) {
|
||||||
tableRow(tbl, "String Format", null).codeWithText("When this element is read ", ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_IMPLIED_PREFIX), "is prefixed to the value before validation");
|
tableRow(tbl, "String Format", null, strikethrough).codeWithText("When this element is read ", ToolingExtensions.readStringExtension(d, ToolingExtensions.EXT_IMPLIED_PREFIX), "is prefixed to the value before validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.hasExtension(ToolingExtensions.EXT_STANDARDS_STATUS)) {
|
if (d.hasExtension(ToolingExtensions.EXT_STANDARDS_STATUS)) {
|
||||||
|
@ -3525,29 +3540,29 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||||
if (sdb != null) {
|
if (sdb != null) {
|
||||||
StandardsStatus base = determineStandardsStatus(sdb, (ElementDefinition) d.getUserData("derived.pointer"));
|
StandardsStatus base = determineStandardsStatus(sdb, (ElementDefinition) d.getUserData("derived.pointer"));
|
||||||
if (base != null) {
|
if (base != null) {
|
||||||
tableRow(tbl, "Standards Status", "versions.html#std-process", ss.toDisplay()+" (from "+base.toDisplay()+")");
|
tableRow(tbl, "Standards Status", "versions.html#std-process", strikethrough, ss.toDisplay()+" (from "+base.toDisplay()+")");
|
||||||
} else {
|
} else {
|
||||||
tableRow(tbl, "Standards Status", "versions.html#std-process", ss.toDisplay());
|
tableRow(tbl, "Standards Status", "versions.html#std-process", strikethrough, ss.toDisplay());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tableRow(tbl, "Standards Status", "versions.html#std-process", ss.toDisplay());
|
tableRow(tbl, "Standards Status", "versions.html#std-process", strikethrough, ss.toDisplay());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode != GEN_MODE_DIFF && d.hasIsSummary()) {
|
if (mode != GEN_MODE_DIFF && d.hasIsSummary()) {
|
||||||
tableRow(tbl, "Summary", "search.html#summary", Boolean.toString(d.getIsSummary()));
|
tableRow(tbl, "Summary", "search.html#summary", strikethrough, Boolean.toString(d.getIsSummary()));
|
||||||
}
|
}
|
||||||
tableRow(tbl, "Requirements", null, compareMarkdown(sd.getName(), d.getRequirementsElement(), (compare==null) || slicedExtension ? null : compare.getRequirementsElement(), mode));
|
tableRow(tbl, "Requirements", null, strikethrough, compareMarkdown(sd.getName(), d.getRequirementsElement(), (compare==null) || slicedExtension ? null : compare.getRequirementsElement(), mode));
|
||||||
tableRow(tbl, "Alternate Names", null, compareSimpleTypeLists(d.getAlias(), ((compare==null) || slicedExtension ? null : compare.getAlias()), mode));
|
tableRow(tbl, "Alternate Names", null, strikethrough, compareSimpleTypeLists(d.getAlias(), ((compare==null) || slicedExtension ? null : compare.getAlias()), mode));
|
||||||
tableRow(tbl, "Comments", null, compareMarkdown(sd.getName(), d.getCommentElement(), (compare==null) || slicedExtension ? null : compare.getCommentElement(), mode));
|
tableRow(tbl, "Comments", null, strikethrough, compareMarkdown(sd.getName(), d.getCommentElement(), (compare==null) || slicedExtension ? null : compare.getCommentElement(), mode));
|
||||||
tableRow(tbl, "Max Length", null, compareString(d.hasMaxLength() ? toStr(d.getMaxLength()) : null, d.getMaxLengthElement(), null, "maxLength", d, compare!= null && compare.hasMaxLengthElement() ? toStr(compare.getMaxLength()) : null, null, mode));
|
tableRow(tbl, "Max Length", null, strikethrough, compareString(d.hasMaxLength() ? toStr(d.getMaxLength()) : null, d.getMaxLengthElement(), null, "maxLength", d, compare!= null && compare.hasMaxLengthElement() ? toStr(compare.getMaxLength()) : null, null, mode));
|
||||||
tableRow(tbl, "Default Value", null, encodeValue(d.getDefaultValue(), "defaultValue", d, compare==null ? null : compare.getDefaultValue(), mode));
|
tableRow(tbl, "Default Value", null, strikethrough, encodeValue(d.getDefaultValue(), "defaultValue", d, compare==null ? null : compare.getDefaultValue(), mode));
|
||||||
tableRow(tbl, "Meaning if Missing", null, d.getMeaningWhenMissing());
|
tableRow(tbl, "Meaning if Missing", null, strikethrough, d.getMeaningWhenMissing());
|
||||||
tableRow(tbl, "Fixed Value", null, encodeValue(d.getFixed(), "fixed", d, compare==null ? null : compare.getFixed(), mode));
|
tableRow(tbl, "Fixed Value", null, strikethrough, encodeValue(d.getFixed(), "fixed", d, compare==null ? null : compare.getFixed(), mode));
|
||||||
tableRow(tbl, "Pattern Value", null, encodeValue(d.getPattern(), "pattern", d, compare==null ? null : compare.getPattern(), mode));
|
tableRow(tbl, "Pattern Value", null, strikethrough, encodeValue(d.getPattern(), "pattern", d, compare==null ? null : compare.getPattern(), mode));
|
||||||
tableRow(tbl, "Example", null, encodeValues(d.getExample()));
|
tableRow(tbl, "Example", null, strikethrough, encodeValues(d.getExample()));
|
||||||
tableRow(tbl, "Invariants", null, invariants(d.getConstraint(), compare==null ? null : compare.getConstraint(), mode));
|
tableRow(tbl, "Invariants", null, strikethrough, invariants(d.getConstraint(), compare==null ? null : compare.getConstraint(), mode));
|
||||||
tableRow(tbl, "LOINC Code", null, getMapping(sd, d, LOINC_MAPPING, compare, mode));
|
tableRow(tbl, "LOINC Code", null, strikethrough, getMapping(sd, d, LOINC_MAPPING, compare, mode));
|
||||||
tableRow(tbl, "SNOMED-CT Code", null, getMapping(sd, d, SNOMED_MAPPING, compare, mode));
|
tableRow(tbl, "SNOMED-CT Code", null, strikethrough, getMapping(sd, d, SNOMED_MAPPING, compare, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String spec(String name) {
|
private String spec(String name) {
|
||||||
|
@ -3772,7 +3787,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||||
return "unordered";
|
return "unordered";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateSlicing(XhtmlNode tbl, StructureDefinition profile, ElementDefinition ed, ElementDefinitionSlicingComponent slicing, ElementDefinition compare, int mode) throws IOException {
|
private void generateSlicing(XhtmlNode tbl, StructureDefinition profile, ElementDefinition ed, ElementDefinitionSlicingComponent slicing, ElementDefinition compare, int mode, boolean strikethrough) throws IOException {
|
||||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||||
|
|
||||||
x.codeWithText("This element introduces a set of slices on ", ed.getPath(), ". The slices are ");
|
x.codeWithText("This element introduces a set of slices on ", ed.getPath(), ". The slices are ");
|
||||||
|
@ -3801,27 +3816,36 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
||||||
} else {
|
} else {
|
||||||
x.tx(", and defines no discriminators to differentiate the slices");
|
x.tx(", and defines no discriminators to differentiate the slices");
|
||||||
}
|
}
|
||||||
tableRow(tbl, "Slicing", "profiling.html#slicing", x);
|
tableRow(tbl, "Slicing", "profiling.html#slicing", strikethrough, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XhtmlNode tableRow(XhtmlNode x, String name, String defRef) throws IOException {
|
private XhtmlNode tableRow(XhtmlNode x, String name, String defRef, boolean strikethrough) throws IOException {
|
||||||
var tr = x.tr();
|
var tr = x.tr();
|
||||||
|
if (strikethrough) {
|
||||||
|
tr.style("text-decoration: line-through");
|
||||||
|
}
|
||||||
addFirstCell(name, defRef, tr);
|
addFirstCell(name, defRef, tr);
|
||||||
return tr.td();
|
return tr.td();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void tableRow(XhtmlNode x, String name, String defRef, XhtmlNode possibleTd) throws IOException {
|
private void tableRow(XhtmlNode x, String name, String defRef, boolean strikethrough, XhtmlNode possibleTd) throws IOException {
|
||||||
if (possibleTd != null && !possibleTd.isEmpty()) {
|
if (possibleTd != null && !possibleTd.isEmpty()) {
|
||||||
var tr = x.tr();
|
var tr = x.tr();
|
||||||
|
if (strikethrough) {
|
||||||
|
tr.style("text-decoration: line-through");
|
||||||
|
}
|
||||||
addFirstCell(name, defRef, tr);
|
addFirstCell(name, defRef, tr);
|
||||||
tr.td().copyAllContent(possibleTd);
|
tr.td().copyAllContent(possibleTd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tableRow(XhtmlNode x, String name, String defRef, String text) throws IOException {
|
private void tableRow(XhtmlNode x, String name, String defRef, boolean strikethrough, String text) throws IOException {
|
||||||
if (!Utilities.noString(text)) {
|
if (!Utilities.noString(text)) {
|
||||||
var tr = x.tr();
|
var tr = x.tr();
|
||||||
|
if (strikethrough) {
|
||||||
|
tr.style("text-decoration: line-through");
|
||||||
|
}
|
||||||
addFirstCell(name, defRef, tr);
|
addFirstCell(name, defRef, tr);
|
||||||
tr.td().tx(text);
|
tr.td().tx(text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.DefinitionException;
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.model.Base;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
@ -48,6 +49,7 @@ public class DefinitionNavigator {
|
||||||
private IWorkerContext context;
|
private IWorkerContext context;
|
||||||
private StructureDefinition structure;
|
private StructureDefinition structure;
|
||||||
private int index;
|
private int index;
|
||||||
|
private boolean indexMatches; //
|
||||||
private List<DefinitionNavigator> children;
|
private List<DefinitionNavigator> children;
|
||||||
private List<DefinitionNavigator> typeChildren;
|
private List<DefinitionNavigator> typeChildren;
|
||||||
private List<DefinitionNavigator> slices;
|
private List<DefinitionNavigator> slices;
|
||||||
|
@ -63,7 +65,13 @@ public class DefinitionNavigator {
|
||||||
this.structure = structure;
|
this.structure = structure;
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.diff = diff;
|
this.diff = diff;
|
||||||
this.path = current().getPath();
|
if (diff) {
|
||||||
|
this.path = structure.getType(); // fragile?
|
||||||
|
indexMatches = this.path.equals(list().get(0).getPath());
|
||||||
|
} else {
|
||||||
|
indexMatches = true;
|
||||||
|
this.path = current().getPath(); // first element
|
||||||
|
}
|
||||||
names.add(nameTail());
|
names.add(nameTail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +81,7 @@ public class DefinitionNavigator {
|
||||||
this.structure = structure;
|
this.structure = structure;
|
||||||
this.diff = diff;
|
this.diff = diff;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
this.indexMatches = true;
|
||||||
if (type == null)
|
if (type == null)
|
||||||
for (String name : names)
|
for (String name : names)
|
||||||
this.names.add(name+"."+nameTail());
|
this.names.add(name+"."+nameTail());
|
||||||
|
@ -108,7 +117,7 @@ public class DefinitionNavigator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public ElementDefinition current() {
|
public ElementDefinition current() {
|
||||||
return list().get(index);
|
return indexMatches ? list().get(index) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DefinitionNavigator> slices() throws DefinitionException {
|
public List<DefinitionNavigator> slices() throws DefinitionException {
|
||||||
|
@ -127,19 +136,23 @@ public class DefinitionNavigator {
|
||||||
|
|
||||||
private void loadChildren() throws DefinitionException {
|
private void loadChildren() throws DefinitionException {
|
||||||
children = new ArrayList<DefinitionNavigator>();
|
children = new ArrayList<DefinitionNavigator>();
|
||||||
String prefix = current().getPath()+".";
|
String prefix = path+".";
|
||||||
Map<String, DefinitionNavigator> nameMap = new HashMap<String, DefinitionNavigator>();
|
Map<String, DefinitionNavigator> nameMap = new HashMap<String, DefinitionNavigator>();
|
||||||
|
|
||||||
for (int i = index + 1; i < list().size(); i++) {
|
DefinitionNavigator last = null;
|
||||||
|
for (int i = indexMatches ? index + 1 : index; i < list().size(); i++) {
|
||||||
String path = list().get(i).getPath();
|
String path = list().get(i).getPath();
|
||||||
if (path.startsWith(prefix) && !path.substring(prefix.length()).contains(".")) {
|
if (path.startsWith(prefix)) {
|
||||||
|
if (!path.substring(prefix.length()).contains(".")) {
|
||||||
|
// immediate child
|
||||||
DefinitionNavigator dn = new DefinitionNavigator(context, structure, diff, i, this.path+"."+tail(path), names, null);
|
DefinitionNavigator dn = new DefinitionNavigator(context, structure, diff, i, this.path+"."+tail(path), names, null);
|
||||||
|
last = dn;
|
||||||
|
|
||||||
if (nameMap.containsKey(path)) {
|
if (nameMap.containsKey(path)) {
|
||||||
DefinitionNavigator master = nameMap.get(path);
|
DefinitionNavigator master = nameMap.get(path);
|
||||||
ElementDefinition cm = master.current();
|
ElementDefinition cm = master.current();
|
||||||
// if (!cm.hasSlicing())
|
// if (!cm.hasSlicing())
|
||||||
// throw new DefinitionException("Found slices with no slicing details at "+dn.current().getPath());
|
// throw new DefinitionException("Found slices with no slicing details at "+dn.current().getPath());
|
||||||
if (master.slices == null)
|
if (master.slices == null)
|
||||||
master.slices = new ArrayList<DefinitionNavigator>();
|
master.slices = new ArrayList<DefinitionNavigator>();
|
||||||
master.slices.add(dn);
|
master.slices.add(dn);
|
||||||
|
@ -147,6 +160,12 @@ public class DefinitionNavigator {
|
||||||
nameMap.put(path, dn);
|
nameMap.put(path, dn);
|
||||||
children.add(dn);
|
children.add(dn);
|
||||||
}
|
}
|
||||||
|
} else if (last == null || !path.startsWith(last.path)) {
|
||||||
|
// implied child
|
||||||
|
DefinitionNavigator dn = new DefinitionNavigator(context, structure, diff, i, this.path+"."+tail(path), names, null);
|
||||||
|
nameMap.put(path, dn);
|
||||||
|
children.add(dn);
|
||||||
|
}
|
||||||
} else if (path.length() < prefix.length())
|
} else if (path.length() < prefix.length())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -222,5 +241,10 @@ public class DefinitionNavigator {
|
||||||
return current().getId();
|
return current().getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Base parent() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue