Merge pull request #237 from hapifhir/gg-work
override Element extension methods to also check for modifierExtensions
This commit is contained in:
commit
3e55b24473
|
@ -50,6 +50,11 @@ public class CodeSystemComparer extends CanonicalResourceComparer {
|
|||
protected String abbreviation() {
|
||||
return "cs";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String summary() {
|
||||
return "CodeSystem: "+left.present()+" vs "+right.present();
|
||||
}
|
||||
}
|
||||
|
||||
private CodeSystem right;
|
||||
|
|
|
@ -2,9 +2,12 @@ package org.hl7.fhir.r5.comparison;
|
|||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
|
@ -12,6 +15,7 @@ import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
|||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
|
@ -47,9 +51,27 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
|
||||
public void render() throws IOException {
|
||||
dumpBinaries();
|
||||
for (String id : session.getCompares().keySet()) {
|
||||
renderComparison(id, session.getCompares().get(id));
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
for (String id : sorted(session.getCompares().keySet())) {
|
||||
ResourceComparison comp = session.getCompares().get(id);
|
||||
renderComparison(id, comp);
|
||||
b.append("<li><a href=\""+comp.getId()+".html\">"+Utilities.escapeXml(comp.summary())+"</a></li>\r\n");
|
||||
}
|
||||
Map<String, Base> vars = new HashMap<>();
|
||||
CodeSystemComparer cs = new CodeSystemComparer(session);
|
||||
vars.put("title", new StringType(session.getTitle()));
|
||||
vars.put("list", new StringType(b.toString()));
|
||||
String template = templates.get("Index");
|
||||
String cnt = processTemplate(template, "CodeSystem", vars);
|
||||
TextFile.stringToFile(cnt, file("index.html"));
|
||||
}
|
||||
|
||||
private List<String> sorted(Set<String> keySet) {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.addAll(keySet);
|
||||
Collections.sort(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private void dumpBinaries() throws IOException {
|
||||
|
@ -115,7 +137,7 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
private void renderProfile(String id, ProfileComparison comp) throws IOException {
|
||||
String template = templates.get("Profile");
|
||||
Map<String, Base> vars = new HashMap<>();
|
||||
ProfileComparer cs = new ProfileComparer(session);
|
||||
ProfileComparer cs = new ProfileComparer(session, new ProfileUtilities(session.getContext(), null, null));
|
||||
vars.put("left", new StringType(comp.getLeft().present()));
|
||||
vars.put("right", new StringType(comp.getRight().present()));
|
||||
vars.put("leftId", new StringType(comp.getLeft().getId()));
|
||||
|
@ -124,7 +146,7 @@ public class ComparisonRenderer implements IEvaluationContext {
|
|||
vars.put("rightUrl", new StringType(comp.getRight().getUrl()));
|
||||
vars.put("errors", new StringType(new XhtmlComposer(true).compose(cs.renderErrors(comp))));
|
||||
vars.put("metadata", new StringType(new XhtmlComposer(true).compose(cs.renderMetadata(comp, "", ""))));
|
||||
// vars.put("concepts", new StringType(new XhtmlComposer(true).compose(cs.renderConcepts(comp, "", ""))));
|
||||
vars.put("structure", new StringType(new XhtmlComposer(true).compose(cs.renderStructure(comp, "", "", "http://hl7.org/fhir"))));
|
||||
String cnt = processTemplate(template, "CodeSystem", vars);
|
||||
TextFile.stringToFile(cnt, file(comp.getId()+".html"));
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", comp.getId() + "-union.json")), comp.getUnion());
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
|||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||
import org.hl7.fhir.r5.comparison.ResourceComparer.ResourceComparison;
|
||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
|
@ -27,17 +28,25 @@ public class ComparisonSession {
|
|||
private String sessiondId;
|
||||
private int count;
|
||||
private boolean debug;
|
||||
private String title;
|
||||
|
||||
public ComparisonSession(IWorkerContext context) {
|
||||
public ComparisonSession(IWorkerContext context, String title) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.sessiondId = UUID.randomUUID().toString().toLowerCase();
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public IWorkerContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public ResourceComparison compare(String left, String right) throws DefinitionException, FHIRFormatError, IOException {
|
||||
CanonicalResource l = (CanonicalResource) context.fetchResource(Resource.class, left);
|
||||
if (l == null) {
|
||||
|
@ -69,7 +78,7 @@ public class ComparisonSession {
|
|||
compares.put(key, csc);
|
||||
return csc;
|
||||
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
|
||||
ProfileComparer cs = new ProfileComparer(this);
|
||||
ProfileComparer cs = new ProfileComparer(this, new ProfileUtilities(context, null, null));
|
||||
ProfileComparison csc = cs.compare((StructureDefinition) left, (StructureDefinition) right);
|
||||
compares.put(key, csc);
|
||||
return csc;
|
||||
|
@ -91,9 +100,6 @@ public class ComparisonSession {
|
|||
|
||||
public void identify(ResourceComparison res) {
|
||||
count++;
|
||||
if (!Utilities.isValidId(res.getId())) {
|
||||
res.setId(sessiondId+"-"+count);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,8 +7,11 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities.UnusedTracker;
|
||||
import org.hl7.fhir.r5.formats.IParser;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
|
@ -30,6 +33,11 @@ import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
|||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Row;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.TableModel;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class ProfileComparer extends CanonicalResourceComparer {
|
||||
|
||||
|
@ -50,10 +58,21 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
protected String abbreviation() {
|
||||
return "sd";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String summary() {
|
||||
return "Profile: "+left.present()+" vs "+right.present();
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileComparer(ComparisonSession session) {
|
||||
|
||||
|
||||
|
||||
private ProfileUtilities utils;
|
||||
|
||||
public ProfileComparer(ComparisonSession session, ProfileUtilities utils) {
|
||||
super(session);
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,6 +114,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
DefinitionNavigator rn = new DefinitionNavigator(session.getContext(), right);
|
||||
StructuralMatch<ElementDefinition> sm = new StructuralMatch<ElementDefinition>(ln.current(), rn.current());
|
||||
compareElements(res, sm, ln.path(), null, ln, rn);
|
||||
res.combined = sm;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -143,17 +163,21 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
subset.setIsSummary(left.current().getIsSummary());
|
||||
|
||||
// descriptive properties from ElementDefinition - merge them:
|
||||
subset.setLabel(mergeText(comp, res, path, "label", left.current().getLabel(), right.current().getLabel()));
|
||||
subset.setShort(mergeText(comp, res, path, "short", left.current().getShort(), right.current().getShort()));
|
||||
subset.setDefinition(mergeText(comp, res, path, "definition", left.current().getDefinition(), right.current().getDefinition()));
|
||||
subset.setComment(mergeText(comp, res, path, "comments", left.current().getComment(), right.current().getComment()));
|
||||
subset.setRequirements(mergeText(comp, res, path, "requirements", left.current().getRequirements(), right.current().getRequirements()));
|
||||
subset.setLabel(mergeText(comp, res, path, "label", left.current().getLabel(), right.current().getLabel(), false));
|
||||
subset.setShort(mergeText(comp, res, path, "short", left.current().getShort(), right.current().getShort(), false));
|
||||
subset.setDefinition(mergeText(comp, res, path, "definition", left.current().getDefinition(), right.current().getDefinition(), false));
|
||||
subset.setComment(mergeText(comp, res, path, "comments", left.current().getComment(), right.current().getComment(), false));
|
||||
subset.setRequirements(mergeText(comp, res, path, "requirements", left.current().getRequirements(), right.current().getRequirements(), false));
|
||||
subset.getCode().addAll(mergeCodings(left.current().getCode(), right.current().getCode()));
|
||||
subset.getAlias().addAll(mergeStrings(left.current().getAlias(), right.current().getAlias()));
|
||||
subset.getMapping().addAll(mergeMappings(left.current().getMapping(), right.current().getMapping()));
|
||||
// left will win for example
|
||||
subset.setExample(left.current().hasExample() ? left.current().getExample() : right.current().getExample());
|
||||
|
||||
if (left.current().getMustSupport() != right.current().getMustSupport()) {
|
||||
vm(IssueSeverity.ERROR, "Elements differ in definition for mustSupport:\r\n \""+left.current().getMustSupport()+"\"\r\n \""+right.current().getMustSupport()+"\"", path, comp.getMessages(), res.getMessages());
|
||||
|
||||
}
|
||||
subset.setMustSupport(left.current().getMustSupport() || right.current().getMustSupport());
|
||||
ElementDefinition superset = subset.copy();
|
||||
|
||||
|
@ -278,7 +302,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
|
||||
private DefinitionNavigator findInList(List<DefinitionNavigator> rc, DefinitionNavigator l) {
|
||||
for (DefinitionNavigator t : rc) {
|
||||
if (t.current().getPath().equals(l.current().getPath())) {
|
||||
if (tail(t.current().getPath()).equals(tail(l.current().getPath()))) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
@ -292,8 +316,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
vm(IssueSeverity.ERROR, "Added "+name, path, comp.getMessages(), res.getMessages());
|
||||
} else if (vRight == null) {
|
||||
vm(IssueSeverity.ERROR, "Removed "+name, path, comp.getMessages(), res.getMessages());
|
||||
} else if (Base.compareDeep(vLeft, vRight, false)) {
|
||||
vm(IssueSeverity.ERROR, name+" be the same ("+toString(vLeft)+"/"+toString(vRight)+")", path, comp.getMessages(), res.getMessages());
|
||||
} else if (!Base.compareDeep(vLeft, vRight, false)) {
|
||||
vm(IssueSeverity.ERROR, name+" must be the same ("+toString(vLeft)+"/"+toString(vRight)+")", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +348,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return test;
|
||||
}
|
||||
|
||||
private String mergeText(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String name, String left, String right) {
|
||||
private String mergeText(ProfileComparison comp, StructuralMatch<ElementDefinition> res, String path, String name, String left, String right, boolean isError) {
|
||||
if (left == null && right == null)
|
||||
return null;
|
||||
if (left == null)
|
||||
|
@ -336,7 +360,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
if (left.equalsIgnoreCase(right))
|
||||
return left;
|
||||
if (path != null) {
|
||||
vm(IssueSeverity.ERROR, "Elements differ in definition for "+name+":\r\n \""+left+"\"\r\n \""+right+"\"", path, comp.getMessages(), res.getMessages());
|
||||
vm(isError ? IssueSeverity.ERROR : IssueSeverity.WARNING, "Elements differ in "+name+":\r\n \""+left+"\"\r\n \""+right+"\"", path, comp.getMessages(), res.getMessages());
|
||||
}
|
||||
return "left: "+left+"; right: "+right;
|
||||
}
|
||||
|
@ -661,8 +685,8 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
subset.setBinding(subBinding);
|
||||
ElementDefinitionBindingComponent superBinding = new ElementDefinitionBindingComponent();
|
||||
superset.setBinding(superBinding);
|
||||
subBinding.setDescription(mergeText(comp, res, path, "description", left.getDescription(), right.getDescription()));
|
||||
superBinding.setDescription(mergeText(comp, res, path, "description", left.getDescription(), right.getDescription()));
|
||||
subBinding.setDescription(mergeText(comp, res, path, "description", left.getDescription(), right.getDescription(), false));
|
||||
superBinding.setDescription(mergeText(comp, res, path, "description", left.getDescription(), right.getDescription(), false));
|
||||
if (left.getStrength() == BindingStrength.REQUIRED || right.getStrength() == BindingStrength.REQUIRED)
|
||||
subBinding.setStrength(BindingStrength.REQUIRED);
|
||||
else
|
||||
|
@ -776,7 +800,7 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
union.setStrength(left.getStrength());
|
||||
else
|
||||
union.setStrength(right.getStrength());
|
||||
union.setDescription(mergeText(comp, res, path, "binding.description", left.getDescription(), right.getDescription()));
|
||||
union.setDescription(mergeText(comp, res, path, "binding.description", left.getDescription(), right.getDescription(), false));
|
||||
if (Base.compareDeep(left.getValueSet(), right.getValueSet(), false))
|
||||
union.setValueSet(left.getValueSet());
|
||||
else {
|
||||
|
@ -802,8 +826,165 @@ public class ProfileComparer extends CanonicalResourceComparer {
|
|||
return session.getContext().fetchResource(ValueSet.class, vsRef);
|
||||
}
|
||||
|
||||
public XhtmlNode renderStructure(ProfileComparison comp, String id, String prefix, String corePath) throws FHIRException, IOException {
|
||||
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(Utilities.path("[tmp]", "compare"), false, true);
|
||||
gen.setTranslator(session.getContext().translator());
|
||||
TableModel model = gen.initComparisonTable(corePath, id);
|
||||
genElementComp(null /* oome back to this later */, gen, model.getRows(), comp.combined, corePath, prefix, null, true);
|
||||
return gen.generate(model, prefix, 0, null);
|
||||
}
|
||||
|
||||
private void genElementComp(String defPath, HierarchicalTableGenerator gen, List<Row> rows, StructuralMatch<ElementDefinition> combined, String corePath, String prefix, Row slicingRow, boolean root) throws IOException {
|
||||
Row originalRow = slicingRow;
|
||||
Row typesRow = null;
|
||||
|
||||
List<StructuralMatch<ElementDefinition>> children = combined.getChildren();
|
||||
|
||||
Row row = gen.new Row();
|
||||
rows.add(row);
|
||||
String path = combined.either().getPath();
|
||||
row.setAnchor(path);
|
||||
row.setColor(utils.getRowColor(combined.either(), false));
|
||||
if (eitherHasSlicing(combined))
|
||||
row.setLineColor(1);
|
||||
else if (eitherHasSliceName(combined))
|
||||
row.setLineColor(2);
|
||||
else
|
||||
row.setLineColor(0);
|
||||
boolean ext = false;
|
||||
if (tail(path).equals("extension")) {
|
||||
if (elementIsComplex(combined))
|
||||
row.setIcon("icon_extension_complex.png", HierarchicalTableGenerator.TEXT_ICON_EXTENSION_COMPLEX);
|
||||
else
|
||||
row.setIcon("icon_extension_simple.png", HierarchicalTableGenerator.TEXT_ICON_EXTENSION_SIMPLE);
|
||||
ext = true;
|
||||
} else if (tail(path).equals("modifierExtension")) {
|
||||
if (elementIsComplex(combined))
|
||||
row.setIcon("icon_modifier_extension_complex.png", HierarchicalTableGenerator.TEXT_ICON_EXTENSION_COMPLEX);
|
||||
else
|
||||
row.setIcon("icon_modifier_extension_simple.png", HierarchicalTableGenerator.TEXT_ICON_EXTENSION_SIMPLE);
|
||||
} else if (hasChoice(combined)) {
|
||||
if (allAreReference(combined))
|
||||
row.setIcon("icon_reference.png", HierarchicalTableGenerator.TEXT_ICON_REFERENCE);
|
||||
else {
|
||||
row.setIcon("icon_choice.gif", HierarchicalTableGenerator.TEXT_ICON_CHOICE);
|
||||
typesRow = row;
|
||||
}
|
||||
} else if (combined.either().hasContentReference())
|
||||
row.setIcon("icon_reuse.png", HierarchicalTableGenerator.TEXT_ICON_REUSE);
|
||||
else if (isPrimitive(combined))
|
||||
row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||
else if (hasTarget(combined))
|
||||
row.setIcon("icon_reference.png", HierarchicalTableGenerator.TEXT_ICON_REFERENCE);
|
||||
else if (isDataType(combined))
|
||||
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||
else
|
||||
row.setIcon("icon_resource.png", HierarchicalTableGenerator.TEXT_ICON_RESOURCE);
|
||||
String ref = defPath == null ? null : defPath + combined.either().getId();
|
||||
String sName = tail(path);
|
||||
String sn = getSliceName(combined);
|
||||
if (sn != null)
|
||||
sName = sName +":"+sn;
|
||||
UnusedTracker used = new UnusedTracker();
|
||||
Cell nc;
|
||||
String leftColor = !combined.hasLeft() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||
String rightColor = !combined.hasRight() ? COLOR_NO_ROW_LEFT : combined.hasErrors() ? COLOR_DIFFERENT : null;
|
||||
if (combined.hasLeft()) {
|
||||
nc = utils.genElementNameCell(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
} else {
|
||||
nc = utils.genElementNameCell(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName);
|
||||
}
|
||||
if (combined.hasLeft()) {
|
||||
frame(utils.genElementCells(gen, combined.getLeft(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used , ref, sName, nc), leftColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), leftColor);
|
||||
}
|
||||
if (combined.hasRight()) {
|
||||
frame(utils.genElementCells(gen, combined.getRight(), "??", true, corePath, prefix, root, false, false, null, typesRow, row, false, ext, used, ref, sName, nc), rightColor);
|
||||
} else {
|
||||
frame(spacers(row, 4, gen), rightColor);
|
||||
}
|
||||
row.getCells().add(cellForMessages(gen, combined.getMessages()));
|
||||
|
||||
for (StructuralMatch<ElementDefinition> child : children) {
|
||||
genElementComp(defPath, gen, row.getSubRows(), child, corePath, prefix, originalRow, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void frame(List<Cell> cells, String color) {
|
||||
for (Cell cell : cells) {
|
||||
if (color != null) {
|
||||
cell.setStyle("background-color: "+color);
|
||||
}
|
||||
}
|
||||
cells.get(0).setStyle("border-left: 1px grey solid"+(color == null ? "" : "; background-color: "+color));
|
||||
cells.get(cells.size()-1).setStyle("border-right: 1px grey solid"+(color == null ? "" : "; background-color: "+color));
|
||||
}
|
||||
|
||||
private List<Cell> spacers(Row row, int count, HierarchicalTableGenerator gen) {
|
||||
List<Cell> res = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Cell c = gen.new Cell();
|
||||
res.add(c);
|
||||
row.getCells().add(c);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private String getSliceName(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isDataType(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasTarget(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isPrimitive(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allAreReference(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasChoice(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean elementIsComplex(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub velement.hasType() && element.getType().get(0).hasProfile() && extensionIsComplex(element.getType().get(0).getProfile().get(0).getValue()
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean eitherHasSliceName(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean eitherHasSlicing(StructuralMatch<ElementDefinition> combined) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private String tail(String path) {
|
||||
if (path.contains("."))
|
||||
return path.substring(path.lastIndexOf('.')+1);
|
||||
else
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -47,9 +47,7 @@ public class ResourceComparer {
|
|||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = abbreviation()+"-"+id;
|
||||
}
|
||||
protected abstract String summary();
|
||||
}
|
||||
|
||||
public final static String COLOR_NO_ROW_LEFT = "#ffffb3";
|
||||
|
@ -84,6 +82,7 @@ public class ResourceComparer {
|
|||
XhtmlNode tbl = div.table("grid");
|
||||
for (ValidationMessage vm : csc.messages) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.style("background-color: "+colorForLevel(vm.getLevel()));
|
||||
tr.td().tx(vm.getLocation());
|
||||
tr.td().tx(vm.getMessage());
|
||||
tr.td().tx(vm.getLevel().getDisplay());
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
|
||||
public class StructuralMatch<T> {
|
||||
|
||||
|
@ -77,5 +78,14 @@ public class StructuralMatch<T> {
|
|||
return messages;
|
||||
}
|
||||
|
||||
public boolean hasErrors() {
|
||||
for (ValidationMessage vm : messages) {
|
||||
if (vm.getLevel() == IssueSeverity.ERROR) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -60,7 +60,12 @@ public class ValueSetComparer extends CanonicalResourceComparer {
|
|||
|
||||
@Override
|
||||
protected String abbreviation() {
|
||||
return "sd";
|
||||
return "vs";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String summary() {
|
||||
return "ValueSet: "+left.present()+" vs "+right.present();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
this.pkp = pkp;
|
||||
}
|
||||
|
||||
private class UnusedTracker {
|
||||
public static class UnusedTracker {
|
||||
private boolean used;
|
||||
}
|
||||
|
||||
|
@ -3219,7 +3219,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return (!min.hasValue() ? "" : Integer.toString(min.getValue())) + ".." + (!max.hasValue() ? "" : max.getValue());
|
||||
}
|
||||
|
||||
private void genCardinality(HierarchicalTableGenerator gen, ElementDefinition definition, Row row, boolean hasDef, UnusedTracker tracker, ElementDefinition fallback) {
|
||||
private Cell genCardinality(HierarchicalTableGenerator gen, ElementDefinition definition, Row row, boolean hasDef, UnusedTracker tracker, ElementDefinition fallback) {
|
||||
IntegerType min = !hasDef ? new IntegerType() : definition.hasMinElement() ? definition.getMinElement() : new IntegerType();
|
||||
StringType max = !hasDef ? new StringType() : definition.hasMaxElement() ? definition.getMaxElement() : new StringType();
|
||||
if (min.isEmpty() && definition.getUserData(DERIVATION_POINTER) != null) {
|
||||
|
@ -3249,8 +3249,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!min.isEmpty() || !max.isEmpty()) {
|
||||
cell.addPiece(checkForNoChange(min, gen.new Piece(null, !min.hasValue() ? "" : Integer.toString(min.getValue()), null)));
|
||||
cell.addPiece(checkForNoChange(min, max, gen.new Piece(null, "..", null)));
|
||||
cell.addPiece(checkForNoChange(min, gen.new Piece(null, !max.hasValue() ? "" : max.getValue(), null)));
|
||||
cell.addPiece(checkForNoChange(max, gen.new Piece(null, !max.hasValue() ? "" : max.getValue(), null)));
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3393,13 +3394,9 @@ 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) throws IOException, FHIRException {
|
||||
Row originalRow = slicingRow;
|
||||
StructureDefinition profile = profiles == null ? null : profiles.get(profiles.size()-1);
|
||||
String s = tail(element.getPath());
|
||||
if (element.hasSliceName())
|
||||
s = s +":"+element.getSliceName();
|
||||
Row typesRow = null;
|
||||
|
||||
List<ElementDefinition> children = getChildren(all, element);
|
||||
boolean isExtension = (s.equals("extension") || s.equals("modifierExtension"));
|
||||
// if (!snapshot && isExtension && extensions != null && extensions != isExtension)
|
||||
// return;
|
||||
|
||||
|
@ -3449,71 +3446,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||
else
|
||||
row.setIcon("icon_resource.png", HierarchicalTableGenerator.TEXT_ICON_RESOURCE);
|
||||
String ref = defPath == null ? null : defPath + element.getId();
|
||||
UnusedTracker used = new UnusedTracker();
|
||||
String ref = defPath == null ? null : defPath + element.getId();
|
||||
String sName = tail(element.getPath());
|
||||
if (element.hasSliceName())
|
||||
sName = sName +":"+element.getSliceName();
|
||||
used.used = true;
|
||||
if (logicalModel && element.hasRepresentation(PropertyRepresentation.XMLATTR))
|
||||
s = "@"+s;
|
||||
String hint = "";
|
||||
hint = checkAdd(hint, (element.hasSliceName() ? translate("sd.table", "Slice")+" "+element.getSliceName() : ""));
|
||||
if (hasDef && element.hasDefinition()) {
|
||||
hint = checkAdd(hint, (hasDef && element.hasSliceName() ? ": " : ""));
|
||||
hint = checkAdd(hint, !hasDef ? null : gt(element.getDefinitionElement()));
|
||||
}
|
||||
Cell left = gen.new Cell(null, ref, s, hint, null);
|
||||
row.getCells().add(left);
|
||||
Cell gc = gen.new Cell();
|
||||
row.getCells().add(gc);
|
||||
if (element != null && element.getIsModifier())
|
||||
checkForNoChange(element.getIsModifierElement(), gc.addStyledText(translate("sd.table", "This element is a modifier element"), "?!", null, null, null, false));
|
||||
if (element != null && element.getMustSupport())
|
||||
checkForNoChange(element.getMustSupportElement(), gc.addStyledText(translate("sd.table", "This element must be supported"), "S", "white", "red", null, false));
|
||||
if (element != null && element.getIsSummary())
|
||||
checkForNoChange(element.getIsSummaryElement(), gc.addStyledText(translate("sd.table", "This element is included in summaries"), "\u03A3", null, null, null, false));
|
||||
if (element != null && (!element.getConstraint().isEmpty() || !element.getCondition().isEmpty()))
|
||||
gc.addStyledText(translate("sd.table", "This element has or is affected by some invariants ("+listConstraintsAndConditions(element)+")"), "I", null, null, null, false);
|
||||
|
||||
ExtensionContext extDefn = null;
|
||||
if (ext) {
|
||||
if (element != null && element.getType().size() == 1 && element.getType().get(0).hasProfile()) {
|
||||
String eurl = element.getType().get(0).getProfile().get(0).getValue();
|
||||
extDefn = locateExtension(StructureDefinition.class, eurl);
|
||||
if (extDefn == null) {
|
||||
genCardinality(gen, element, row, hasDef, used, null);
|
||||
row.getCells().add(gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null));
|
||||
generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot);
|
||||
} else {
|
||||
String name = urltail(eurl);
|
||||
left.getPieces().get(0).setText(name);
|
||||
// left.getPieces().get(0).setReference((String) extDefn.getExtensionStructure().getTag("filename"));
|
||||
left.getPieces().get(0).setHint(translate("sd.table", "Extension URL")+" = "+extDefn.getUrl());
|
||||
genCardinality(gen, element, row, hasDef, used, extDefn.getElement());
|
||||
ElementDefinition valueDefn = extDefn.getExtensionValueDefinition();
|
||||
if (valueDefn != null && !"0".equals(valueDefn.getMax()))
|
||||
genTypes(gen, row, valueDefn, profileBaseFileName, profile, corePath, imagePath, root);
|
||||
else // if it's complex, we just call it nothing
|
||||
// genTypes(gen, row, extDefn.getSnapshot().getElement().get(0), profileBaseFileName, profile);
|
||||
row.getCells().add(gen.new Cell(null, null, "("+translate("sd.table", "Complex")+")", null, null));
|
||||
generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot);
|
||||
}
|
||||
} else {
|
||||
genCardinality(gen, element, row, hasDef, used, null);
|
||||
if ("0".equals(element.getMax()))
|
||||
row.getCells().add(gen.new Cell());
|
||||
else
|
||||
genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root);
|
||||
generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot);
|
||||
}
|
||||
} else {
|
||||
genCardinality(gen, element, row, hasDef, used, null);
|
||||
if (element.hasSlicing())
|
||||
row.getCells().add(gen.new Cell(null, corePath+"profiling.html#slicing", "(Slice Definition)", null, null));
|
||||
else if (hasDef && !"0".equals(element.getMax()) && typesRow == null)
|
||||
genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root);
|
||||
else
|
||||
row.getCells().add(gen.new Cell());
|
||||
generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot);
|
||||
}
|
||||
sName = "@"+sName;
|
||||
Cell nc = genElementNameCell(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName);
|
||||
genElementCells(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, nc);
|
||||
if (element.hasSlicing()) {
|
||||
if (standardExtensionSlicing(element)) {
|
||||
used.used = true; // doesn't matter whether we have a type, we're used if we're setting up slicing ... element.hasType() && element.getType().get(0).hasProfile();
|
||||
|
@ -3545,7 +3487,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
hrow.setColor(getRowColor(element, isConstraintMode));
|
||||
hrow.setLineColor(1);
|
||||
hrow.setIcon("icon_element.gif", HierarchicalTableGenerator.TEXT_ICON_ELEMENT);
|
||||
hrow.getCells().add(gen.new Cell(null, null, s+":All Slices", "", null));
|
||||
hrow.getCells().add(gen.new Cell(null, null, sName+":All Slices", "", null));
|
||||
hrow.getCells().add(gen.new Cell());
|
||||
hrow.getCells().add(gen.new Cell());
|
||||
hrow.getCells().add(gen.new Cell());
|
||||
|
@ -3560,7 +3502,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
hrow.setColor(getRowColor(element, isConstraintMode));
|
||||
hrow.setLineColor(1);
|
||||
hrow.setIcon("icon_element.gif", HierarchicalTableGenerator.TEXT_ICON_ELEMENT);
|
||||
hrow.getCells().add(gen.new Cell(null, null, s+":All Types", "", null));
|
||||
hrow.getCells().add(gen.new Cell(null, null, sName+":All Types", "", null));
|
||||
hrow.getCells().add(gen.new Cell());
|
||||
hrow.getCells().add(gen.new Cell());
|
||||
hrow.getCells().add(gen.new Cell());
|
||||
|
@ -3569,7 +3511,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
row = hrow;
|
||||
}
|
||||
|
||||
Row currRow = row;
|
||||
Row currRow = row;
|
||||
boolean isExtension = Utilities.existsInList(tail(element.getPath()), "extension", "modifierExtension");
|
||||
for (ElementDefinition child : children) {
|
||||
if (!child.hasSliceName())
|
||||
currRow = row;
|
||||
|
@ -3588,6 +3531,85 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return slicingRow;
|
||||
}
|
||||
|
||||
public Cell genElementNameCell(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
||||
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
||||
boolean ext, UnusedTracker used, String ref, String sName) throws IOException {
|
||||
String hint = "";
|
||||
hint = checkAdd(hint, (element.hasSliceName() ? translate("sd.table", "Slice")+" "+element.getSliceName() : ""));
|
||||
if (hasDef && element.hasDefinition()) {
|
||||
hint = checkAdd(hint, (hasDef && element.hasSliceName() ? ": " : ""));
|
||||
hint = checkAdd(hint, !hasDef ? null : gt(element.getDefinitionElement()));
|
||||
}
|
||||
Cell left = gen.new Cell(null, ref, sName, hint, null);
|
||||
row.getCells().add(left);
|
||||
return left;
|
||||
}
|
||||
|
||||
public List<Cell> genElementCells(HierarchicalTableGenerator gen, ElementDefinition element, String profileBaseFileName, boolean snapshot, String corePath,
|
||||
String imagePath, boolean root, boolean logicalModel, boolean allInvariants, StructureDefinition profile, Row typesRow, Row row, boolean hasDef,
|
||||
boolean ext, UnusedTracker used, String ref, String sName, Cell nameCell) throws IOException {
|
||||
List<Cell> res = new ArrayList<>();
|
||||
Cell gc = gen.new Cell();
|
||||
row.getCells().add(gc);
|
||||
res.add(gc);
|
||||
if (element != null && element.getIsModifier())
|
||||
checkForNoChange(element.getIsModifierElement(), gc.addStyledText(translate("sd.table", "This element is a modifier element"), "?!", null, null, null, false));
|
||||
if (element != null && element.getMustSupport())
|
||||
checkForNoChange(element.getMustSupportElement(), gc.addStyledText(translate("sd.table", "This element must be supported"), "S", "white", "red", null, false));
|
||||
if (element != null && element.getIsSummary())
|
||||
checkForNoChange(element.getIsSummaryElement(), gc.addStyledText(translate("sd.table", "This element is included in summaries"), "\u03A3", null, null, null, false));
|
||||
if (element != null && (!element.getConstraint().isEmpty() || !element.getCondition().isEmpty()))
|
||||
gc.addStyledText(translate("sd.table", "This element has or is affected by some invariants ("+listConstraintsAndConditions(element)+")"), "I", null, null, null, false);
|
||||
|
||||
ExtensionContext extDefn = null;
|
||||
if (ext) {
|
||||
if (element != null && element.getType().size() == 1 && element.getType().get(0).hasProfile()) {
|
||||
String eurl = element.getType().get(0).getProfile().get(0).getValue();
|
||||
extDefn = locateExtension(StructureDefinition.class, eurl);
|
||||
if (extDefn == null) {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
res.add(addCell(row, gen.new Cell(null, null, "?gen-e1? "+element.getType().get(0).getProfile(), null, null)));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, profile.getUrl(), eurl, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot));
|
||||
} else {
|
||||
String name = urltail(eurl);
|
||||
nameCell.getPieces().get(0).setText(name);
|
||||
// left.getPieces().get(0).setReference((String) extDefn.getExtensionStructure().getTag("filename"));
|
||||
nameCell.getPieces().get(0).setHint(translate("sd.table", "Extension URL")+" = "+extDefn.getUrl());
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, extDefn.getElement()));
|
||||
ElementDefinition valueDefn = extDefn.getExtensionValueDefinition();
|
||||
if (valueDefn != null && !"0".equals(valueDefn.getMax()))
|
||||
res.add(genTypes(gen, row, valueDefn, profileBaseFileName, profile, corePath, imagePath, root));
|
||||
else // if it's complex, we just call it nothing
|
||||
// genTypes(gen, row, extDefn.getSnapshot().getElement().get(0), profileBaseFileName, profile);
|
||||
res.add(addCell(row, gen.new Cell(null, null, "("+translate("sd.table", "Complex")+")", null, null)));
|
||||
res.add(generateDescription(gen, row, element, extDefn.getElement(), used.used, null, extDefn.getUrl(), profile, corePath, imagePath, root, logicalModel, allInvariants, valueDefn, snapshot));
|
||||
}
|
||||
} else {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
if ("0".equals(element.getMax()))
|
||||
res.add(addCell(row, gen.new Cell()));
|
||||
else
|
||||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot));
|
||||
}
|
||||
} else {
|
||||
res.add(genCardinality(gen, element, row, hasDef, used, null));
|
||||
if (element.hasSlicing())
|
||||
res.add(addCell(row, gen.new Cell(null, corePath+"profiling.html#slicing", "(Slice Definition)", null, null)));
|
||||
else if (hasDef && !"0".equals(element.getMax()) && typesRow == null)
|
||||
res.add(genTypes(gen, row, element, profileBaseFileName, profile, corePath, imagePath, root));
|
||||
else
|
||||
res.add(addCell(row, gen.new Cell()));
|
||||
res.add(generateDescription(gen, row, element, (ElementDefinition) element.getUserData(DERIVATION_POINTER), used.used, null, null, profile, corePath, imagePath, root, logicalModel, allInvariants, snapshot));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private Cell addCell(Row row, Cell cell) {
|
||||
row.getCells().add(cell);
|
||||
return (cell);
|
||||
}
|
||||
|
||||
private String checkAdd(String src, String app) {
|
||||
return app == null ? src : src + app;
|
||||
}
|
||||
|
@ -3800,7 +3822,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
|
||||
private String getRowColor(ElementDefinition element, boolean isConstraintMode) {
|
||||
public String getRowColor(ElementDefinition element, boolean isConstraintMode) {
|
||||
switch (element.getUserInt(UD_ERROR_STATUS)) {
|
||||
case STATUS_HINT: return ROW_COLOR_HINT;
|
||||
case STATUS_WARNING: return ROW_COLOR_WARNING;
|
||||
|
@ -3849,7 +3871,12 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
c.getPieces().add(gen.new Piece(null, ToolingExtensions.readStringExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"), null));
|
||||
}
|
||||
}
|
||||
|
||||
if (root) {
|
||||
if (profile.getAbstract()) {
|
||||
if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br"));
|
||||
c.addPiece(gen.new Piece(null, "This is an abstract profile", null));
|
||||
}
|
||||
}
|
||||
if (definition.getPath().endsWith("url") && definition.hasFixed()) {
|
||||
c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "\""+buildJson(definition.getFixed())+"\"", null).addStyle("color: darkgreen")));
|
||||
} else {
|
||||
|
|
|
@ -609,6 +609,10 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs) {
|
||||
assert options != null;
|
||||
|
||||
if (options == null) {
|
||||
options = ValidationOptions.defaults();
|
||||
}
|
||||
|
||||
CacheToken cacheToken = txCache != null ? txCache.generateValidationToken(options, code, vs) : null;
|
||||
ValidationResult res = null;
|
||||
if (txCache != null)
|
||||
|
|
|
@ -240,7 +240,69 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public void addModifierExtension(String url, DataType value) {
|
||||
if (isDisallowExtensions())
|
||||
throw new Error("Extensions are not allowed in this context");
|
||||
Extension ex = new Extension();
|
||||
ex.setUrl(url);
|
||||
ex.setValue(value);
|
||||
getModifierExtension().add(ex);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Extension getExtensionByUrl(String theUrl) {
|
||||
org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null");
|
||||
ArrayList<Extension> retVal = new ArrayList<Extension>();
|
||||
Extension res = super.getExtensionByUrl(theUrl);
|
||||
if (res != null) {
|
||||
retVal.add(res);
|
||||
}
|
||||
for (Extension next : getModifierExtension()) {
|
||||
if (theUrl.equals(next.getUrl())) {
|
||||
retVal.add(next);
|
||||
}
|
||||
}
|
||||
if (retVal.size() == 0)
|
||||
return null;
|
||||
else {
|
||||
org.apache.commons.lang3.Validate.isTrue(retVal.size() == 1, "Url "+theUrl+" must have only one match");
|
||||
return retVal.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtension(String theUrl) {
|
||||
for (int i = getModifierExtension().size()-1; i >= 0; i--) {
|
||||
if (theUrl.equals(getExtension().get(i).getUrl()))
|
||||
getExtension().remove(i);
|
||||
}
|
||||
super.removeExtension(theUrl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list containing all extensions on this element which
|
||||
* match the given URL.
|
||||
*
|
||||
* @param theUrl The URL. Must not be blank or null.
|
||||
* @return an unmodifiable list containing all extensions on this element which
|
||||
* match the given URL
|
||||
*/
|
||||
@Override
|
||||
public List<Extension> getExtensionsByUrl(String theUrl) {
|
||||
org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null");
|
||||
ArrayList<Extension> retVal = new ArrayList<Extension>();
|
||||
retVal.addAll(super.getExtensionsByUrl(theUrl));
|
||||
for (Extension next : getModifierExtension()) {
|
||||
if (theUrl.equals(next.getUrl())) {
|
||||
retVal.add(next);
|
||||
}
|
||||
}
|
||||
return java.util.Collections.unmodifiableList(retVal);
|
||||
}
|
||||
|
||||
// end addition
|
||||
|
||||
}
|
|
@ -319,7 +319,15 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE
|
|||
getExtension().add(ex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns an extension if one (and only one) matches the given URL.
|
||||
*
|
||||
* Note: BackbdoneElements override this to look in matching Modifier Extensions too
|
||||
*
|
||||
* @param theUrl The URL. Must not be blank or null.
|
||||
* @return the matching extension, or null
|
||||
*/
|
||||
public Extension getExtensionByUrl(String theUrl) {
|
||||
org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null");
|
||||
ArrayList<Extension> retVal = new ArrayList<Extension>();
|
||||
|
@ -336,6 +344,13 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any extensions that match (by given URL).
|
||||
*
|
||||
* Note: BackbdoneElements override this to remove from Modifier Extensions too
|
||||
*
|
||||
* @param theUrl The URL. Must not be blank or null.
|
||||
*/
|
||||
public void removeExtension(String theUrl) {
|
||||
for (int i = getExtension().size()-1; i >= 0; i--) {
|
||||
if (theUrl.equals(getExtension().get(i).getUrl()))
|
||||
|
@ -367,9 +382,10 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE
|
|||
* Returns an unmodifiable list containing all extensions on this element which
|
||||
* match the given URL.
|
||||
*
|
||||
* Note: BackbdoneElements override this to add matching Modifier Extensions too
|
||||
*
|
||||
* @param theUrl The URL. Must not be blank or null.
|
||||
* @return an unmodifiable list containing all extensions on this element which
|
||||
* match the given URL
|
||||
* @return an unmodifiable list containing all extensions on this element which match the given URL
|
||||
*/
|
||||
public List<Extension> getExtensionsByUrl(String theUrl) {
|
||||
org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null");
|
||||
|
@ -382,11 +398,24 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE
|
|||
return java.util.Collections.unmodifiableList(retVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an true if this element has an extension that matchs the given URL.
|
||||
*
|
||||
* Note: BackbdoneElements override this to check Modifier Extensions too
|
||||
*
|
||||
* @param theUrl The URL. Must not be blank or null.
|
||||
*/
|
||||
public boolean hasExtension(String theUrl) {
|
||||
return !getExtensionsByUrl(theUrl).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value as a string if this element has only one extension that matches the given URL, and that can be converted to a string.
|
||||
*
|
||||
* Note: BackbdoneElements override this to check Modifier Extensions too
|
||||
*
|
||||
* @param theUrl The URL. Must not be blank or null.
|
||||
*/
|
||||
public String getExtensionString(String theUrl) throws FHIRException {
|
||||
List<Extension> ext = getExtensionsByUrl(theUrl);
|
||||
if (ext.isEmpty())
|
||||
|
|
|
@ -201,6 +201,11 @@ public class DefinitionNavigator {
|
|||
public StructureDefinition getStructure() {
|
||||
return structure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return current().getId();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -415,6 +415,10 @@ public class HierarchicalTableGenerator extends TranslatingUtilities {
|
|||
this.span = span;
|
||||
}
|
||||
|
||||
public Title setStyle(String value) {
|
||||
super.setStyle(value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class Row {
|
||||
|
@ -569,6 +573,26 @@ public class HierarchicalTableGenerator extends TranslatingUtilities {
|
|||
return model;
|
||||
}
|
||||
|
||||
public TableModel initComparisonTable(String prefix, String id) {
|
||||
TableModel model = new TableModel(id, true);
|
||||
|
||||
model.setAlternating(true);
|
||||
model.setDocoImg(prefix+"help16.png");
|
||||
model.setDocoRef(prefix+"formats.html#table");
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "Name"), translate("sd.hint", "The logical name of the element"), null, 0));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "L Flags"), translate("sd.hint", "Information about the use of the element - Left Structure"), null, 0).setStyle("border-left: 1px grey solid"));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "L Card."), translate("sd.hint", "Minimum and Maximum # of times the the element can appear in the instance - Left Structure"), null, 0));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "L Type"), translate("sd.hint", "Reference to the type of the element - Left Structure"), null, 100));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "L Description & Constraints"), translate("sd.hint", "Additional information about the element - Left Structure"), null, 0).setStyle("border-right: 1px grey solid"));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "R Flags"), translate("sd.hint", "Information about the use of the element - Left Structure"), null, 0).setStyle("border-left: 1px grey solid"));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "R Card."), translate("sd.hint", "Minimum and Maximum # of times the the element can appear in the instance - Left Structure"), null, 0));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "L Type"), translate("sd.hint", "Reference to the type of the element - Left Structure"), null, 100));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "L Description & Constraints"), translate("sd.hint", "Additional information about the element - Left Structure"), null, 0).setStyle("border-right: 1px grey solid"));
|
||||
model.getTitles().add(new Title(null, model.getDocoRef(), translate("sd.head", "Comments"), translate("sd.hint", "Comments about the comparison"), null, 0));
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TableModel initGridTable(String prefix, String id) {
|
||||
TableModel model = new TableModel(id, false);
|
||||
|
|
|
@ -14,8 +14,11 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
|||
import org.hl7.fhir.r5.comparison.CodeSystemComparer;
|
||||
import org.hl7.fhir.r5.comparison.CodeSystemComparer.CodeSystemComparison;
|
||||
import org.hl7.fhir.r5.comparison.ComparisonSession;
|
||||
import org.hl7.fhir.r5.comparison.ProfileComparer;
|
||||
import org.hl7.fhir.r5.comparison.ProfileComparer.ProfileComparison;
|
||||
import org.hl7.fhir.r5.comparison.ValueSetComparer;
|
||||
import org.hl7.fhir.r5.comparison.ValueSetComparer.ValueSetComparison;
|
||||
import org.hl7.fhir.r5.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
|
@ -24,6 +27,7 @@ import org.hl7.fhir.r5.model.CanonicalResource;
|
|||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.Constants;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
|
@ -103,7 +107,7 @@ public class ComparisonTests {
|
|||
System.out.println("---- Set up Output ----------------------------------------------------------");
|
||||
Utilities.createDirectory(Utilities.path("[tmp]", "comparison"));
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.pubpack", "0.0.5");
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.pubpack", "0.0.6");
|
||||
for (String f : npm.list("other")) {
|
||||
TextFile.streamToFile(npm.load("other", f), Utilities.path("[tmp]", "comparison", f));
|
||||
}
|
||||
|
@ -112,7 +116,7 @@ public class ComparisonTests {
|
|||
CanonicalResource left = load("left");
|
||||
CanonicalResource right = load("right");
|
||||
|
||||
ComparisonSession session = new ComparisonSession(context);
|
||||
ComparisonSession session = new ComparisonSession(context, "Comparison Tests");
|
||||
|
||||
if (left instanceof CodeSystem && right instanceof CodeSystem) {
|
||||
CodeSystemComparer cs = new CodeSystemComparer(session);
|
||||
|
@ -138,11 +142,31 @@ public class ComparisonTests {
|
|||
String xml3 = new XhtmlComposer(true).compose(cs.renderExpansion(csc, "", ""));
|
||||
TextFile.stringToFile(HEADER + hd("Messages") + xmle + BREAK + hd("Metadata") + xml1 + BREAK + hd("Definition") + xml2 + BREAK + hd("Expansion") + xml3 + FOOTER, Utilities.path("[tmp]", "comparison", name + ".html"));
|
||||
checkOutcomes(csc.getMessages(), content);
|
||||
} else if (left instanceof StructureDefinition && right instanceof StructureDefinition) {
|
||||
ProfileUtilities utils = new ProfileUtilities(context, null, null);
|
||||
genSnapshot(utils, (StructureDefinition) left);
|
||||
genSnapshot(utils, (StructureDefinition) right);
|
||||
ProfileComparer pc = new ProfileComparer(session, utils);
|
||||
ProfileComparison csc = pc.compare((StructureDefinition) left, (StructureDefinition) right);
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-union.json")), csc.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-intersection.json")), csc.getIntersection());
|
||||
|
||||
String xmle = new XhtmlComposer(true).compose(pc.renderErrors(csc));
|
||||
String xml1 = new XhtmlComposer(true).compose(pc.renderMetadata(csc, "", ""));
|
||||
String xml2 = new XhtmlComposer(true).compose(pc.renderStructure(csc, "", "", "http://hl7.org/fhir"));
|
||||
// String xml3 = new XhtmlComposer(true).compose(cs.renderExpansion(csc, "", ""));
|
||||
TextFile.stringToFile(HEADER + hd("Messages") + xmle + BREAK + hd("Metadata") + xml1 + BREAK + hd("Structure") + xml2 + FOOTER, Utilities.path("[tmp]", "comparison", name + ".html"));
|
||||
checkOutcomes(csc.getMessages(), content);
|
||||
} else {
|
||||
throw new FHIRException("Can't compare " + left.fhirType() + " to " + right.fhirType());
|
||||
}
|
||||
}
|
||||
|
||||
private void genSnapshot(ProfileUtilities utils, StructureDefinition sd) {
|
||||
StructureDefinition base = context.fetchTypeDefinition(sd.getType());
|
||||
utils.generateSnapshot(base, sd, sd.getUrl(), "http://hl7.org/fhir/r4", sd.present());
|
||||
}
|
||||
|
||||
private String hd(String text) {
|
||||
return "<h2>" + text + "</h2>\r\n";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue