added i18N handling to JsonParser

This commit is contained in:
patrick-werner 2020-03-10 14:32:46 +01:00
parent c8187bc8f2
commit 9443b1c1c3
3 changed files with 50 additions and 24 deletions

View File

@ -45,6 +45,7 @@ import org.hl7.fhir.r5.formats.JsonCreatorCanonical;
import org.hl7.fhir.r5.formats.JsonCreatorGson;
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.utilities.I18nConstants;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.json.JsonTrackingParser;
@ -94,7 +95,7 @@ public class JsonParser extends ParserBase {
try {
obj = JsonTrackingParser.parse(source, map);
} catch (Exception e) {
logError(-1, -1, "(document)", IssueType.INVALID, "Error parsing JSON: "+e.getMessage(), IssueSeverity.FATAL);
logError(-1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL);
return null;
}
assert (map.containsKey(obj));
@ -114,7 +115,7 @@ public class JsonParser extends ParserBase {
public Element parse(JsonObject object) throws FHIRException {
JsonElement rt = object.get("resourceType");
if (rt == null) {
logError(line(object), col(object), "$", IssueType.INVALID, "Unable to find resourceType property", IssueSeverity.FATAL);
logError(line(object), col(object), "$", IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL);
return null;
} else {
String name = rt.getAsString();
@ -144,13 +145,13 @@ public class JsonParser extends ParserBase {
// }
}
if (!found)
logError(line(object), col(object), path, IssueType.INVALID, "Object must have some content", IssueSeverity.ERROR);
logError(line(object), col(object), path, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR);
}
}
private void parseChildren(String path, JsonObject object, Element context, boolean hasResourceType) throws FHIRException {
reapComments(object, context);
List<Property> properties = context.getProperty().getChildProperties(context.getName(), null);
private void parseChildren(String path, JsonObject object, Element element, boolean hasResourceType) throws FHIRException {
reapComments(object, element);
List<Property> properties = element.getProperty().getChildProperties(element.getName(), null);
Set<String> processed = new HashSet<String>();
if (hasResourceType)
processed.add("resourceType");
@ -159,14 +160,14 @@ public class JsonParser extends ParserBase {
// note that we do not trouble ourselves to maintain the wire format order here - we don't even know what it was anyway
// first pass: process the properties
for (Property property : properties) {
parseChildItem(path, object, context, processed, property);
parseChildItem(path, object, element, processed, property);
}
// second pass: check for things not processed
if (policy != ValidationPolicy.NONE) {
for (Entry<String, JsonElement> e : object.entrySet()) {
if (!processed.contains(e.getKey())) {
logError(line(e.getValue()), col(e.getValue()), path, IssueType.STRUCTURE, "Unrecognised property '@"+e.getKey()+"'", IssueSeverity.ERROR);
logError(line(e.getValue()), col(e.getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_, e.getKey()), IssueSeverity.ERROR);
}
}
}
@ -191,7 +192,7 @@ public class JsonParser extends ParserBase {
}
}
private void parseChildComplex(String path, JsonObject object, Element context, Set<String> processed, Property property, String name) throws FHIRException {
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();
JsonElement e = object.get(name);
@ -199,14 +200,14 @@ public class JsonParser extends ParserBase {
JsonArray arr = (JsonArray) e;
int c = 0;
for (JsonElement am : arr) {
parseChildComplexInstance(npath+"["+c+"]", object, context, property, name, am);
parseChildComplexInstance(npath+"["+c+"]", object, element, property, name, am);
c++;
}
} else {
if (property.isList()) {
logError(line(e), col(e), npath, IssueType.INVALID, "This property must be an Array, not "+describeType(e), IssueSeverity.ERROR);
logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describeType(e)), IssueSeverity.ERROR);
}
parseChildComplexInstance(npath, object, context, property, name, e);
parseChildComplexInstance(npath, object, element, property, name, e);
}
}
@ -222,18 +223,18 @@ public class JsonParser extends ParserBase {
return null;
}
private void parseChildComplexInstance(String npath, JsonObject object, Element context, Property property, String name, JsonElement e) throws FHIRException {
private void parseChildComplexInstance(String npath, 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));
checkObject(child, npath);
context.getChildren().add(n);
element.getChildren().add(n);
if (property.isResource())
parseResource(npath, child, n, property);
else
parseChildren(npath, child, n, false);
} else
logError(line(e), col(e), npath, IssueType.INVALID, "This property must be "+(property.isList() ? "an Array" : "an Object")+", not "+describe(e), IssueSeverity.ERROR);
logError(line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE__NOT_, (property.isList() ? "an Array" : "an Object"), describe(e)), IssueSeverity.ERROR);
}
private String describe(JsonElement e) {
@ -274,15 +275,16 @@ public class JsonParser extends ParserBase {
return arr == null ? 0 : arr.size();
}
private void parseChildPrimitiveInstance(Element context, Property property, String name, String npath,
private void parseChildPrimitiveInstance(Element element, Property property, String name, String npath,
JsonElement main, JsonElement fork) throws FHIRException {
if (main != null && !(main instanceof JsonPrimitive))
logError(line(main), col(main), npath, IssueType.INVALID, "This property must be an simple value, not "+describe(main), IssueSeverity.ERROR);
logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(
I18nConstants.THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_, describe(main)), IssueSeverity.ERROR);
else if (fork != null && !(fork instanceof JsonObject))
logError(line(fork), col(fork), npath, IssueType.INVALID, "This property must be an object, not "+describe(fork), IssueSeverity.ERROR);
logError(line(fork), col(fork), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(fork)), IssueSeverity.ERROR);
else {
Element n = new Element(name, property).markLocation(line(main != null ? main : fork), col(main != null ? main : fork));
context.getChildren().add(n);
element.getChildren().add(n);
if (main != null) {
JsonPrimitive p = (JsonPrimitive) main;
if (p.isNumber() && p.getAsNumber() instanceof JsonTrackingParser.PresentedBigDecimal) {
@ -295,19 +297,19 @@ public class JsonParser extends ParserBase {
try {
n.setXhtml(new XhtmlParser().setValidatorMode(policy == ValidationPolicy.EVERYTHING).parse(n.getValue(), null).getDocumentElement());
} catch (Exception e) {
logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing XHTML: "+e.getMessage(), IssueSeverity.ERROR);
logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_XHTML_, e.getMessage()), IssueSeverity.ERROR);
}
}
if (policy == ValidationPolicy.EVERYTHING) {
// now we cross-check the primitive format against the stated type
if (Utilities.existsInList(n.getType(), "boolean")) {
if (!p.isBoolean())
logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing JSON: the primitive value must be a boolean", IssueSeverity.ERROR);
logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_BOOLEAN), IssueSeverity.ERROR);
} else if (Utilities.existsInList(n.getType(), "integer", "unsignedInt", "positiveInt", "decimal")) {
if (!p.isNumber())
logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing JSON: the primitive value must be a number", IssueSeverity.ERROR);
logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_NUMBER), IssueSeverity.ERROR);
} else if (!p.isString())
logError(line(main), col(main), npath, IssueType.INVALID, "Error parsing JSON: the primitive value must be a string", IssueSeverity.ERROR);
logError(line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_STRING), IssueSeverity.ERROR);
}
}
if (fork != null) {
@ -322,7 +324,7 @@ public class JsonParser extends ParserBase {
private void parseResource(String npath, JsonObject res, Element parent, Property elementProperty) throws FHIRException {
JsonElement rt = res.get("resourceType");
if (rt == null) {
logError(line(res), col(res), npath, IssueType.INVALID, "Unable to find resourceType property", IssueSeverity.FATAL);
logError(line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL);
} else {
String name = rt.getAsString();
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, context.getOverrideVersionNs()));

View File

@ -352,5 +352,17 @@ public class I18nConstants {
public final static String THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME = "This_cannot_be_parsed_as_a_FHIR_object_no_name";
public final static String THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAMESPACENAME_ = "This_does_not_appear_to_be_a_FHIR_resource_unknown_namespacename_";
public final static String THIS__CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAMESPACE = "This__cannot_be_parsed_as_a_FHIR_object_no_namespace";
public final static String UNABLE_TO_FIND_RESOURCETYPE_PROPERTY = "Unable_to_find_resourceType_property";
public final static String ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_STRING = "Error_parsing_JSON_the_primitive_value_must_be_a_string";
public final static String ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_NUMBER = "Error_parsing_JSON_the_primitive_value_must_be_a_number";
public final static String ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_BOOLEAN = "Error_parsing_JSON_the_primitive_value_must_be_a_boolean";
public final static String ERROR_PARSING_XHTML_ = "Error_parsing_XHTML_";
public final static String THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_ = "This_property_must_be_an_object_not_";
public final static String THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_ = "This_property_must_be_an_simple_value_not_";
public final static String THIS_PROPERTY_MUST_BE__NOT_ = "This_property_must_be__not_";
public final static String THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_ = "This_property_must_be_an_Array_not_";
public final static String UNRECOGNISED_PROPERTY_ = "Unrecognised_property_";
public final static String OBJECT_MUST_HAVE_SOME_CONTENT = "Object_must_have_some_content";
public final static String ERROR_PARSING_JSON_ = "Error_parsing_JSON_";
}

View File

@ -349,3 +349,15 @@ This_does_not_appear_to_be_a_FHIR_resource_unknown_name_ = This does not appear
This_cannot_be_parsed_as_a_FHIR_object_no_name = This cannot be parsed as a FHIR object (no name)
This_does_not_appear_to_be_a_FHIR_resource_unknown_namespacename_ = This does not appear to be a FHIR resource (unknown namespace/name "{0}::{1}")
This__cannot_be_parsed_as_a_FHIR_object_no_namespace = This "{0}2 cannot be parsed as a FHIR object (no namespace)
Unable_to_find_resourceType_property = Unable to find resourceType property
Error_parsing_JSON_the_primitive_value_must_be_a_string = Error parsing JSON: the primitive value must be a string
Error_parsing_JSON_the_primitive_value_must_be_a_number = Error parsing JSON: the primitive value must be a number
Error_parsing_JSON_the_primitive_value_must_be_a_boolean = Error parsing JSON: the primitive value must be a boolean
Error_parsing_XHTML_ = Error parsing XHTML: {0}
This_property_must_be_an_object_not_ = This property must be an object, not {0}
This_property_must_be_an_simple_value_not_ = This property must be an simple value, not {0}
This_property_must_be__not_ = This property must be {0}, not {1}
This_property_must_be_an_Array_not_ = This property must be an Array, not {0}
Unrecognised_property_ = Unrecognised property ''@{0}''
Object_must_have_some_content = Object must have some content
Error_parsing_JSON_ = Error parsing JSON: {0}