Add parent tracking for Validation support of nested bundles

This commit is contained in:
Grahame Grieve 2020-08-31 13:22:42 +10:00
parent 42a7dad39a
commit c7e8ffff09
3 changed files with 81 additions and 7 deletions

View File

@ -100,6 +100,8 @@ public class Element extends Base {
private SpecialElement special;
private XhtmlNode xhtml; // if this is populated, then value will also hold the string representation
private String explicitType; // for xsi:type attribute
private Element parentForValidator;
private boolean hasParentForValidator;
public Element(String name) {
super();
@ -911,5 +913,23 @@ public class Element extends Base {
return false;
}
/**
* this is set by the instance validator. There's no reason to maintain this when working with an element tree, and so it should be ignored outside the validator
*/
public Element getParentForValidator() {
if (!hasParentForValidator) {
throw new Error("Parent not set");
}
return parentForValidator;
}
public void setParentForValidator(Element parentForValidator) {
this.parentForValidator = parentForValidator;
this.hasParentForValidator = true;
}
public boolean hasParentForValidator() {
return hasParentForValidator;
}
}

View File

@ -57,6 +57,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import static org.apache.commons.lang3.StringUtils.isBlank;
@ -1369,4 +1370,30 @@ public class Utilities {
return byteArrays;
}
public static String presentDuration(long duration) {
duration = duration / 1000000;
String res = ""; // ;
long days = TimeUnit.MILLISECONDS.toDays(duration);
long hours = TimeUnit.MILLISECONDS.toHours(duration) -
TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
long millis = TimeUnit.MILLISECONDS.toMillis(duration) -
TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));
if (days > 0)
res = String.format("%dd %02d:%02d:%02d.%04d", days, hours, minutes, seconds, millis);
else if (hours > 0)
res = String.format("%02d:%02d:%02d.%04d", hours, minutes, seconds, millis);
else //
res = String.format("%02d:%02d.%04d", minutes, seconds, millis);
// else
// res = String.format("%02d.%04d", seconds, millis);
return res;
}
}

View File

@ -238,19 +238,26 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
if (c.getAppContext() instanceof Element) {
Element bnd = (Element) c.getAppContext();
Base res = resolveInBundle(url, bnd);
if (res != null) {
return res;
Element element = (Element) c.getAppContext();
while (element != null) {
Base res = resolveInBundle(url, element);
if (res != null) {
return res;
}
element = element.getParentForValidator();
}
}
Base res = resolveInBundle(url, c.getResource());
if (res != null) {
return res;
}
res = resolveInBundle(url, c.getContainer());
if (res != null) {
return res;
Element element = c.getRootResource();
while (element != null) {
res = resolveInBundle(url, element);
if (res != null) {
return res;
}
element = element.getParentForValidator();
}
if (externalHostServices != null) {
@ -279,6 +286,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (item instanceof Resource) {
try {
Element e = new ObjectConverter(context).convert((Resource) item);
setParents(e);
self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e), valerrors, e, e, sd, IdStatus.OPTIONAL, new NodeStack(context, e, validationLanguage));
} catch (IOException e1) {
throw new FHIRException(e1);
@ -682,6 +690,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
resourceTracker.clear();
executionId = UUID.randomUUID().toString();
baseOnly = profiles.isEmpty();
setParents(element);
long t = System.nanoTime();
if (profiles == null || profiles.isEmpty()) {
@ -697,6 +706,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
timeTracker.overall(t);
}
private void checkElementUsage(List<ValidationMessage> errors, Element element, NodeStack stack) {
String elementUsage = element.getUserString("elementSupported");
hint(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), elementUsage == null || elementUsage.equals("Y"), I18nConstants.MUSTSUPPORT_VAL_MUSTSUPPORT, element.getName(), element.getProperty().getStructure().getUrl());
@ -2418,6 +2428,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
throw new FHIRException(e);
}
if (ext != null) {
setParents(ext);
fetchCache.put(ref, ext);
}
}
@ -3156,6 +3167,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return fetchCache.get(ref);
} else {
Element res = fetcher.fetch(appContext, ref);
setParents(res);
fetchCache.put(ref, res);
return res;
}
@ -4904,4 +4916,19 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
public static void setParents(Element element) {
if (element != null && !element.hasParentForValidator()) {
element.setParentForValidator(null);
setParentsInner(element);
}
}
public static void setParentsInner(Element element) {
for (Element child : element.getChildren()) {
child.setParentForValidator(element);
setParentsInner(child);
}
}
}