Merge pull request #655 from hapifhir/gg-202111-conceptmap-rendering
Gg 202111 conceptmap rendering
This commit is contained in:
commit
cf440359aa
|
@ -160,11 +160,24 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
addUnmapped(tbl, grp);
|
||||
}
|
||||
} else {
|
||||
boolean hasRelationships = false;
|
||||
for (int si = 0; si < grp.getElement().size(); si++) {
|
||||
SourceElementComponent ccl = grp.getElement().get(si);
|
||||
for (int ti = 0; ti < ccl.getTarget().size(); ti++) {
|
||||
TargetElementComponent ccm = ccl.getTarget().get(ti);
|
||||
if (ccm.hasRelationship()) {
|
||||
hasRelationships = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XhtmlNode tbl = x.table( "grid");
|
||||
XhtmlNode tr = tbl.tr();
|
||||
XhtmlNode td;
|
||||
tr.td().colspan(Integer.toString(1+sources.size())).b().tx("Source Concept Details");
|
||||
tr.td().b().tx("Relationship");
|
||||
if (hasRelationships) {
|
||||
tr.td().b().tx("Relationship");
|
||||
}
|
||||
tr.td().colspan(Integer.toString(1+targets.size())).b().tx("Destination Concept Details");
|
||||
if (comment) {
|
||||
tr.td().b().tx("Comment");
|
||||
|
@ -184,7 +197,9 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
tr.td().b().addText(getDescForConcept(s));
|
||||
}
|
||||
}
|
||||
tr.td();
|
||||
if (hasRelationships) {
|
||||
tr.td();
|
||||
}
|
||||
if (targets.get("code").size() == 1) {
|
||||
String url = targets.get("code").iterator().next();
|
||||
renderCSDetailsLink(tr, url, true);
|
||||
|
@ -238,23 +253,19 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
td.addText(ccl.getCode());
|
||||
else
|
||||
td.addText(grp.getSource()+" / "+ccl.getCode());
|
||||
display = getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
|
||||
display = ccl.hasDisplay() ? ccl.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
|
||||
td = tr.td();
|
||||
if (!first)
|
||||
td.style("border-left-width: 0px; border-top-style: none");
|
||||
else if (!last)
|
||||
if (!last)
|
||||
td.style("border-left-width: 0px; border-bottom-style: none");
|
||||
else
|
||||
td.style("border-left-width: 0px");
|
||||
td.tx(display == null ? "" : display);
|
||||
} else {
|
||||
td = tr.td(); // for display
|
||||
if (!first)
|
||||
td.style("border-left-width: 0px; border-top-style: none");
|
||||
else if (!last)
|
||||
td.style("border-left-width: 0px; border-bottom-style: none");
|
||||
if (!last)
|
||||
td.style("border-left-width: 0px; border-top-style: none; border-bottom-style: none");
|
||||
else
|
||||
td.style("border-left-width: 0px");
|
||||
td.style("border-top-style: none; border-left-width: 0px");
|
||||
}
|
||||
for (String s : sources.keySet()) {
|
||||
if (!s.equals("code")) {
|
||||
|
@ -268,14 +279,16 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
}
|
||||
}
|
||||
first = false;
|
||||
if (!ccm.hasRelationship())
|
||||
tr.td().tx(":"+"("+ConceptMapRelationship.EQUIVALENT.toCode()+")");
|
||||
else {
|
||||
if (ccm.getRelationshipElement().hasExtension(ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) {
|
||||
String code = ToolingExtensions.readStringExtension(ccm.getRelationshipElement(), ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE);
|
||||
tr.td().ah(eqpath+"#"+code).tx(presentEquivalenceCode(code));
|
||||
} else {
|
||||
tr.td().ah(eqpath+"#"+ccm.getRelationship().toCode()).tx(presentRelationshipCode(ccm.getRelationship().toCode()));
|
||||
if (hasRelationships) {
|
||||
if (!ccm.hasRelationship())
|
||||
tr.td();
|
||||
else {
|
||||
if (ccm.getRelationshipElement().hasExtension(ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) {
|
||||
String code = ToolingExtensions.readStringExtension(ccm.getRelationshipElement(), ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE);
|
||||
tr.td().ah(eqpath+"#"+code).tx(presentEquivalenceCode(code));
|
||||
} else {
|
||||
tr.td().ah(eqpath+"#"+ccm.getRelationship().toCode()).tx(presentRelationshipCode(ccm.getRelationship().toCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
td = tr.td().style("border-right-width: 0px");
|
||||
|
@ -283,7 +296,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
td.addText(ccm.getCode());
|
||||
else
|
||||
td.addText(grp.getTarget()+" / "+ccm.getCode());
|
||||
display = getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
|
||||
display = ccm.hasDisplay() ? ccm.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
|
||||
tr.td().style("border-left-width: 0px").tx(display == null ? "" : display);
|
||||
|
||||
for (String s : targets.keySet()) {
|
||||
|
|
|
@ -1320,7 +1320,7 @@ public class DataRenderer extends Renderer {
|
|||
} else if (system.contains("|")) {
|
||||
return system.substring(0, system.indexOf("|"));
|
||||
} else {
|
||||
return system;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -290,7 +290,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (i.hasAnswerValueSet()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Value Set: ", null));
|
||||
if (i.getAnswerValueSet().startsWith("#")) {
|
||||
if (!Utilities.noString(i.getAnswerValueSet()) && i.getAnswerValueSet().startsWith("#")) {
|
||||
ValueSet vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
|
||||
if (vs == null) {
|
||||
defn.getPieces().add(gen.new Piece(null, i.getAnswerValueSet(), null));
|
||||
|
@ -469,7 +469,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (i.hasAnswerValueSet()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Value Set: ", null));
|
||||
if (i.getAnswerValueSet().startsWith("#")) {
|
||||
if (Utilities.noString(i.getAnswerValueSet()) && i.getAnswerValueSet().startsWith("#")) {
|
||||
ValueSet vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
|
||||
if (vs == null) {
|
||||
defn.getPieces().add(gen.new Piece(null, i.getAnswerValueSet(), null));
|
||||
|
@ -703,7 +703,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
}
|
||||
if (i.hasAnswerValueSet()) {
|
||||
XhtmlNode ans = item(ul, "Answers");
|
||||
if (i.getAnswerValueSet().startsWith("#")) {
|
||||
if (Utilities.noString(i.getAnswerValueSet()) && i.getAnswerValueSet().startsWith("#")) {
|
||||
ValueSet vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
|
||||
if (vs == null) {
|
||||
ans.tx(i.getAnswerValueSet());
|
||||
|
@ -792,7 +792,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
private void listOptions(Questionnaire q, QuestionnaireItemComponent i, XhtmlNode select) {
|
||||
if (i.hasAnswerValueSet()) {
|
||||
ValueSet vs = null;
|
||||
if (i.getAnswerValueSet().startsWith("#")) {
|
||||
if (Utilities.noString(i.getAnswerValueSet()) && i.getAnswerValueSet().startsWith("#")) {
|
||||
vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
|
||||
if (vs != null && !vs.hasUrl()) {
|
||||
vs = vs.copy();
|
||||
|
|
|
@ -104,7 +104,7 @@ public class TerminologyCacheManager {
|
|||
Utilities.createDirectory(path);
|
||||
} else {
|
||||
Utilities.createDirectory(Utilities.getDirectoryForFile(path));
|
||||
TextFile.streamToFile(zipIn, path);
|
||||
TextFile.streamToFileNoClose(zipIn, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +154,8 @@ public class TerminologyCacheManager {
|
|||
String url = "https://tx.fhir.org/post/tx-cache/"+ghOrg+"/"+ghRepo+"/"+ghBranch+".zip";
|
||||
System.out.println("Sending tx-cache to "+url+" ("+Utilities.describeSize(bs.toByteArray().length)+")");
|
||||
SimpleHTTPClient http = new SimpleHTTPClient();
|
||||
http.setUsername(token.substring(0, token.indexOf(':')));
|
||||
http.setPassword(token.substring(token.indexOf(':')+1));
|
||||
HTTPResult res = http.put(url, "application/zip", bs.toByteArray(), null); // accept doesn't matter
|
||||
if (res.getCode() >= 300) {
|
||||
System.out.println("sending cache failed: "+res.getCode());
|
||||
|
|
|
@ -166,14 +166,23 @@ public class TextFile {
|
|||
if (input== null) {
|
||||
return null;
|
||||
}
|
||||
// Define a size if you have an idea of it.
|
||||
ByteArrayOutputStream r = new ByteArrayOutputStream(2048);
|
||||
byte[] read = new byte[512]; // Your buffer size.
|
||||
byte[] read = new byte[512];
|
||||
for (int i; -1 != (i = input.read(read)); r.write(read, 0, i));
|
||||
input.close();
|
||||
return r.toByteArray();
|
||||
}
|
||||
|
||||
public static byte[] streamToBytesNoClose(InputStream input) throws IOException {
|
||||
if (input== null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream r = new ByteArrayOutputStream(2048);
|
||||
byte[] read = new byte[512];
|
||||
for (int i; -1 != (i = input.read(read)); r.write(read, 0, i));
|
||||
return r.toByteArray();
|
||||
}
|
||||
|
||||
public static void bytesToFile(byte[] bytes, String path) throws IOException {
|
||||
File file = new CSFile(path);
|
||||
OutputStream sw = new FileOutputStream(file);
|
||||
|
@ -231,4 +240,9 @@ public class TextFile {
|
|||
byte[] cnt = streamToBytes(stream);
|
||||
bytesToFile(cnt, filename);
|
||||
}
|
||||
|
||||
public static void streamToFileNoClose(InputStream stream, String filename) throws IOException {
|
||||
byte[] cnt = streamToBytesNoClose(stream);
|
||||
bytesToFile(cnt, filename);
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ public class I18nConstants {
|
|||
public static final String BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES = "BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES";
|
||||
public static final String BUNDLE_BUNDLE_ENTRY_NOTFOUND = "Bundle_BUNDLE_Entry_NotFound";
|
||||
public static final String BUNDLE_BUNDLE_ENTRY_ORPHAN = "Bundle_BUNDLE_Entry_Orphan";
|
||||
public static final String BUNDLE_BUNDLE_ENTRY_REVERSE = "BUNDLE_BUNDLE_ENTRY_REVERSE";
|
||||
public static final String BUNDLE_BUNDLE_ENTRY_TYPE = "Bundle_BUNDLE_Entry_Type";
|
||||
public static final String BUNDLE_BUNDLE_ENTRY_TYPE2 = "Bundle_BUNDLE_Entry_Type2";
|
||||
public static final String BUNDLE_BUNDLE_ENTRY_TYPE3 = "Bundle_BUNDLE_Entry_Type3";
|
||||
|
|
|
@ -11,6 +11,7 @@ BUNDLE_BUNDLE_ENTRY_FULLURL_REQUIRED = Except for transactions and batches, each
|
|||
Bundle_BUNDLE_Entry_NoProfile = No profile found for contained resource of type ''{0}''
|
||||
Bundle_BUNDLE_Entry_NotFound = Can''t find ''{0}'' in the bundle ({1})
|
||||
Bundle_BUNDLE_Entry_Orphan = Entry {0} isn''t reachable by traversing from first Bundle entry
|
||||
BUNDLE_BUNDLE_ENTRY_REVERSE = Entry {0} isn''t reachable by traversing forwards from first Bundle entry, and isn''t a resource type that is typically used that way - check this is not missed somewhere
|
||||
Bundle_BUNDLE_Entry_Type = The type ''{0}'' is not valid - no resources allowed here (allowed = {1})
|
||||
Bundle_BUNDLE_Entry_Type2 = The type ''{0}'' is not valid - must be {1} (allowed = {2})
|
||||
Bundle_BUNDLE_Entry_Type3 = The type ''{0}'' is not valid - must be one of {1}
|
||||
|
|
|
@ -396,20 +396,30 @@ public class BundleValidator extends BaseValidator{
|
|||
|
||||
private void checkAllInterlinked(List<ValidationMessage> errors, List<Element> entries, NodeStack stack, Element bundle, boolean isError) {
|
||||
List<EntrySummary> entryList = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (Element entry : entries) {
|
||||
Element r = entry.getNamedChild(RESOURCE);
|
||||
if (r != null) {
|
||||
entryList.add(new EntrySummary(entry, r));
|
||||
EntrySummary e = new EntrySummary(i, entry, r);
|
||||
entryList.add(e);
|
||||
System.out.println("Found entry "+e.dbg());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
for (EntrySummary e : entryList) {
|
||||
Set<String> references = findReferences(e.getEntry());
|
||||
for (String ref : references) {
|
||||
Element tgt = resolveInBundle(entries, ref, e.getEntry().getChildValue(FULL_URL), e.getResource().fhirType(), e.getResource().getIdBase());
|
||||
if (tgt != null) {
|
||||
EntrySummary t = entryForTarget(entryList, tgt);
|
||||
if (t != null) {
|
||||
e.getTargets().add(t);
|
||||
if (t != null ) {
|
||||
if (t != e) {
|
||||
System.out.println("Entry "+e.getIndex()+" refers to "+t.getIndex()+" by ref '"+ref+"'");
|
||||
e.getTargets().add(t);
|
||||
} else {
|
||||
System.out.println("Entry "+e.getIndex()+" refers to itself by '"+ref+"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -422,6 +432,7 @@ public class BundleValidator extends BaseValidator{
|
|||
foundRevLinks = false;
|
||||
for (EntrySummary e : entryList) {
|
||||
if (!visited.contains(e)) {
|
||||
System.out.println("Not visited "+e.getIndex()+" - check for reverse links");
|
||||
boolean add = false;
|
||||
for (EntrySummary t : e.getTargets()) {
|
||||
if (visited.contains(t)) {
|
||||
|
@ -429,6 +440,10 @@ public class BundleValidator extends BaseValidator{
|
|||
}
|
||||
}
|
||||
if (add) {
|
||||
warning(errors, IssueType.INFORMATIONAL, e.getEntry().line(), e.getEntry().col(),
|
||||
stack.addToLiteralPath(ENTRY + '[' + (i + 1) + ']'), isExpectedToBeReverse(e.getResource().fhirType()),
|
||||
I18nConstants.BUNDLE_BUNDLE_ENTRY_REVERSE, (e.getEntry().getChildValue(FULL_URL) != null ? "'" + e.getEntry().getChildValue(FULL_URL) + "'" : ""));
|
||||
System.out.println("Found reverse links for "+e.getIndex());
|
||||
foundRevLinks = true;
|
||||
visitLinked(visited, e);
|
||||
}
|
||||
|
@ -436,7 +451,7 @@ public class BundleValidator extends BaseValidator{
|
|||
}
|
||||
} while (foundRevLinks);
|
||||
|
||||
int i = 0;
|
||||
i = 0;
|
||||
for (EntrySummary e : entryList) {
|
||||
Element entry = e.getEntry();
|
||||
if (isError) {
|
||||
|
@ -450,6 +465,10 @@ public class BundleValidator extends BaseValidator{
|
|||
|
||||
|
||||
|
||||
private boolean isExpectedToBeReverse(String fhirType) {
|
||||
return Utilities.existsInList(fhirType, "Provenance");
|
||||
}
|
||||
|
||||
private String uriRegexForVersion() {
|
||||
if (VersionUtilities.isR3Ver(context.getVersion()))
|
||||
return URI_REGEX3;
|
||||
|
|
|
@ -10,6 +10,7 @@ public class EntrySummary {
|
|||
Element entry;
|
||||
Element resource;
|
||||
List<EntrySummary> targets = new ArrayList<>();
|
||||
private int index;
|
||||
|
||||
public Element getEntry() {
|
||||
return entry;
|
||||
|
@ -38,8 +39,17 @@ public class EntrySummary {
|
|||
return this;
|
||||
}
|
||||
|
||||
public EntrySummary(Element entry, Element resource) {
|
||||
this.entry = entry;
|
||||
this.resource = resource;
|
||||
public EntrySummary(int i, Element entry, Element resource) {
|
||||
this.index = i;
|
||||
this.entry = entry;
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String dbg() {
|
||||
return ""+index+"="+ entry.getChildValue("fullUrl")+" | "+resource.getIdBase() + "("+resource.fhirType()+")";
|
||||
}
|
||||
|
||||
public String getIndex() {
|
||||
return Integer.toString(index);
|
||||
}
|
||||
}
|
2
pom.xml
2
pom.xml
|
@ -19,7 +19,7 @@
|
|||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.1.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.73-SNAPSHOT</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.73</validator_test_case_version>
|
||||
<junit_jupiter_version>5.7.1</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.7.1</junit_platform_launcher_version>
|
||||
<maven_surefire_version>3.0.0-M4</maven_surefire_version>
|
||||
|
|
Loading…
Reference in New Issue