use of org.hl7.fhir.utilities.validation.ValidationMessage.Source in project org.hl7.fhir.core by hapifhir.
the class ProfileUtilities method processPaths.
/**
* @param trimDifferential
* @throws DefinitionException, FHIRException
* @throws Exception
*/
private void processPaths(StructureDefinitionSnapshotComponent result, StructureDefinitionSnapshotComponent base, StructureDefinitionDifferentialComponent differential, int baseCursor, int diffCursor, int baseLimit, int diffLimit, String url, String profileName, String contextPath, boolean trimDifferential, String contextName, String resultPathBase, boolean slicingDone) throws DefinitionException, FHIRException {
// just repeat processing entries until we run out of our allowed scope (1st entry, the allowed scope is all the entries)
while (baseCursor <= baseLimit) {
// get the current focus of the base, and decide what to do
ElementDefinition currentBase = base.getElement().get(baseCursor);
String cpath = fixedPath(contextPath, currentBase.getPath());
// get a list of matching elements in scope
List<ElementDefinition> diffMatches = getDiffMatches(differential, cpath, diffCursor, diffLimit, profileName);
// in the simple case, source is not sliced.
if (!currentBase.hasSlicing()) {
if (diffMatches.isEmpty()) {
// the differential doesn't say anything about this item
// so we just copy it in
ElementDefinition outcome = updateURLs(url, currentBase.copy());
outcome.setPath(fixedPath(contextPath, outcome.getPath()));
updateFromBase(outcome, currentBase);
markDerived(outcome);
if (resultPathBase == null)
resultPathBase = outcome.getPath();
else if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException("Adding wrong path");
result.getElement().add(outcome);
baseCursor++;
} else if (diffMatches.size() == 1 && (slicingDone || (!diffMatches.get(0).hasSlicing() && !(isExtension(diffMatches.get(0)) && !diffMatches.get(0).hasName())))) {
// one matching element in the differential
ElementDefinition template = null;
if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !diffMatches.get(0).getType().get(0).getCode().equals("Reference")) {
String p = diffMatches.get(0).getType().get(0).getProfile().get(0).asStringValue();
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p);
if (sd != null) {
if (!sd.hasSnapshot()) {
StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
if (sdb == null)
throw new DefinitionException("no base for " + sd.getBaseDefinition());
generateSnapshot(sdb, sd, sd.getUrl(), sd.getName());
}
template = sd.getSnapshot().getElement().get(0).copy().setPath(currentBase.getPath());
// temporary work around
if (!diffMatches.get(0).getType().get(0).getCode().equals("Extension")) {
template.setMin(currentBase.getMin());
template.setMax(currentBase.getMax());
}
}
}
if (template == null)
template = currentBase.copy();
else
// some of what's in currentBase overrides template
template = overWriteWithCurrent(template, currentBase);
ElementDefinition outcome = updateURLs(url, template);
outcome.setPath(fixedPath(contextPath, outcome.getPath()));
updateFromBase(outcome, currentBase);
if (diffMatches.get(0).hasName())
outcome.setName(diffMatches.get(0).getName());
outcome.setSlicing(null);
updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url);
if (// if the base profile allows multiple types, but the profile only allows one, rename it
outcome.getPath().endsWith("[x]") && outcome.getType().size() == 1 && !outcome.getType().get(0).getCode().equals("*"))
outcome.setPath(outcome.getPath().substring(0, outcome.getPath().length() - 3) + Utilities.capitalize(outcome.getType().get(0).getCode()));
if (resultPathBase == null)
resultPathBase = outcome.getPath();
else if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException("Adding wrong path");
result.getElement().add(outcome);
baseCursor++;
diffCursor = differential.getElement().indexOf(diffMatches.get(0)) + 1;
if (differential.getElement().size() > diffCursor && outcome.getPath().contains(".") && isDataType(outcome.getType())) {
// don't want to do this for the root, since that's base, and we're already processing it
if (pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath() + ".")) {
if (outcome.getType().size() > 1)
throw new DefinitionException(diffMatches.get(0).getPath() + " has children (" + differential.getElement().get(diffCursor).getPath() + ") and multiple types (" + typeCode(outcome.getType()) + ") in profile " + profileName);
StructureDefinition dt = getProfileForDataType(outcome.getType().get(0));
if (dt == null)
throw new DefinitionException(diffMatches.get(0).getPath() + " has children (" + differential.getElement().get(diffCursor).getPath() + ") for type " + typeCode(outcome.getType()) + " in profile " + profileName + ", but can't find type");
contextName = dt.getUrl();
int start = diffCursor;
while (differential.getElement().size() > diffCursor && pathStartsWith(differential.getElement().get(diffCursor).getPath(), diffMatches.get(0).getPath() + ".")) diffCursor++;
processPaths(result, dt.getSnapshot(), differential, 1, /* starting again on the data type, but skip the root */
start - 1, dt.getSnapshot().getElement().size() - 1, diffCursor - 1, url, profileName + pathTail(diffMatches, 0), diffMatches.get(0).getPath(), trimDifferential, contextName, resultPathBase, false);
}
}
} else {
// ok, the differential slices the item. Let's check our pre-conditions to ensure that this is correct
if (!unbounded(currentBase) && !isSlicedToOneOnly(diffMatches.get(0)))
// (but you might do that in order to split up constraints by type)
throw new DefinitionException("Attempt to a slice an element that does not repeat: " + currentBase.getPath() + "/" + currentBase.getName() + " from " + contextName);
if (// well, the diff has set up a slice, but hasn't defined it. this is an error
!diffMatches.get(0).hasSlicing() && !isExtension(currentBase))
throw new DefinitionException("differential does not have a slice: " + currentBase.getPath());
// well, if it passed those preconditions then we slice the dest.
// we're just going to accept the differential slicing at face value
ElementDefinition outcome = updateURLs(url, currentBase.copy());
outcome.setPath(fixedPath(contextPath, outcome.getPath()));
updateFromBase(outcome, currentBase);
if (!diffMatches.get(0).hasSlicing())
outcome.setSlicing(makeExtensionSlicing());
else
outcome.setSlicing(diffMatches.get(0).getSlicing().copy());
if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException("Adding wrong path");
result.getElement().add(outcome);
// differential - if the first one in the list has a name, we'll process it. Else we'll treat it as the base definition of the slice.
int start = 0;
if (!diffMatches.get(0).hasName()) {
updateFromDefinition(outcome, diffMatches.get(0), profileName, trimDifferential, url);
if (!outcome.hasType()) {
throw new DefinitionException("not done yet");
}
start = 1;
} else
checkExtensionDoco(outcome);
// now, for each entry in the diff matches, we're going to process the base item
// our processing scope for base is all the children of the current path
int nbl = findEndOfElement(base, baseCursor);
int ndc = diffCursor;
int ndl = diffCursor;
for (int i = start; i < diffMatches.size(); i++) {
// our processing scope for the differential is the item in the list, and all the items before the next one in the list
ndc = differential.getElement().indexOf(diffMatches.get(i));
ndl = findEndOfElement(differential, ndc);
// now we process the base scope repeatedly for each instance of the item in the differential list
processPaths(result, base, differential, baseCursor, ndc, nbl, ndl, url, profileName + pathTail(diffMatches, i), contextPath, trimDifferential, contextName, resultPathBase, true);
}
// ok, done with that - next in the base list
baseCursor = nbl + 1;
diffCursor = ndl + 1;
}
} else {
// the item is already sliced in the base profile.
// here's the rules
// 1. irrespective of whether the slicing is ordered or not, the definition order must be maintained
// 2. slice element names have to match.
// 3. new slices must be introduced at the end
// corallory: you can't re-slice existing slices. is that ok?
// we're going to need this:
String path = currentBase.getPath();
ElementDefinition original = currentBase;
if (diffMatches.isEmpty()) {
// copy across the currentbase, and all of it's children and siblings
while (baseCursor < base.getElement().size() && base.getElement().get(baseCursor).getPath().startsWith(path)) {
ElementDefinition outcome = updateURLs(url, base.getElement().get(baseCursor).copy());
if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException("Adding wrong path: " + outcome.getPath() + " vs " + resultPathBase);
// so we just copy it in
result.getElement().add(outcome);
baseCursor++;
}
} else {
// first - check that the slicing is ok
boolean closed = currentBase.getSlicing().getRules() == SlicingRules.CLOSED;
int diffpos = 0;
boolean isExtension = cpath.endsWith(".extension") || cpath.endsWith(".modifierExtension");
if (diffMatches.get(0).hasSlicing()) {
// it might be null if the differential doesn't want to say anything about slicing
if (!isExtension)
// if there's a slice on the first, we'll ignore any content it has
diffpos++;
ElementDefinitionSlicingComponent dSlice = diffMatches.get(0).getSlicing();
ElementDefinitionSlicingComponent bSlice = currentBase.getSlicing();
if (!orderMatches(dSlice.getOrderedElement(), bSlice.getOrderedElement()))
throw new DefinitionException("Slicing rules on differential (" + summariseSlicing(dSlice) + ") do not match those on base (" + summariseSlicing(bSlice) + ") - order @ " + path + " (" + contextName + ")");
if (!discriiminatorMatches(dSlice.getDiscriminator(), bSlice.getDiscriminator()))
throw new DefinitionException("Slicing rules on differential (" + summariseSlicing(dSlice) + ") do not match those on base (" + summariseSlicing(bSlice) + ") - disciminator @ " + path + " (" + contextName + ")");
if (!ruleMatches(dSlice.getRules(), bSlice.getRules()))
throw new DefinitionException("Slicing rules on differential (" + summariseSlicing(dSlice) + ") do not match those on base (" + summariseSlicing(bSlice) + ") - rule @ " + path + " (" + contextName + ")");
}
ElementDefinition outcome = updateURLs(url, currentBase.copy());
outcome.setPath(fixedPath(contextPath, outcome.getPath()));
updateFromBase(outcome, currentBase);
if (diffMatches.get(0).hasSlicing() && !isExtension) {
updateFromSlicing(outcome.getSlicing(), diffMatches.get(0).getSlicing());
// if there's no slice, we don't want to update the unsliced description
updateFromDefinition(outcome, diffMatches.get(0), profileName, closed, url);
}
if (diffMatches.get(0).hasSlicing() && !diffMatches.get(0).hasName())
diffpos++;
result.getElement().add(outcome);
// now, we have two lists, base and diff. we're going to work through base, looking for matches in diff.
List<ElementDefinition> baseMatches = getSiblings(base.getElement(), currentBase);
for (ElementDefinition baseItem : baseMatches) {
baseCursor = base.getElement().indexOf(baseItem);
outcome = updateURLs(url, baseItem.copy());
updateFromBase(outcome, currentBase);
outcome.setPath(fixedPath(contextPath, outcome.getPath()));
outcome.setSlicing(null);
if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException("Adding wrong path");
if (diffpos < diffMatches.size() && diffMatches.get(diffpos).getName().equals(outcome.getName())) {
// if there's a diff, we update the outcome with diff
// no? updateFromDefinition(outcome, diffMatches.get(diffpos), profileName, closed, url);
// then process any children
int nbl = findEndOfElement(base, baseCursor);
int ndc = differential.getElement().indexOf(diffMatches.get(diffpos));
int ndl = findEndOfElement(differential, ndc);
// now we process the base scope repeatedly for each instance of the item in the differential list
processPaths(result, base, differential, baseCursor, ndc, nbl, ndl, url, profileName + pathTail(diffMatches, diffpos), contextPath, closed, contextName, resultPathBase, true);
// ok, done with that - now set the cursors for if this is the end
baseCursor = nbl + 1;
diffCursor = ndl + 1;
diffpos++;
} else {
result.getElement().add(outcome);
baseCursor++;
// just copy any children on the base
while (baseCursor < base.getElement().size() && base.getElement().get(baseCursor).getPath().startsWith(path) && !base.getElement().get(baseCursor).getPath().equals(path)) {
outcome = updateURLs(url, currentBase.copy());
outcome.setPath(fixedPath(contextPath, outcome.getPath()));
if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException("Adding wrong path");
result.getElement().add(outcome);
baseCursor++;
}
}
}
// finally, we process any remaining entries in diff, which are new (and which are only allowed if the base wasn't closed
if (closed && diffpos < diffMatches.size())
throw new DefinitionException("The base snapshot marks a slicing as closed, but the differential tries to extend it in " + profileName + " at " + path + " (" + cpath + ")");
while (diffpos < diffMatches.size()) {
ElementDefinition diffItem = diffMatches.get(diffpos);
for (ElementDefinition baseItem : baseMatches) if (baseItem.getName().equals(diffItem.getName()))
throw new DefinitionException("Named items are out of order in the slice");
outcome = updateURLs(url, original.copy());
outcome.setPath(fixedPath(contextPath, outcome.getPath()));
updateFromBase(outcome, currentBase);
outcome.setSlicing(null);
if (!outcome.getPath().startsWith(resultPathBase))
throw new DefinitionException("Adding wrong path");
result.getElement().add(outcome);
updateFromDefinition(outcome, diffItem, profileName, trimDifferential, url);
diffpos++;
}
}
}
}
}
use of org.hl7.fhir.utilities.validation.ValidationMessage.Source in project org.hl7.fhir.core by hapifhir.
the class NarrativeGenerator method generate.
public void generate(ConceptMap cm) {
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
x.addTag("h2").addText(cm.getName() + " (" + cm.getUrl() + ")");
XhtmlNode p = x.addTag("p");
p.addText("Mapping from ");
AddVsRef(((Reference) cm.getSource()).getReference(), p);
p.addText(" to ");
AddVsRef(((Reference) cm.getTarget()).getReference(), p);
p = x.addTag("p");
if (cm.getExperimental())
p.addText(Utilities.capitalize(cm.getStatus().toString()) + " (not intended for production usage). ");
else
p.addText(Utilities.capitalize(cm.getStatus().toString()) + ". ");
p.addText("Published on " + cm.getDateElement().toHumanDisplay() + " by " + cm.getPublisher());
if (!cm.getContact().isEmpty()) {
p.addText(" (");
boolean firsti = true;
for (ConceptMapContactComponent ci : cm.getContact()) {
if (firsti)
firsti = false;
else
p.addText(", ");
if (ci.hasName())
p.addText(ci.getName() + ": ");
boolean first = true;
for (ContactPoint c : ci.getTelecom()) {
if (first)
first = false;
else
p.addText(", ");
addTelecom(p, c);
}
p.addText("; ");
}
p.addText(")");
}
p.addText(". ");
p.addText(cm.getCopyright());
if (!Utilities.noString(cm.getDescription()))
x.addTag("p").addText(cm.getDescription());
x.addTag("br");
if (!cm.getElement().isEmpty()) {
SourceElementComponent cc = cm.getElement().get(0);
String src = cc.getSystem();
boolean comments = false;
boolean ok = cc.getTarget().size() == 1;
Map<String, HashSet<String>> sources = new HashMap<String, HashSet<String>>();
sources.put("code", new HashSet<String>());
Map<String, HashSet<String>> targets = new HashMap<String, HashSet<String>>();
targets.put("code", new HashSet<String>());
if (ok) {
String dst = cc.getTarget().get(0).getSystem();
for (SourceElementComponent ccl : cm.getElement()) {
ok = ok && src.equals(ccl.getSystem()) && ccl.getTarget().size() == 1 && dst.equals(ccl.getTarget().get(0).getSystem()) && ccl.getTarget().get(0).getDependsOn().isEmpty() && ccl.getTarget().get(0).getProduct().isEmpty();
if (ccl.hasSystem())
sources.get("code").add(ccl.getSystem());
for (TargetElementComponent ccm : ccl.getTarget()) {
comments = comments || !Utilities.noString(ccm.getComments());
for (OtherElementComponent d : ccm.getDependsOn()) {
if (!sources.containsKey(d.getElement()))
sources.put(d.getElement(), new HashSet<String>());
sources.get(d.getElement()).add(d.getSystem());
}
if (ccm.hasSystem())
targets.get("code").add(ccm.getSystem());
for (OtherElementComponent d : ccm.getProduct()) {
if (!targets.containsKey(d.getElement()))
targets.put(d.getElement(), new HashSet<String>());
targets.get(d.getElement()).add(d.getSystem());
}
}
}
}
String display;
if (ok) {
// simple
XhtmlNode tbl = x.addTag("table").setAttribute("class", "grid");
XhtmlNode tr = tbl.addTag("tr");
tr.addTag("td").addTag("b").addText("Source Code");
tr.addTag("td").addTag("b").addText("Equivalence");
tr.addTag("td").addTag("b").addText("Destination Code");
if (comments)
tr.addTag("td").addTag("b").addText("Comments");
for (SourceElementComponent ccl : cm.getElement()) {
tr = tbl.addTag("tr");
XhtmlNode td = tr.addTag("td");
td.addText(ccl.getCode());
display = getDisplayForConcept(ccl.getSystem(), ccl.getCode());
if (display != null)
td.addText(" (" + display + ")");
TargetElementComponent ccm = ccl.getTarget().get(0);
tr.addTag("td").addText(!ccm.hasEquivalence() ? "" : ccm.getEquivalence().toCode());
td = tr.addTag("td");
td.addText(ccm.getCode());
display = getDisplayForConcept(ccm.getSystem(), ccm.getCode());
if (display != null)
td.addText(" (" + display + ")");
if (comments)
tr.addTag("td").addText(ccm.getComments());
}
} else {
XhtmlNode tbl = x.addTag("table").setAttribute("class", "grid");
XhtmlNode tr = tbl.addTag("tr");
XhtmlNode td;
tr.addTag("td").setAttribute("colspan", Integer.toString(sources.size())).addTag("b").addText("Source Concept");
tr.addTag("td").addTag("b").addText("Equivalence");
tr.addTag("td").setAttribute("colspan", Integer.toString(targets.size())).addTag("b").addText("Destination Concept");
if (comments)
tr.addTag("td").addTag("b").addText("Comments");
tr = tbl.addTag("tr");
if (sources.get("code").size() == 1)
tr.addTag("td").addTag("b").addText("Code " + sources.get("code").toString() + "");
else
tr.addTag("td").addTag("b").addText("Code");
for (String s : sources.keySet()) {
if (!s.equals("code")) {
if (sources.get(s).size() == 1)
tr.addTag("td").addTag("b").addText(getDescForConcept(s) + " " + sources.get(s).toString());
else
tr.addTag("td").addTag("b").addText(getDescForConcept(s));
}
}
tr.addTag("td");
if (targets.get("code").size() == 1)
tr.addTag("td").addTag("b").addText("Code " + targets.get("code").toString());
else
tr.addTag("td").addTag("b").addText("Code");
for (String s : targets.keySet()) {
if (!s.equals("code")) {
if (targets.get(s).size() == 1)
tr.addTag("td").addTag("b").addText(getDescForConcept(s) + " " + targets.get(s).toString() + "");
else
tr.addTag("td").addTag("b").addText(getDescForConcept(s));
}
}
if (comments)
tr.addTag("td");
for (SourceElementComponent ccl : cm.getElement()) {
tr = tbl.addTag("tr");
td = tr.addTag("td");
if (sources.get("code").size() == 1)
td.addText(ccl.getCode());
else
td.addText(ccl.getSystem() + " / " + ccl.getCode());
display = getDisplayForConcept(ccl.getSystem(), ccl.getCode());
if (display != null)
td.addText(" (" + display + ")");
TargetElementComponent ccm = ccl.getTarget().get(0);
for (String s : sources.keySet()) {
if (!s.equals("code")) {
td = tr.addTag("td");
td.addText(getCode(ccm.getDependsOn(), s, sources.get(s).size() != 1));
display = getDisplay(ccm.getDependsOn(), s);
if (display != null)
td.addText(" (" + display + ")");
}
}
tr.addTag("td").addText(ccm.getEquivalence().toString());
td = tr.addTag("td");
if (targets.get("code").size() == 1)
td.addText(ccm.getCode());
else
td.addText(ccm.getSystem() + " / " + ccm.getCode());
display = getDisplayForConcept(ccm.getSystem(), ccm.getCode());
if (display != null)
td.addText(" (" + display + ")");
for (String s : targets.keySet()) {
if (!s.equals("code")) {
td = tr.addTag("td");
td.addText(getCode(ccm.getProduct(), s, targets.get(s).size() != 1));
display = getDisplay(ccm.getProduct(), s);
if (display != null)
td.addText(" (" + display + ")");
}
}
if (comments)
tr.addTag("td").addText(ccm.getComments());
}
}
}
inject(cm, x, NarrativeStatus.GENERATED);
}
use of org.hl7.fhir.utilities.validation.ValidationMessage.Source in project org.hl7.fhir.core by hapifhir.
the class NarrativeGenerator method generate.
/**
* This generate is optimised for the build tool in that it tracks the source extension.
* But it can be used for any other use.
*
* @param vs
* @param codeSystems
* @throws DefinitionException
* @throws Exception
*/
public void generate(OperationOutcome op) throws DefinitionException {
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
boolean hasSource = false;
boolean success = true;
for (OperationOutcomeIssueComponent i : op.getIssue()) {
success = success && i.getSeverity() == IssueSeverity.INFORMATION;
hasSource = hasSource || ExtensionHelper.hasExtension(i, ToolingExtensions.EXT_ISSUE_SOURCE);
}
if (success)
x.addTag("p").addText("All OK");
if (op.getIssue().size() > 0) {
XhtmlNode tbl = x.addTag("table");
// on the basis that we'll most likely be rendered using the standard fhir css, but it doesn't really matter
tbl.setAttribute("class", "grid");
XhtmlNode tr = tbl.addTag("tr");
tr.addTag("td").addTag("b").addText("Severity");
tr.addTag("td").addTag("b").addText("Location");
tr.addTag("td").addTag("b").addText("Code");
tr.addTag("td").addTag("b").addText("Details");
tr.addTag("td").addTag("b").addText("Diagnostics");
if (hasSource)
tr.addTag("td").addTag("b").addText("Source");
for (OperationOutcomeIssueComponent i : op.getIssue()) {
tr = tbl.addTag("tr");
tr.addTag("td").addText(i.getSeverity().toString());
XhtmlNode td = tr.addTag("td");
boolean d = false;
for (StringType s : i.getLocation()) {
if (d)
td.addText(", ");
else
d = true;
td.addText(s.getValue());
}
tr.addTag("td").addText(i.getCode().getDisplay());
tr.addTag("td").addText(gen(i.getDetails()));
smartAddText(tr.addTag("td"), i.getDiagnostics());
if (hasSource) {
Extension ext = ExtensionHelper.getExtension(i, ToolingExtensions.EXT_ISSUE_SOURCE);
tr.addTag("td").addText(ext == null ? "" : gen(ext));
}
}
}
inject(op, x, hasSource ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
}
use of org.hl7.fhir.utilities.validation.ValidationMessage.Source in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method parseConceptMap.
private void parseConceptMap(StructureMap result, FHIRLexer lexer) throws FHIRLexerException {
lexer.token("conceptmap");
ConceptMap map = new ConceptMap();
String id = lexer.readConstant("map id");
if (!id.startsWith("#"))
lexer.error("Concept Map identifier must start with #");
map.setId(id.substring(1));
result.getContained().add(map);
lexer.token("{");
lexer.skipComments();
// lexer.token("source");
// map.setSource(new UriType(lexer.readConstant("source")));
// lexer.token("target");
// map.setSource(new UriType(lexer.readConstant("target")));
Map<String, String> prefixes = new HashMap<String, String>();
while (lexer.hasToken("prefix")) {
lexer.token("prefix");
String n = lexer.take();
lexer.token("=");
String v = lexer.readConstant("prefix url");
prefixes.put(n, v);
}
while (!lexer.hasToken("}")) {
SourceElementComponent e = map.addElement();
e.setSystem(readPrefix(prefixes, lexer));
lexer.token(":");
e.setCode(lexer.take());
TargetElementComponent tgt = e.addTarget();
tgt.setEquivalence(readEquivalence(lexer));
if (tgt.getEquivalence() != ConceptMapEquivalence.UNMATCHED) {
tgt.setSystem(readPrefix(prefixes, lexer));
lexer.token(":");
tgt.setCode(lexer.take());
}
if (lexer.hasComment())
tgt.setComments(lexer.take().substring(2).trim());
}
lexer.token("}");
}
use of org.hl7.fhir.utilities.validation.ValidationMessage.Source in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method translate.
public Base translate(TransformContext context, StructureMap map, Base source, String conceptMapUrl, String fieldToReturn) throws FHIRException {
Coding src = new Coding();
if (source.isPrimitive()) {
src.setCode(source.primitiveValue());
} else if ("Coding".equals(source.fhirType())) {
Base[] b = source.getProperty("system".hashCode(), "system", true);
if (b.length == 1)
src.setSystem(b[0].primitiveValue());
b = source.getProperty("code".hashCode(), "code", true);
if (b.length == 1)
src.setCode(b[0].primitiveValue());
} else if ("CE".equals(source.fhirType())) {
Base[] b = source.getProperty("codeSystem".hashCode(), "codeSystem", true);
if (b.length == 1)
src.setSystem(b[0].primitiveValue());
b = source.getProperty("code".hashCode(), "code", true);
if (b.length == 1)
src.setCode(b[0].primitiveValue());
} else
throw new FHIRException("Unable to translate source " + source.fhirType());
if (conceptMapUrl.equals("http://hl7.org/fhir/ConceptMap/special-oid2uri")) {
String uri = worker.oid2Uri(src.getCode());
if (uri == null)
uri = "urn:oid:" + src.getCode();
if ("uri".equals(fieldToReturn))
return new UriType(uri);
else
throw new FHIRException("Error in return code");
} else {
ConceptMap cmap = null;
if (conceptMapUrl.startsWith("#")) {
for (Resource r : map.getContained()) {
if (r instanceof ConceptMap && ((ConceptMap) r).getId().equals(conceptMapUrl.substring(1)))
cmap = (ConceptMap) r;
}
} else
cmap = worker.fetchResource(ConceptMap.class, conceptMapUrl);
Coding outcome = null;
boolean done = false;
String message = null;
if (cmap == null) {
if (services == null)
message = "No map found for " + conceptMapUrl;
else {
outcome = services.translate(context.appInfo, src, conceptMapUrl);
done = true;
}
} else {
List<SourceElementComponent> list = new ArrayList<SourceElementComponent>();
for (SourceElementComponent e : cmap.getElement()) {
if (!src.hasSystem() && src.getCode().equals(e.getCode()))
list.add(e);
else if (src.hasSystem() && src.getSystem().equals(e.getSystem()) && src.getCode().equals(e.getCode()))
list.add(e);
}
if (list.size() == 0)
done = true;
else if (list.get(0).getTarget().size() == 0)
message = "Concept map " + conceptMapUrl + " found no translation for " + src.getCode();
else {
for (TargetElementComponent tgt : list.get(0).getTarget()) {
if (tgt.getEquivalence() == ConceptMapEquivalence.EQUAL || tgt.getEquivalence() == ConceptMapEquivalence.EQUIVALENT || tgt.getEquivalence() == ConceptMapEquivalence.WIDER) {
if (done) {
message = "Concept map " + conceptMapUrl + " found multiple matches for " + src.getCode();
done = false;
} else {
done = true;
outcome = new Coding().setCode(tgt.getCode()).setSystem(tgt.getSystem());
}
} else if (tgt.getEquivalence() == ConceptMapEquivalence.UNMATCHED) {
done = true;
}
}
if (!done)
message = "Concept map " + conceptMapUrl + " found no usable translation for " + src.getCode();
}
}
if (!done)
throw new FHIRException(message);
if (outcome == null)
return null;
if ("code".equals(fieldToReturn))
return new CodeType(outcome.getCode());
else
return outcome;
}
}
Aggregations