From 942d4f15aae71759338a661c008604a2a278da88 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Fri, 14 Jan 2022 16:40:16 -0500 Subject: [PATCH] Avoid unnecessary JsonParser/XmlParser class load --- .../hl7/fhir/r5/elementmodel/JsonParser.java | 62 ++++++------ .../hl7/fhir/r5/elementmodel/XmlParser.java | 7 ++ .../hl7/fhir/r5/formats/FormatUtilities.java | 94 ++++++++++--------- 3 files changed, 92 insertions(+), 71 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java index d4b633e02..3878f0221 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/JsonParser.java @@ -1,33 +1,33 @@ package org.hl7.fhir.r5.elementmodel; -/* - Copyright (c) 2011+, HL7, Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - */ +/* + Copyright (c) 2011+, HL7, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of HL7 nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + */ @@ -70,9 +70,15 @@ import com.google.gson.JsonElement; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; +import org.slf4j.LoggerFactory; public class JsonParser extends ParserBase { + static { + // Helpful for troubleshooting why this class is being loaded + LoggerFactory.getLogger(JsonParser.class).debug("Loading JsonParser class"); + } + private JsonCreator json; private Map map; private boolean allowComments; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java index 892080497..ae699cc78 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java @@ -75,12 +75,19 @@ import org.hl7.fhir.utilities.xhtml.XhtmlParser; import org.hl7.fhir.utilities.xml.IXMLWriter; import org.hl7.fhir.utilities.xml.XMLUtil; import org.hl7.fhir.utilities.xml.XMLWriter; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; public class XmlParser extends ParserBase { + + static { + // Helpful for troubleshooting why this class is being loaded + LoggerFactory.getLogger(XmlParser.class).debug("Loading JsonParser class"); + } + private boolean allowXsiLocation; private String version; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/formats/FormatUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/formats/FormatUtilities.java index 242456397..95a092f05 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/formats/FormatUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/formats/FormatUtilities.java @@ -3,34 +3,34 @@ package org.hl7.fhir.r5.formats; import java.io.FileNotFoundException; import java.io.IOException; -/* - Copyright (c) 2011+, HL7, Inc. - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - */ +/* + Copyright (c) 2011+, HL7, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of HL7 nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + */ @@ -63,6 +63,7 @@ POSSIBILITY OF SUCH DAMAGE. */ +import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.net.URI; @@ -117,24 +118,31 @@ public abstract class FormatUtilities { } public static ParserBase makeParser(FhirFormat format) { - switch (format) { - case XML : return new XmlParser(); - case JSON : return new JsonParser(); - case TURTLE : throw new Error("unsupported Format "+format.toString()); // return new TurtleParser(); - case VBAR : throw new Error("unsupported Format "+format.toString()); // - case TEXT : throw new Error("unsupported Format "+format.toString()); // - } - throw new Error("unsupported Format "+format.toString()); + return makeParser(format.name()); } public static ParserBase makeParser(String format) { - if ("XML".equalsIgnoreCase(format)) return new XmlParser(); - if ("JSON".equalsIgnoreCase(format)) return new JsonParser(); - if ("TURTLE".equalsIgnoreCase(format)) throw new Error("unsupported Format "+format.toString()); // return new TurtleParser(); - if ("JSONLD".equalsIgnoreCase(format)) throw new Error("unsupported Format "+format.toString()); // return new JsonLdParser(); - if ("VBAR".equalsIgnoreCase(format)) throw new Error("unsupported Format "+format.toString()); // - if ("TEXT".equalsIgnoreCase(format)) throw new Error("unsupported Format "+format.toString()); // - throw new Error("unsupported Format "+format); + /* + * Note: In this class we're instantiating the parsers using reflection. This is because the + * XmlParser and JsonParser are huuuuuge classes and classloading them is quite expensive + * in cases where they won't actually ever be instantiated (such as when using the + * validator in HAPI FHIR) + */ + try { + if ("XML".equalsIgnoreCase(format)) + return (ParserBase) Class.forName("org.hl7.fhir.r5.formats.XmlParser").getConstructor().newInstance(); + if ("JSON".equalsIgnoreCase(format)) + return (ParserBase) Class.forName("org.hl7.fhir.r5.formats.JsonParser").getConstructor().newInstance(); + if ("TURTLE".equalsIgnoreCase(format)) + throw new Error("unsupported Format " + format.toString()); // return new TurtleParser(); + if ("JSONLD".equalsIgnoreCase(format)) + throw new Error("unsupported Format " + format.toString()); // return new JsonLdParser(); + if ("VBAR".equalsIgnoreCase(format)) throw new Error("unsupported Format " + format.toString()); // + if ("TEXT".equalsIgnoreCase(format)) throw new Error("unsupported Format " + format.toString()); // + throw new Error("unsupported Format " + format); + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException("Failed to create parser", e); + } } public static FhirFormat determineFormat(byte[] source) throws FHIRException {