From ef6f92a21ee24fb5176aec54f2701a6c6ec0b7c3 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 21 Sep 2023 09:50:08 -0400 Subject: [PATCH 1/5] WIP return validation fragments --- .../r5/elementmodel/ValidatedFragment.java | 5 ++++- .../hl7/fhir/validation/ValidationEngine.java | 13 +++++++----- .../cli/services/ValidationService.java | 21 +++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java index 63a78970f..42f6a7d24 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java @@ -50,5 +50,8 @@ public class ValidatedFragment { public String getFilename() { return name+"."+extension; } - + + public String getExtension() { + return extension; + } } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index 5d9da1fac..d1484a4b9 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -32,12 +32,8 @@ import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.context.IWorkerContextManager; import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.context.SystemOutLoggingService; -import org.hl7.fhir.r5.elementmodel.Element; -import org.hl7.fhir.r5.elementmodel.Manager; +import org.hl7.fhir.r5.elementmodel.*; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; -import org.hl7.fhir.r5.elementmodel.ObjectConverter; -import org.hl7.fhir.r5.elementmodel.ParserBase; -import org.hl7.fhir.r5.elementmodel.SHCParser; import org.hl7.fhir.r5.formats.FormatUtilities; import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.formats.JsonParser; @@ -635,6 +631,13 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP return results.getEntryFirstRep().getResource(); } + + public List validateAsFragments(byte[] source, FhirFormat cntType, List profiles, List messages) throws FHIRException, IOException, EOperationOutcome { + InstanceValidator validator = getValidator(cntType); + validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles)); + return validator.validatedContent; + } + public OperationOutcome validate(byte[] source, FhirFormat cntType, List profiles, List messages) throws FHIRException, IOException, EOperationOutcome { InstanceValidator validator = getValidator(cntType); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index f7ef45a47..eda673aa1 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -29,6 +29,7 @@ import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.LanguageUtils; import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; +import org.hl7.fhir.r5.elementmodel.ValidatedFragment; import org.hl7.fhir.r5.formats.IParser; import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.model.Bundle; @@ -116,11 +117,31 @@ public class ValidationService { for (FileInfo fp : request.getFilesToValidate()) { List messages = new ArrayList<>(); + + List validatedFragments = validator.validateAsFragments(fp.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fp.getFileType()), + request.getCliContext().getProfiles(), messages); + + // TODO this chunk does not work for multi-file validation, as the fileName is overwritten + for (ValidatedFragment validatedFragment : validatedFragments) { + ValidationOutcome outcome = new ValidationOutcome(); + FileInfo fileInfo = new FileInfo( + validatedFragment.getFilename(), + new String(validatedFragment.getContent()), + validatedFragment.getExtension()); + outcome.setMessages(validatedFragment.getErrors()); + outcome.setFileInfo(fileInfo); + response.addOutcome(outcome); + } + + //TODO the code below works correctly for multi-file validation. + /* validator.validate(fp.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fp.getFileType()), request.getCliContext().getProfiles(), messages); + ValidationOutcome outcome = new ValidationOutcome().setFileInfo(fp); messages.forEach(outcome::addMessage); response.addOutcome(outcome); + */ } System.out.println(" Max Memory: "+Runtime.getRuntime().maxMemory()); return response; From ba8a4797e55ea806301ea9d959aa84167e8b5cc5 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 21 Sep 2023 13:15:42 -0400 Subject: [PATCH 2/5] If fileType is null, use ResourceChecker --- .../cli/services/ValidationService.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index eda673aa1..be7cc97e7 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -62,10 +62,7 @@ import org.hl7.fhir.utilities.i18n.XLIFFProducer; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.validation.ValidationMessage; -import org.hl7.fhir.validation.IgLoader; -import org.hl7.fhir.validation.ValidationEngine; -import org.hl7.fhir.validation.ValidationRecord; -import org.hl7.fhir.validation.ValidatorUtils; +import org.hl7.fhir.validation.*; import org.hl7.fhir.validation.ValidatorUtils.SourceFile; import org.hl7.fhir.validation.cli.model.CliContext; import org.hl7.fhir.validation.cli.model.FileInfo; @@ -115,10 +112,19 @@ public class ValidationService { ValidationResponse response = new ValidationResponse().setSessionId(sessionId); - for (FileInfo fp : request.getFilesToValidate()) { + for (FileInfo fileToValidate : request.getFilesToValidate()) { + if (fileToValidate.getFileType() == null) { + Manager.FhirFormat format = ResourceChecker.checkIsResource(validator.getContext(), + false, + fileToValidate.getFileContent().getBytes(), + fileToValidate.getFileName(), + false); + fileToValidate.setFileType(format.getExtension()); + } + List messages = new ArrayList<>(); - List validatedFragments = validator.validateAsFragments(fp.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fp.getFileType()), + List validatedFragments = validator.validateAsFragments(fileToValidate.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fileToValidate.getFileType()), request.getCliContext().getProfiles(), messages); // TODO this chunk does not work for multi-file validation, as the fileName is overwritten From c79fa084731df57d0631ee1b2ecfb13ed574dc96 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 21 Sep 2023 13:59:41 -0400 Subject: [PATCH 3/5] Refactor "focus" ValidatedFragment usage --- .../hl7/fhir/r5/elementmodel/FmlParser.java | 6 +- .../hl7/fhir/r5/elementmodel/JsonParser.java | 8 +-- .../fhir/r5/elementmodel/TurtleParser.java | 66 +++++++++---------- .../r5/elementmodel/ValidatedFragment.java | 2 + .../r5/elementmodel/VerticalBarParser.java | 58 ++++++++-------- .../hl7/fhir/r5/elementmodel/XmlParser.java | 12 ++-- 6 files changed, 77 insertions(+), 75 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java index 3c0cbfa9b..b4f332982 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java @@ -50,9 +50,9 @@ public class FmlParser extends ParserBase { ByteArrayInputStream stream = new ByteArrayInputStream(content); String text = TextFile.streamToString(stream); List result = new ArrayList<>(); - ValidatedFragment ctxt = new ValidatedFragment("focus", "fml", content); - ctxt.setElement(parse(ctxt.getErrors(), text)); - result.add(ctxt); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "fml", content); + focusFragment.setElement(parse(focusFragment.getErrors(), text)); + result.add(focusFragment); return result; } 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 49e1900a7..c71fd4d3c 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 @@ -122,7 +122,7 @@ public class JsonParser extends ParserBase { public List parse(InputStream inStream) throws IOException, FHIRException { // long start = System.currentTimeMillis(); byte[] content = TextFile.streamToBytes(inStream); - ValidatedFragment ctxt = new ValidatedFragment("focus", "json", content); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "json", content); ByteArrayInputStream stream = new ByteArrayInputStream(content); @@ -134,17 +134,17 @@ public class JsonParser extends ParserBase { try { obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true); } catch (Exception e) { - logError(ctxt.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1,context.formatMessage(I18nConstants.DOCUMENT), IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL); + logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1,context.formatMessage(I18nConstants.DOCUMENT), IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL); } } else { obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true); } if (obj != null) { - ctxt.setElement(parse(ctxt.getErrors(), obj)); + focusFragment.setElement(parse(focusFragment.getErrors(), obj)); } List res = new ArrayList<>(); - res.add(ctxt); + res.add(focusFragment); // long t =System.currentTimeMillis()-start; // System.out.println("json parser: "+(t)+"ms, "+(content.length/1024)+"kb "+(t == 0 ? "" : " @ "+(content.length / t)+"kb/s")); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java index 54c7a4f19..da39b2790 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java @@ -2,34 +2,34 @@ package org.hl7.fhir.r5.elementmodel; import java.io.ByteArrayInputStream; -/* - 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. + + */ @@ -82,7 +82,7 @@ public class TurtleParser extends ParserBase { @Override public List parse(InputStream inStream) throws IOException, FHIRException { byte[] content = TextFile.streamToBytes(inStream); - ValidatedFragment ctxt = new ValidatedFragment("focus", "ttl", content); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "ttl", content); ByteArrayInputStream stream = new ByteArrayInputStream(content); Turtle src = new Turtle(); @@ -90,16 +90,16 @@ public class TurtleParser extends ParserBase { try { src.parse(TextFile.streamToString(stream)); } catch (Exception e) { - logError(ctxt.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_TURTLE_, e.getMessage()), IssueSeverity.FATAL); + logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_TURTLE_, e.getMessage()), IssueSeverity.FATAL); return null; } - ctxt.setElement(parse(ctxt.getErrors(), src)); + focusFragment.setElement(parse(focusFragment.getErrors(), src)); } else { src.parse(TextFile.streamToString(stream)); - ctxt.setElement(parse(ctxt.getErrors(), src)); + focusFragment.setElement(parse(focusFragment.getErrors(), src)); } List res = new ArrayList<>(); - res.add(ctxt); + res.add(focusFragment); return res; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java index 42f6a7d24..243d426f4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java @@ -10,6 +10,8 @@ public class ValidatedFragment { private String extension; private Element element; private byte[] content; + + public final static String FOCUS_NAME = "focus"; private List errors = new ArrayList<>(); public ValidatedFragment(String name, String extension, Element element, byte[] content) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.java index 53e96eea7..d73c1b869 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.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. + + */ @@ -465,7 +465,7 @@ public class VerticalBarParser extends ParserBase { while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size())) readSegment(message, reader); List res = new ArrayList<>(); - res.add(new ValidatedFragment("focus", "hl7", message, content)); + res.add(new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "hl7", message, content)); return res; } 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 415cec75d..2759fcc13 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 @@ -114,7 +114,7 @@ public class XmlParser extends ParserBase { public List parse(InputStream inStream) throws FHIRFormatError, DefinitionException, FHIRException, IOException { byte[] content = TextFile.streamToBytes(inStream); - ValidatedFragment context = new ValidatedFragment("focus", "xml", content); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "xml", content); ByteArrayInputStream stream = new ByteArrayInputStream(content); Document doc = null; @@ -134,7 +134,7 @@ public class XmlParser extends ParserBase { // if we can, we'll inspect the header/encoding ourselves stream.mark(1024); - version = checkHeader(context.getErrors(), stream); + version = checkHeader(focusFragment.getErrors(), stream); stream.reset(); // use a slower parser that keeps location data @@ -168,17 +168,17 @@ public class XmlParser extends ParserBase { if (e.getMessage().contains("lineNumber:") && e.getMessage().contains("columnNumber:")) { int line = Utilities.parseInt(extractVal(e.getMessage(), "lineNumber"), 0); int col = Utilities.parseInt(extractVal(e.getMessage(), "columnNumber"), 0); - logError(context.getErrors(), ValidationMessage.NO_RULE_DATE, line, col, "(xml)", IssueType.INVALID, e.getMessage().substring(e.getMessage().lastIndexOf(";")+1).trim(), IssueSeverity.FATAL); + logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, line, col, "(xml)", IssueType.INVALID, e.getMessage().substring(e.getMessage().lastIndexOf(";")+1).trim(), IssueSeverity.FATAL); } else { - logError(context.getErrors(), ValidationMessage.NO_RULE_DATE, 0, 0, "(xml)", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL); + logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, 0, 0, "(xml)", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL); } doc = null; } if (doc != null) { - context.setElement(parse(context.getErrors(), doc)); + focusFragment.setElement(parse(focusFragment.getErrors(), doc)); } List res = new ArrayList<>(); - res.add(context); + res.add(focusFragment); return res; } From d8509440573b73081dd5b84392c59dd3bec595c6 Mon Sep 17 00:00:00 2001 From: dotasek Date: Tue, 26 Sep 2023 16:46:22 -0400 Subject: [PATCH 4/5] WIP track derived content for ValidatedFragment --- .../hl7/fhir/r5/elementmodel/FmlParser.java | 2 +- .../hl7/fhir/r5/elementmodel/JsonParser.java | 2 +- .../hl7/fhir/r5/elementmodel/SHCParser.java | 4 +- .../hl7/fhir/r5/elementmodel/SHLParser.java | 2 +- .../fhir/r5/elementmodel/TurtleParser.java | 2 +- .../r5/elementmodel/ValidatedFragment.java | 47 ++++++++----------- .../r5/elementmodel/VerticalBarParser.java | 2 +- .../hl7/fhir/r5/elementmodel/XmlParser.java | 2 +- .../cli/services/ValidationService.java | 29 ++++++------ 9 files changed, 43 insertions(+), 49 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java index b4f332982..7f04c3286 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/FmlParser.java @@ -50,7 +50,7 @@ public class FmlParser extends ParserBase { ByteArrayInputStream stream = new ByteArrayInputStream(content); String text = TextFile.streamToString(stream); List result = new ArrayList<>(); - ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "fml", content); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "fml", content, false); focusFragment.setElement(parse(focusFragment.getErrors(), text)); result.add(focusFragment); return result; 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 c71fd4d3c..14efb65de 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 @@ -122,7 +122,7 @@ public class JsonParser extends ParserBase { public List parse(InputStream inStream) throws IOException, FHIRException { // long start = System.currentTimeMillis(); byte[] content = TextFile.streamToBytes(inStream); - ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "json", content); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "json", content, false); ByteArrayInputStream stream = new ByteArrayInputStream(content); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java index 9e4737e01..b837cc1cd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java @@ -83,7 +83,7 @@ public class SHCParser extends ParserBase { byte[] content = TextFile.streamToBytes(inStream); ByteArrayInputStream stream = new ByteArrayInputStream(content); List res = new ArrayList<>(); - ValidatedFragment shc = new ValidatedFragment("shc", "json", content); + ValidatedFragment shc = new ValidatedFragment("shc", "json", content, false); res.add(shc); String src = TextFile.streamToString(stream).trim(); @@ -165,7 +165,7 @@ public class SHCParser extends ParserBase { return res; } // ok. all checks passed, we can now validate the bundle - ValidatedFragment bnd = new ValidatedFragment(path, "json", org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(cs.getJsonObject("fhirBundle"))); + ValidatedFragment bnd = new ValidatedFragment(path, "json", org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(cs.getJsonObject("fhirBundle")), true); res.add(bnd); bnd.setElement(jsonParser.parse(bnd.getErrors(), cs.getJsonObject("fhirBundle"))); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java index 5682b4aa0..2c4f64b1d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHLParser.java @@ -280,7 +280,7 @@ public class SHLParser extends ParserBase { } private ValidatedFragment addNamedElement(List res, String name, String type, byte[] content) { - ValidatedFragment result = new ValidatedFragment(name, type, content); + ValidatedFragment result = new ValidatedFragment(name, type, content, true); res.add(result); return result; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java index da39b2790..66b55eb27 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/TurtleParser.java @@ -82,7 +82,7 @@ public class TurtleParser extends ParserBase { @Override public List parse(InputStream inStream) throws IOException, FHIRException { byte[] content = TextFile.streamToBytes(inStream); - ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "ttl", content); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "ttl", content, false); ByteArrayInputStream stream = new ByteArrayInputStream(content); Turtle src = new Turtle(); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java index 243d426f4..8c7d965bd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ValidatedFragment.java @@ -3,57 +3,50 @@ package org.hl7.fhir.r5.elementmodel; import java.util.ArrayList; import java.util.List; +import lombok.Getter; +import lombok.Setter; import org.hl7.fhir.utilities.validation.ValidationMessage; public class ValidatedFragment { + + @Getter private String name; + + @Getter private String extension; + + @Getter @Setter private Element element; + + @Getter @Setter private byte[] content; + @Getter + private final boolean isDerivedContent; public final static String FOCUS_NAME = "focus"; + + @Getter private List errors = new ArrayList<>(); - - public ValidatedFragment(String name, String extension, Element element, byte[] content) { + + + public ValidatedFragment(String name, String extension, Element element, byte[] content, boolean isDerivedContent) { super(); this.name = name; this.element = element; this.content = content; this.extension = extension; + this.isDerivedContent = isDerivedContent; } - public ValidatedFragment(String name, String extension, byte[] content) { + public ValidatedFragment(String name, String extension, byte[] content, boolean isDerivedContent) { super(); this.name = name; this.content = content; this.extension = extension; + this.isDerivedContent = isDerivedContent; } - - public String getName() { - return name; - } - - public Element getElement() { - return element; - } - - public byte[] getContent() { - return content; - } - - public List getErrors() { - return errors; - } - - public void setElement(Element element) { - this.element = element; - } - public String getFilename() { return name+"."+extension; } - public String getExtension() { - return extension; - } } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.java index d73c1b869..cca033fef 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/VerticalBarParser.java @@ -465,7 +465,7 @@ public class VerticalBarParser extends ParserBase { while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size())) readSegment(message, reader); List res = new ArrayList<>(); - res.add(new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "hl7", message, content)); + res.add(new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "hl7", message, content, false)); return res; } 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 2759fcc13..55b3c4d8d 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 @@ -114,7 +114,7 @@ public class XmlParser extends ParserBase { public List parse(InputStream inStream) throws FHIRFormatError, DefinitionException, FHIRException, IOException { byte[] content = TextFile.streamToBytes(inStream); - ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "xml", content); + ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "xml", content, false); ByteArrayInputStream stream = new ByteArrayInputStream(content); Document doc = null; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index be7cc97e7..4ecdafef5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -127,27 +127,28 @@ public class ValidationService { List validatedFragments = validator.validateAsFragments(fileToValidate.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fileToValidate.getFileType()), request.getCliContext().getProfiles(), messages); - // TODO this chunk does not work for multi-file validation, as the fileName is overwritten - for (ValidatedFragment validatedFragment : validatedFragments) { + if (validatedFragments.size() == 1 && !validatedFragments.get(0).isDerivedContent()) { + ValidatedFragment validatedFragment = validatedFragments.get(0); ValidationOutcome outcome = new ValidationOutcome(); - FileInfo fileInfo = new FileInfo( - validatedFragment.getFilename(), + FileInfo fileInfo = new FileInfo( + fileToValidate.getFileName(), new String(validatedFragment.getContent()), validatedFragment.getExtension()); outcome.setMessages(validatedFragment.getErrors()); outcome.setFileInfo(fileInfo); response.addOutcome(outcome); + } else { + for (ValidatedFragment validatedFragment : validatedFragments) { + ValidationOutcome outcome = new ValidationOutcome(); + FileInfo fileInfo = new FileInfo( + validatedFragment.getFilename(), + new String(validatedFragment.getContent()), + validatedFragment.getExtension()); + outcome.setMessages(validatedFragment.getErrors()); + outcome.setFileInfo(fileInfo); + response.addOutcome(outcome); + } } - - //TODO the code below works correctly for multi-file validation. - /* - validator.validate(fp.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fp.getFileType()), - request.getCliContext().getProfiles(), messages); - - ValidationOutcome outcome = new ValidationOutcome().setFileInfo(fp); - messages.forEach(outcome::addMessage); - response.addOutcome(outcome); - */ } System.out.println(" Max Memory: "+Runtime.getRuntime().maxMemory()); return response; From c2071379f48fba204b825a38869e87c1b35d0c9e Mon Sep 17 00:00:00 2001 From: dotasek Date: Fri, 29 Sep 2023 11:00:01 -0400 Subject: [PATCH 5/5] Use txt extension for shc fragment --- .../src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java index 92e67aab0..1e3d56895 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java @@ -83,7 +83,7 @@ public class SHCParser extends ParserBase { byte[] content = TextFile.streamToBytes(inStream); ByteArrayInputStream stream = new ByteArrayInputStream(content); List res = new ArrayList<>(); - ValidatedFragment shc = new ValidatedFragment("shc", "json", content, false); + ValidatedFragment shc = new ValidatedFragment("shc", "txt", content, false); res.add(shc); String src = TextFile.streamToString(stream).trim();