001package org.hl7.fhir.r5.renderers; 002 003import java.io.IOException; 004import java.util.ArrayList; 005import java.util.Collections; 006import java.util.List; 007import java.util.Map; 008 009import org.hl7.fhir.exceptions.DefinitionException; 010import org.hl7.fhir.exceptions.FHIRFormatError; 011import org.hl7.fhir.r5.model.CodeSystem; 012import org.hl7.fhir.r5.model.CodeSystem.CodeSystemContentMode; 013import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent; 014import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; 015import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent; 016import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent; 017import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent; 018import org.hl7.fhir.r5.model.Coding; 019import org.hl7.fhir.r5.model.DomainResource; 020import org.hl7.fhir.r5.model.Enumeration; 021import org.hl7.fhir.r5.model.Extension; 022import org.hl7.fhir.r5.model.Resource; 023import org.hl7.fhir.r5.renderers.utils.RenderingContext; 024import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 025import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; 026import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.CodeSystemNavigator; 027import org.hl7.fhir.r5.utils.ToolingExtensions; 028import org.hl7.fhir.utilities.Utilities; 029import org.hl7.fhir.utilities.xhtml.XhtmlNode; 030 031public class CodeSystemRenderer extends TerminologyRenderer { 032 033 public CodeSystemRenderer(RenderingContext context) { 034 super(context); 035 } 036 037 public CodeSystemRenderer(RenderingContext context, ResourceContext rcontext) { 038 super(context, rcontext); 039 } 040 041 042 public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException { 043 return render(x, (CodeSystem) dr); 044 } 045 046 public boolean render(XhtmlNode x, CodeSystem cs) throws FHIRFormatError, DefinitionException, IOException { 047 boolean hasExtensions = false; 048 049 if (context.isHeader()) { 050 XhtmlNode h = x.h2(); 051 h.addText(cs.hasTitle() ? cs.getTitle() : cs.getName()); 052 addMarkdown(x, cs.getDescription()); 053 if (cs.hasCopyright()) 054 generateCopyright(x, cs ); 055 } 056 057 generateProperties(x, cs); 058 generateFilters(x, cs); 059 List<UsedConceptMap> maps = new ArrayList<UsedConceptMap>(); 060 hasExtensions = generateCodeSystemContent(x, cs, hasExtensions, maps); 061 062 return hasExtensions; 063 } 064 065 public void describe(XhtmlNode x, CodeSystem cs) { 066 x.tx(display(cs)); 067 } 068 069 public String display(CodeSystem cs) { 070 return cs.present(); 071 } 072 073 private void generateFilters(XhtmlNode x, CodeSystem cs) { 074 if (cs.hasFilter()) { 075 x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Filters", getContext().getLang())); 076 XhtmlNode tbl = x.table("grid"); 077 XhtmlNode tr = tbl.tr(); 078 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Code", getContext().getLang())); 079 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Description", getContext().getLang())); 080 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "operator", getContext().getLang())); 081 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Value", getContext().getLang())); 082 for (CodeSystemFilterComponent f : cs.getFilter()) { 083 tr = tbl.tr(); 084 tr.td().tx(f.getCode()); 085 tr.td().tx(f.getDescription()); 086 XhtmlNode td = tr.td(); 087 for (Enumeration<org.hl7.fhir.r5.model.Enumerations.FilterOperator> t : f.getOperator()) 088 td.tx(t.asStringValue()+" "); 089 tr.td().tx(f.getValue()); 090 } 091 } 092 } 093 094 private void generateProperties(XhtmlNode x, CodeSystem cs) { 095 if (cs.hasProperty()) { 096 boolean hasRendered = false; 097 boolean hasURI = false; 098 for (PropertyComponent p : cs.getProperty()) { 099 hasRendered = hasRendered || !p.getCode().equals(ToolingExtensions.getPresentation(p, p.getCodeElement())); 100 hasURI = hasURI || p.hasUri(); 101 } 102 103 x.para().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Properties", getContext().getLang())); 104 XhtmlNode tbl = x.table("grid"); 105 XhtmlNode tr = tbl.tr(); 106 if (hasRendered) { 107 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Name", getContext().getLang())); 108 } 109 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Code", getContext().getLang())); 110 if (hasURI) { 111 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "URL", getContext().getLang())); 112 } 113 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Type", getContext().getLang())); 114 tr.td().b().tx(getContext().getWorker().translator().translate("xhtml-gen-cs", "Description", getContext().getLang())); 115 for (PropertyComponent p : cs.getProperty()) { 116 tr = tbl.tr(); 117 if (hasRendered) { 118 tr.td().tx(ToolingExtensions.getPresentation(p, p.getCodeElement())); 119 } 120 tr.td().tx(p.getCode()); 121 if (hasURI) { 122 tr.td().tx(p.getUri()); 123 } 124 tr.td().tx(p.hasType() ? p.getType().toCode() : ""); 125 tr.td().tx(p.getDescription()); 126 } 127 } 128 } 129 130 private boolean generateCodeSystemContent(XhtmlNode x, CodeSystem cs, boolean hasExtensions, List<UsedConceptMap> maps) throws FHIRFormatError, DefinitionException, IOException { 131 XhtmlNode p = x.para(); 132 if (cs.getContent() == CodeSystemContentMode.COMPLETE) 133 p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines the following codes", cs.getUrl())+":"); 134 else if (cs.getContent() == CodeSystemContentMode.EXAMPLE) 135 p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines some example codes", cs.getUrl())+":"); 136 else if (cs.getContent() == CodeSystemContentMode.FRAGMENT ) 137 p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines many codes, of which the following are a subset", cs.getUrl())+":"); 138 else if (cs.getContent() == CodeSystemContentMode.NOTPRESENT ) { 139 p.tx(getContext().getWorker().translator().translateAndFormat("xhtml-gen-cs", getContext().getLang(), "This code system %s defines many codes, but they are not represented here", cs.getUrl())); 140 return false; 141 } 142 XhtmlNode t = x.table( "codes"); 143 boolean definitions = false; 144 boolean commentS = false; 145 boolean deprecated = false; 146 boolean display = false; 147 boolean hierarchy = false; 148 boolean version = false; 149 boolean ignoreStatus = false; 150 boolean isSupplement = cs.getContent() == CodeSystemContentMode.SUPPLEMENT; 151 List<PropertyComponent> properties = new ArrayList<>(); 152 for (PropertyComponent cp : cs.getProperty()) { 153 if (showPropertyInTable(cp)) { 154 boolean exists = false; 155 for (ConceptDefinitionComponent c : cs.getConcept()) { 156 exists = exists || conceptsHaveProperty(c, cp); 157 } 158 if (exists) { 159 properties.add(cp); 160 if ("status".equals(cp.getCode())) { 161 ignoreStatus = true; 162 } 163 } 164 } 165 } 166 for (ConceptDefinitionComponent c : cs.getConcept()) { 167 commentS = commentS || conceptsHaveComments(c); 168 deprecated = deprecated || conceptsHaveDeprecated(cs, c, ignoreStatus); 169 display = display || conceptsHaveDisplay(c); 170 version = version || conceptsHaveVersion(c); 171 hierarchy = hierarchy || c.hasConcept(); 172 definitions = definitions || conceptsHaveDefinition(c); 173 } 174 CodeSystemNavigator csNav = new CodeSystemNavigator(cs); 175 hierarchy = hierarchy || csNav.isRestructure(); 176 177 List<String> langs = new ArrayList<>(); 178 addMapHeaders(addTableHeaderRowStandard(t, hierarchy, display, definitions, commentS, version, deprecated, properties, null, null, false), maps); 179 for (ConceptDefinitionComponent c : csNav.getConcepts(null)) { 180 hasExtensions = addDefineRowToTable(t, c, 0, hierarchy, display, definitions, commentS, version, deprecated, maps, cs.getUrl(), cs, properties, csNav, langs, isSupplement) || hasExtensions; 181 } 182 if (langs.size() > 0) { 183 Collections.sort(langs); 184 x.para().b().tx("Additional Language Displays"); 185 t = x.table( "codes"); 186 XhtmlNode tr = t.tr(); 187 tr.td().b().tx("Code"); 188 for (String lang : langs) 189 tr.td().b().addText(describeLang(lang)); 190 for (ConceptDefinitionComponent c : cs.getConcept()) { 191 addLanguageRow(c, t, langs); 192 } 193 } 194 return hasExtensions; 195 } 196 197 private boolean conceptsHaveDefinition(ConceptDefinitionComponent c) { 198 if (c.hasDefinition()) { 199 return true; 200 } 201 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) { 202 if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue())) { 203 return true; 204 } 205 } 206 for (ConceptDefinitionComponent g : c.getConcept()) { 207 if (conceptsHaveDefinition(g)) { 208 return true; 209 } 210 } 211 return false; 212 } 213 214 private boolean conceptsHaveProperty(ConceptDefinitionComponent c, PropertyComponent cp) { 215 if (CodeSystemUtilities.hasProperty(c, cp.getCode())) 216 return true; 217 for (ConceptDefinitionComponent g : c.getConcept()) 218 if (conceptsHaveProperty(g, cp)) 219 return true; 220 return false; 221 222 } 223 224 private boolean showPropertyInTable(PropertyComponent cp) { 225 if (cp.hasCode()) { 226 if (cp.hasExtension(ToolingExtensions.EXT_RENDERED_VALUE)) { 227 return true; 228 } 229 if (cp.getCodeElement().hasExtension(ToolingExtensions.EXT_RENDERED_VALUE)) { 230 return true; 231 } 232 String uri = cp.getUri(); 233 if (Utilities.noString(uri)){ 234 return true; // do we always want to render properties in this case? Not sure... 235 } 236 String code = null; 237 if (uri.contains("#")) { 238 code = uri.substring(uri.indexOf("#")+1); 239 uri = uri.substring(0, uri.indexOf("#")); 240 } 241 if (Utilities.existsInList(uri, "http://hl7.org/fhir/concept-properties") || context.getCodeSystemPropList().contains(uri)) { 242 return true; 243 }; 244 CodeSystem cs = getContext().getWorker().fetchCodeSystem(uri); 245 if (cs == null) { 246 return false; 247 } 248 return code == null ? false : CodeSystemUtilities.hasCode(cs, code); 249 } 250 return false; 251 } 252 253 254 private int countConcepts(List<ConceptDefinitionComponent> list) { 255 int count = list.size(); 256 for (ConceptDefinitionComponent c : list) 257 if (c.hasConcept()) 258 count = count + countConcepts(c.getConcept()); 259 return count; 260 } 261 262 private boolean conceptsHaveComments(ConceptDefinitionComponent c) { 263 if (ToolingExtensions.hasCSComment(c)) 264 return true; 265 for (ConceptDefinitionComponent g : c.getConcept()) 266 if (conceptsHaveComments(g)) 267 return true; 268 return false; 269 } 270 271 private boolean conceptsHaveDisplay(ConceptDefinitionComponent c) { 272 if (c.hasDisplay()) 273 return true; 274 for (ConceptDefinitionComponent g : c.getConcept()) 275 if (conceptsHaveDisplay(g)) 276 return true; 277 return false; 278 } 279 280 private boolean conceptsHaveVersion(ConceptDefinitionComponent c) { 281 if (c.hasUserData("cs.version.notes")) 282 return true; 283 for (ConceptDefinitionComponent g : c.getConcept()) 284 if (conceptsHaveVersion(g)) 285 return true; 286 return false; 287 } 288 289 private boolean conceptsHaveDeprecated(CodeSystem cs, ConceptDefinitionComponent c, boolean ignoreStatus) { 290 if (CodeSystemUtilities.isDeprecated(cs, c, ignoreStatus)) 291 return true; 292 for (ConceptDefinitionComponent g : c.getConcept()) 293 if (conceptsHaveDeprecated(cs, g, ignoreStatus)) 294 return true; 295 return false; 296 } 297 298 299 300 private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int level, boolean hasHierarchy, boolean hasDisplay, boolean hasDefinitions, boolean comment, boolean version, boolean deprecated, List<UsedConceptMap> maps, String system, CodeSystem cs, List<PropertyComponent> properties, CodeSystemNavigator csNav, List<String> langs, boolean isSupplement) throws FHIRFormatError, DefinitionException, IOException { 301 boolean hasExtensions = false; 302 XhtmlNode tr = t.tr(); 303 XhtmlNode td = tr.td(); 304 if (hasHierarchy) { 305 td.addText(Integer.toString(level+1)); 306 td = tr.td(); 307 String s = Utilities.padLeft("", '\u00A0', level*2); 308 td.addText(s); 309 } 310 String link = isSupplement ? getLinkForCode(cs.getSupplements(), null, c.getCode()) : null; 311 if (link != null) { 312 td.ah(link).attribute("style", "white-space:nowrap").addText(c.getCode()); 313 } else { 314 td.attribute("style", "white-space:nowrap").addText(c.getCode()); 315 } 316 XhtmlNode a; 317 if (c.hasCodeElement()) { 318 td.an(cs.getId()+"-" + Utilities.nmtokenize(c.getCode())); 319 } 320 321 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) { 322 if (cd.hasLanguage() && !langs.contains(cd.getLanguage()) && (!cs.hasLanguage() || !cs.getLanguage().equals(cd.getLanguage()))) { 323 langs.add(cd.getLanguage()); 324 } 325 326 } 327 328 if (hasDisplay) { 329 td = tr.td(); 330 renderDisplayName(c, cs, td); 331 } 332 if (hasDefinitions) { 333 td = tr.td(); 334 if (c != null && 335 c.hasDefinitionElement()) { 336 if (getContext().getLang() == null) { 337 if (hasMarkdownInDefinitions(cs)) 338 addMarkdown(td, c.getDefinition()); 339 else 340 td.addText(c.getDefinition()); 341 } else if (getContext().getLang().equals("*")) { 342 boolean sl = false; 343 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) 344 if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue())) 345 sl = true; 346 td.addText((sl ? cs.getLanguage("en")+": " : "")+c.getDefinition()); 347 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) { 348 if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && !c.getDefinition().equalsIgnoreCase(cd.getValue())) { 349 td.br(); 350 td.addText(cd.getLanguage()+": "+cd.getValue()); 351 } 352 } 353 } else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) { 354 td.addText(c.getDefinition()); 355 } else { 356 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) { 357 if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "definition") && cd.hasLanguage() && cd.getLanguage().equals(getContext().getLang())) { 358 td.addText(cd.getValue()); 359 } 360 } 361 } 362 } 363 } 364 if (deprecated) { 365 td = tr.td(); 366 Boolean b = CodeSystemUtilities.isDeprecated(cs, c, false); 367 if (b != null && b) { 368 smartAddText(td, getContext().getWorker().translator().translate("xhtml-gen-cs", "Deprecated", getContext().getLang())); 369 hasExtensions = true; 370 if (ToolingExtensions.hasExtension(c, ToolingExtensions.EXT_REPLACED_BY)) { 371 Coding cc = (Coding) ToolingExtensions.getExtension(c, ToolingExtensions.EXT_REPLACED_BY).getValue(); 372 td.tx(" (replaced by "); 373 String url = getCodingReference(cc, system); 374 if (url != null) { 375 td.ah(url).addText(cc.getCode()); 376 td.tx(": "+cc.getDisplay()+")"); 377 } else 378 td.addText(cc.getCode()+" '"+cc.getDisplay()+"' in "+cc.getSystem()+")"); 379 } 380 } 381 } 382 if (comment) { 383 td = tr.td(); 384 Extension ext = c.getExtensionByUrl(ToolingExtensions.EXT_CS_COMMENT); 385 if (ext != null) { 386 hasExtensions = true; 387 String bc = ext.hasValue() ? ext.getValue().primitiveValue() : null; 388 Map<String, String> translations = ToolingExtensions.getLanguageTranslations(ext.getValue()); 389 390 if (getContext().getLang() == null) { 391 if (bc != null) 392 td.addText(bc); 393 } else if (getContext().getLang().equals("*")) { 394 boolean sl = false; 395 for (String l : translations.keySet()) 396 if (bc == null || !bc.equalsIgnoreCase(translations.get(l))) 397 sl = true; 398 if (bc != null) { 399 td.addText((sl ? cs.getLanguage("en")+": " : "")+bc); 400 } 401 for (String l : translations.keySet()) { 402 if (bc == null || !bc.equalsIgnoreCase(translations.get(l))) { 403 if (!td.getChildNodes().isEmpty()) 404 td.br(); 405 td.addText(l+": "+translations.get(l)); 406 } 407 } 408 } else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) { 409 if (bc != null) 410 td.addText(bc); 411 } else { 412 if (bc != null) 413 translations.put(cs.getLanguage("en"), bc); 414 for (String l : translations.keySet()) { 415 if (l.equals(getContext().getLang())) { 416 td.addText(translations.get(l)); 417 } 418 } 419 } 420 } 421 } 422 if (version) { 423 td = tr.td(); 424 if (c.hasUserData("cs.version.notes")) 425 td.addText(c.getUserString("cs.version.notes")); 426 } 427 if (properties != null) { 428 for (PropertyComponent pc : properties) { 429 td = tr.td(); 430 boolean first = true; 431 List<ConceptPropertyComponent> pcvl = CodeSystemUtilities.getPropertyValues(c, pc.getCode()); 432 for (ConceptPropertyComponent pcv : pcvl) { 433 if (pcv.hasValue()) { 434 if (first) first = false; else td.addText(", "); 435 if (pcv.hasValueCoding()) { 436 td.addText(pcv.getValueCoding().getCode()); 437 } else if (pcv.hasValueStringType() && Utilities.isAbsoluteUrlLinkable(pcv.getValue().primitiveValue())) { 438 td.ah(pcv.getValue().primitiveValue()).tx(pcv.getValue().primitiveValue()); 439 } else { 440 td.addText(pcv.getValue().primitiveValue()); 441 } 442 } 443 } 444 } 445 } 446 447 for (UsedConceptMap m : maps) { 448 td = tr.td(); 449 List<TargetElementComponentWrapper> mappings = findMappingsForCode(c.getCode(), m.getMap()); 450 boolean first = true; 451 for (TargetElementComponentWrapper mapping : mappings) { 452 if (!first) 453 td.br(); 454 first = false; 455 XhtmlNode span = td.span(null, mapping.comp.hasRelationship() ? mapping.comp.getRelationship().toCode() : ""); 456 span.addText(getCharForRelationship(mapping.comp)); 457 a = td.ah(getContext().getSpecificationLink()+m.getLink()+"#"+makeAnchor(mapping.group.getTarget(), mapping.comp.getCode())); 458 a.addText(mapping.comp.getCode()); 459 if (!Utilities.noString(mapping.comp.getComment())) 460 td.i().tx("("+mapping.comp.getComment()+")"); 461 } 462 } 463 List<ConceptDefinitionComponent> ocl = csNav.getOtherChildren(c); 464 for (ConceptDefinitionComponent cc : csNav.getConcepts(c)) { 465 hasExtensions = addDefineRowToTable(t, cc, level+1, hasHierarchy, hasDisplay, hasDefinitions, comment, version, deprecated, maps, system, cs, properties, csNav, langs, isSupplement) || hasExtensions; 466 } 467 for (ConceptDefinitionComponent cc : ocl) { 468 tr = t.tr(); 469 td = tr.td(); 470 td.addText(Integer.toString(level+2)); 471 td = tr.td(); 472 String s = Utilities.padLeft("", '\u00A0', (level+1)*2); 473 td.addText(s); 474 td.attribute("style", "white-space:nowrap"); 475 a = td.ah("#"+cs.getId()+"-" + Utilities.nmtokenize(cc.getCode())); 476 a.addText(cc.getCode()); 477 if (hasDisplay) { 478 td = tr.td(); 479 renderDisplayName(cc, cs, td); 480 } 481 int w = 1 + (deprecated ? 1 : 0) + (comment ? 1 : 0) + (version ? 1 : 0) + maps.size(); 482 if (properties != null) { 483 w = w + properties.size(); 484 } 485 td = tr.td().colspan(Integer.toString(w)); 486 } 487 return hasExtensions; 488 } 489 490 private boolean hasMarkdownInDefinitions(CodeSystem cs) { 491 return ToolingExtensions.readBoolExtension(cs, "http://hl7.org/fhir/StructureDefinition/codesystem-use-markdown"); 492 } 493 494 495 public void renderDisplayName(ConceptDefinitionComponent c, CodeSystem cs, XhtmlNode td) { 496 if (c.hasDisplayElement()) { 497 if (getContext().getLang() == null) { 498 td.addText(c.getDisplay()); 499 } else if (getContext().getLang().equals("*")) { 500 boolean sl = false; 501 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) 502 if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && !c.getDisplay().equalsIgnoreCase(cd.getValue())) 503 sl = true; 504 td.addText((sl ? cs.getLanguage("en")+": " : "")+c.getDisplay()); 505 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) { 506 if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && !c.getDisplay().equalsIgnoreCase(cd.getValue())) { 507 td.br(); 508 td.addText(cd.getLanguage()+": "+cd.getValue()); 509 } 510 } 511 } else if (getContext().getLang().equals(cs.getLanguage()) || (getContext().getLang().equals("en") && !cs.hasLanguage())) { 512 td.addText(c.getDisplay()); 513 } else { 514 for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) { 515 if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && cd.getLanguage().equals(getContext().getLang())) { 516 td.addText(cd.getValue()); 517 } 518 } 519 } 520 } 521 } 522 523 private String getCodingReference(Coding cc, String system) { 524 if (cc.getSystem().equals(system)) 525 return "#"+cc.getCode(); 526 if (cc.getSystem().equals("http://snomed.info/sct")) 527 return "http://snomed.info/sct/"+cc.getCode(); 528 if (cc.getSystem().equals("http://loinc.org")) 529 return "http://s.details.loinc.org/LOINC/"+cc.getCode()+".html"; 530 return null; 531 } 532 533 534 private void addLanguageRow(ConceptDefinitionComponent c, XhtmlNode t, List<String> langs) { 535 XhtmlNode tr = t.tr(); 536 tr.td().addText(c.getCode()); 537 for (String lang : langs) { 538 ConceptDefinitionDesignationComponent d = null; 539 for (ConceptDefinitionDesignationComponent designation : c.getDesignation()) { 540 if (designation.hasLanguage()) { 541 if (lang.equals(designation.getLanguage())) 542 d = designation; 543 } 544 } 545 tr.td().addText(d == null ? "" : d.getValue()); 546 } 547 } 548 549}