Add path and message tracking to element model
This commit is contained in:
parent
91de7ec65b
commit
a2c6dd6af1
|
@ -55,6 +55,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
|||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.utilities.ElementDecoration;
|
||||
import org.hl7.fhir.utilities.ElementDecoration.DecorationType;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
|
@ -102,6 +103,8 @@ public class Element extends Base {
|
|||
private String explicitType; // for xsi:type attribute
|
||||
private Element parentForValidator;
|
||||
private boolean hasParentForValidator;
|
||||
private String path;
|
||||
private List<ValidationMessage> messages;
|
||||
|
||||
public Element(String name) {
|
||||
super();
|
||||
|
@ -706,6 +709,13 @@ public class Element extends Base {
|
|||
return property.isList();
|
||||
}
|
||||
|
||||
public boolean isBaseList() {
|
||||
if (elementProperty != null)
|
||||
return elementProperty.isBaseList();
|
||||
else
|
||||
return property.isBaseList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTypesForProperty(int hash, String name) throws FHIRException {
|
||||
Property p = property.getChildSimpleName(this.name, name);
|
||||
|
@ -938,6 +948,29 @@ public class Element extends Base {
|
|||
property = null;
|
||||
elementProperty = null;
|
||||
xhtml = null;
|
||||
path = null;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public void addMessage(ValidationMessage vm) {
|
||||
if (messages == null) {
|
||||
messages = new ArrayList<>();
|
||||
}
|
||||
messages.add(vm);
|
||||
}
|
||||
|
||||
public boolean hasMessages() {
|
||||
return messages != null && !messages.isEmpty();
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
}
|
|
@ -98,6 +98,7 @@ public class JsonParser extends ParserBase {
|
|||
return null;
|
||||
|
||||
Element result = new Element(type, new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities));
|
||||
result.setPath(type);
|
||||
checkObject(obj, path);
|
||||
result.setType(type);
|
||||
parseChildren(path, obj, result, true);
|
||||
|
@ -123,7 +124,7 @@ public class JsonParser extends ParserBase {
|
|||
return parse(obj);
|
||||
} else {
|
||||
JsonObject obj = JsonTrackingParser.parse(source, null); // (JsonObject) new com.google.gson.JsonParser().parse(source);
|
||||
// assert (map.containsKey(obj));
|
||||
// assert (map.containsKey(obj));
|
||||
return parse(obj);
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +151,7 @@ public class JsonParser extends ParserBase {
|
|||
checkObject(object, path);
|
||||
result.markLocation(line(object), col(object));
|
||||
result.setType(name);
|
||||
result.setPath(result.fhirType());
|
||||
parseChildren(path, object, result, true);
|
||||
result.numberChildren();
|
||||
return result;
|
||||
|
@ -215,6 +217,7 @@ public class JsonParser extends ParserBase {
|
|||
private void parseChildComplex(String path, JsonObject object, Element element, Set<String> processed, Property property, String name) throws FHIRException {
|
||||
processed.add(name);
|
||||
String npath = path+"."+property.getName();
|
||||
String fpath = element.getPath()+"."+property.getName();
|
||||
JsonElement e = object.get(name);
|
||||
if (property.isList() && (e instanceof JsonArray)) {
|
||||
JsonArray arr = (JsonArray) e;
|
||||
|
@ -223,14 +226,14 @@ public class JsonParser extends ParserBase {
|
|||
}
|
||||
int c = 0;
|
||||
for (JsonElement am : arr) {
|
||||
parseChildComplexInstance(npath+"["+c+"]", object, element, property, name, am);
|
||||
parseChildComplexInstance(npath+"["+c+"]", fpath+"["+c+"]", object, element, property, name, am);
|
||||
c++;
|
||||
}
|
||||
} else {
|
||||
if (property.isList()) {
|
||||
logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describeType(e), name, path), IssueSeverity.ERROR);
|
||||
}
|
||||
parseChildComplexInstance(npath, object, element, property, name, e);
|
||||
parseChildComplexInstance(npath, fpath, object, element, property, name, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,10 +249,11 @@ public class JsonParser extends ParserBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void parseChildComplexInstance(String npath, JsonObject object, Element element, Property property, String name, JsonElement e) throws FHIRException {
|
||||
private void parseChildComplexInstance(String npath, String fpath, JsonObject object, Element element, Property property, String name, JsonElement e) throws FHIRException {
|
||||
if (e instanceof JsonObject) {
|
||||
JsonObject child = (JsonObject) e;
|
||||
Element n = new Element(name, property).markLocation(line(child), col(child));
|
||||
n.setPath(fpath);
|
||||
checkObject(child, npath);
|
||||
element.getChildren().add(n);
|
||||
if (property.isResource())
|
||||
|
@ -275,6 +279,7 @@ public class JsonParser extends ParserBase {
|
|||
|
||||
private void parseChildPrimitive(JsonObject object, Element element, Set<String> processed, Property property, String path, String name) throws FHIRException {
|
||||
String npath = path+"."+property.getName();
|
||||
String fpath = element.getPath()+"."+property.getName();
|
||||
processed.add(name);
|
||||
processed.add("_"+name);
|
||||
JsonElement main = object.has(name) ? object.get(name) : null;
|
||||
|
@ -296,11 +301,11 @@ public class JsonParser extends ParserBase {
|
|||
for (int i = 0; i < Math.max(arrC(arr1), arrC(arr2)); i++) {
|
||||
JsonElement m = arrI(arr1, i);
|
||||
JsonElement f = arrI(arr2, i);
|
||||
parseChildPrimitiveInstance(element, property, name, npath, m, f);
|
||||
parseChildPrimitiveInstance(element, property, name, npath, fpath, m, f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parseChildPrimitiveInstance(element, property, name, npath, main, fork);
|
||||
parseChildPrimitiveInstance(element, property, name, npath, fpath, main, fork);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,8 +318,7 @@ public class JsonParser extends ParserBase {
|
|||
return arr == null ? 0 : arr.size();
|
||||
}
|
||||
|
||||
private void parseChildPrimitiveInstance(Element element, Property property, String name, String npath,
|
||||
JsonElement main, JsonElement fork) throws FHIRException {
|
||||
private void parseChildPrimitiveInstance(Element element, Property property, String name, String npath, String fpath, JsonElement main, JsonElement fork) throws FHIRException {
|
||||
if (main != null && !(main instanceof JsonPrimitive))
|
||||
logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(
|
||||
I18nConstants.THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_, describe(main), name, npath), IssueSeverity.ERROR);
|
||||
|
@ -322,6 +326,7 @@ public class JsonParser extends ParserBase {
|
|||
logError(line(fork), col(fork), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(fork), name, npath), IssueSeverity.ERROR);
|
||||
else {
|
||||
Element n = new Element(name, property).markLocation(line(main != null ? main : fork), col(main != null ? main : fork));
|
||||
n.setPath(fpath);
|
||||
element.getChildren().add(n);
|
||||
if (main != null) {
|
||||
JsonPrimitive p = (JsonPrimitive) main;
|
||||
|
|
|
@ -232,6 +232,10 @@ public class Property {
|
|||
return !"1".equals(definition.getMax());
|
||||
}
|
||||
|
||||
public boolean isBaseList() {
|
||||
return !"1".equals(definition.getBase().getMax());
|
||||
}
|
||||
|
||||
public String getScopedPropertyName() {
|
||||
return definition.getBase().getPath();
|
||||
}
|
||||
|
|
|
@ -203,6 +203,7 @@ public class XmlParser extends ParserBase {
|
|||
return null;
|
||||
|
||||
Element result = new Element(element.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
||||
result.setPath(element.getLocalName());
|
||||
checkElement(element, path, result.getProperty());
|
||||
result.markLocation(line(element), col(element));
|
||||
result.setType(element.getLocalName());
|
||||
|
@ -262,6 +263,7 @@ public class XmlParser extends ParserBase {
|
|||
public Element parse(org.w3c.dom.Element base, String type) throws Exception {
|
||||
StructureDefinition sd = getDefinition(0, 0, FormatUtilities.FHIR_NS, type);
|
||||
Element result = new Element(base.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
||||
result.setPath(base.getLocalName());
|
||||
String path = "/"+pathPrefix(base.getNamespaceURI())+base.getLocalName();
|
||||
checkElement(base, path, result.getProperty());
|
||||
result.setType(base.getLocalName());
|
||||
|
@ -283,13 +285,18 @@ public class XmlParser extends ParserBase {
|
|||
if (property != null) {
|
||||
if ("ED.data[x]".equals(property.getDefinition().getId()) || (property.getDefinition()!=null && property.getDefinition().getBase()!=null && "ED.data[x]".equals(property.getDefinition().getBase().getPath()))) {
|
||||
if ("B64".equals(node.getAttribute("representation"))) {
|
||||
element.getChildren().add(new Element("dataBase64Binary", property, "base64Binary", text).markLocation(line, col));
|
||||
Element n = new Element("dataBase64Binary", property, "base64Binary", text).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
} else {
|
||||
element.getChildren().add(new Element("dataString", property, "string", text).markLocation(line, col));
|
||||
Element n = new Element("dataString", property, "string", text).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
}
|
||||
} else {
|
||||
element.getChildren().add(
|
||||
new Element(property.getName(), property, property.getType(), text).markLocation(line, col));
|
||||
Element n = new Element(property.getName(), property, property.getType(), text).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -325,8 +332,11 @@ public class XmlParser extends ParserBase {
|
|||
av = convertForDateFormatFromExternal(ToolingExtensions.readStringExtension(property.getDefinition(), "http://www.healthintersections.com.au/fhir/StructureDefinition/elementdefinition-dateformat"), av);
|
||||
if (property.getName().equals("value") && element.isPrimitive())
|
||||
element.setValue(av);
|
||||
else
|
||||
element.getChildren().add(new Element(property.getName(), property, property.getType(), av).markLocation(line, col));
|
||||
else {
|
||||
Element n = new Element(property.getName(), property, property.getType(), av).markLocation(line, col);
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
}
|
||||
} else {
|
||||
boolean ok = false;
|
||||
if (FormatUtilities.FHIR_NS.equals(node.getNamespaceURI())) {
|
||||
|
@ -342,21 +352,36 @@ public class XmlParser extends ParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
String lastName = null;
|
||||
int repeatCount = 0;
|
||||
Node child = node.getFirstChild();
|
||||
while (child != null) {
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Property property = getElementProp(properties, child.getLocalName(), child.getNamespaceURI());
|
||||
if (property != null) {
|
||||
if (property.getName().equals(lastName)) {
|
||||
repeatCount++;
|
||||
} else {
|
||||
lastName = property.getName();
|
||||
repeatCount = 0;
|
||||
}
|
||||
if (!property.isChoice() && "xhtml".equals(property.getType())) {
|
||||
XhtmlNode xhtml;
|
||||
if (property.getDefinition().hasRepresentation(PropertyRepresentation.CDATEXT))
|
||||
xhtml = new CDANarrativeFormat().convert((org.w3c.dom.Element) child);
|
||||
else
|
||||
xhtml = new XhtmlParser().setValidatorMode(true).parseHtmlNode((org.w3c.dom.Element) child);
|
||||
element.getChildren().add(new Element(property.getName(), property, "xhtml", new XhtmlComposer(XhtmlComposer.XML, false).compose(xhtml)).setXhtml(xhtml).markLocation(line(child), col(child)));
|
||||
Element n = new Element(property.getName(), property, "xhtml", new XhtmlComposer(XhtmlComposer.XML, false).compose(xhtml)).setXhtml(xhtml).markLocation(line(child), col(child));
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
element.getChildren().add(n);
|
||||
} else {
|
||||
String npath = path+"/"+pathPrefix(child.getNamespaceURI())+child.getLocalName();
|
||||
Element n = new Element(child.getLocalName(), property).markLocation(line(child), col(child));
|
||||
if (property.isList()) {
|
||||
n.setPath(element.getPath()+"."+property.getName()+"["+repeatCount+"]");
|
||||
} else {
|
||||
n.setPath(element.getPath()+"."+property.getName());
|
||||
}
|
||||
checkElement((org.w3c.dom.Element) child, npath, n.getProperty());
|
||||
boolean ok = true;
|
||||
if (property.isChoice()) {
|
||||
|
|
Loading…
Reference in New Issue