
001package org.hl7.fhir.r4.elementmodel; 002 003/* 004 Copyright (c) 2011+, HL7, Inc. 005 All rights reserved. 006 007 Redistribution and use in source and binary forms, with or without modification, 008 are permitted provided that the following conditions are met: 009 010 * Redistributions of source code must retain the above copyright notice, this 011 list of conditions and the following disclaimer. 012 * Redistributions in binary form must reproduce the above copyright notice, 013 this list of conditions and the following disclaimer in the documentation 014 and/or other materials provided with the distribution. 015 * Neither the name of HL7 nor the names of its contributors may be used to 016 endorse or promote products derived from this software without specific 017 prior written permission. 018 019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 022 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 024 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 025 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 026 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 POSSIBILITY OF SUCH DAMAGE. 029 030 */ 031 032import java.io.IOException; 033import java.io.InputStream; 034import java.io.OutputStream; 035import java.util.List; 036 037import org.hl7.fhir.exceptions.DefinitionException; 038import org.hl7.fhir.exceptions.FHIRException; 039import org.hl7.fhir.exceptions.FHIRFormatError; 040import org.hl7.fhir.r4.context.IWorkerContext; 041import org.hl7.fhir.r4.formats.FormatUtilities; 042import org.hl7.fhir.r4.formats.IParser.OutputStyle; 043import org.hl7.fhir.r4.model.StructureDefinition; 044import org.hl7.fhir.r4.model.StructureDefinition.TypeDerivationRule; 045import org.hl7.fhir.r4.utils.ToolingExtensions; 046import org.hl7.fhir.utilities.Utilities; 047import org.hl7.fhir.utilities.validation.ValidationMessage; 048import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; 049import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; 050import org.hl7.fhir.utilities.validation.ValidationMessage.Source; 051 052@Deprecated 053public abstract class ParserBase { 054 055 public interface ILinkResolver { 056 String resolveType(String type); 057 058 String resolveProperty(Property property); 059 060 String resolvePage(String string); 061 } 062 063 public enum ValidationPolicy { 064 NONE, QUICK, EVERYTHING 065 } 066 067 public boolean isPrimitive(String code) { 068 return Utilities.existsInList(code, "boolean", "integer", "string", "decimal", "uri", "base64Binary", "instant", 069 "date", "dateTime", "time", "code", "oid", "id", "markdown", "unsignedInt", "positiveInt", "xhtml", "url", 070 "canonical"); 071 072// StructureDefinition sd = context.fetchTypeDefinition(code); 073// return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE; 074 } 075 076 protected IWorkerContext context; 077 protected ValidationPolicy policy; 078 protected List<ValidationMessage> errors; 079 protected ILinkResolver linkResolver; 080 protected boolean showDecorations; 081 082 public ParserBase(IWorkerContext context) { 083 super(); 084 this.context = context; 085 policy = ValidationPolicy.NONE; 086 } 087 088 public void setupValidation(ValidationPolicy policy, List<ValidationMessage> errors) { 089 this.policy = policy; 090 this.errors = errors; 091 } 092 093 public abstract Element parse(InputStream stream) 094 throws IOException, FHIRFormatError, DefinitionException, FHIRException; 095 096 public abstract void compose(Element e, OutputStream destination, OutputStyle style, String base) 097 throws FHIRException, IOException; 098 099 public void logError(int line, int col, String path, IssueType type, String message, IssueSeverity level) 100 throws FHIRFormatError { 101 if (policy == ValidationPolicy.EVERYTHING) { 102 ValidationMessage msg = new ValidationMessage(Source.InstanceValidator, type, line, col, path, message, level); 103 errors.add(msg); 104 } else if (level == IssueSeverity.FATAL || (level == IssueSeverity.ERROR && policy == ValidationPolicy.QUICK)) 105 throw new FHIRFormatError(message + String.format(" at line %d col %d", line, col)); 106 } 107 108 protected StructureDefinition getDefinition(int line, int col, String ns, String name) throws FHIRFormatError { 109 if (ns == null) { 110 logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no namespace)", 111 IssueSeverity.FATAL); 112 return null; 113 } 114 if (name == null) { 115 logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no name)", 116 IssueSeverity.FATAL); 117 return null; 118 } 119 for (StructureDefinition sd : context.allStructures()) { 120 if (sd.getDerivation() == TypeDerivationRule.SPECIALIZATION 121 && !sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/de-")) { 122 if (name.equals(sd.getType()) && (ns == null || ns.equals(FormatUtilities.FHIR_NS)) && !ToolingExtensions 123 .hasExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) 124 return sd; 125 String sns = ToolingExtensions.readStringExtension(sd, 126 "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"); 127 if (name.equals(sd.getType()) && ns != null && ns.equals(sns)) 128 return sd; 129 } 130 } 131 logError(line, col, name, IssueType.STRUCTURE, 132 "This does not appear to be a FHIR resource (unknown namespace/name '" + ns + "::" + name + "')", 133 IssueSeverity.FATAL); 134 return null; 135 } 136 137 protected StructureDefinition getDefinition(int line, int col, String name) throws FHIRFormatError { 138 if (name == null) { 139 logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no name)", 140 IssueSeverity.FATAL); 141 return null; 142 } 143 // first pass: only look at base definitions 144 for (StructureDefinition sd : context.getStructures()) { 145 if (sd.getUrl().equals("http://hl7.org/fhir/StructureDefinition/" + name)) { 146 context.generateSnapshot(sd); 147 return sd; 148 } 149 } 150 for (StructureDefinition sd : context.getStructures()) { 151 if (name.equals(sd.getType()) && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) { 152 context.generateSnapshot(sd); 153 return sd; 154 } 155 } 156 logError(line, col, name, IssueType.STRUCTURE, 157 "This does not appear to be a FHIR resource (unknown name '" + name + "')", IssueSeverity.FATAL); 158 return null; 159 } 160 161 public ILinkResolver getLinkResolver() { 162 return linkResolver; 163 } 164 165 public ParserBase setLinkResolver(ILinkResolver linkResolver) { 166 this.linkResolver = linkResolver; 167 return this; 168 } 169 170 public boolean isShowDecorations() { 171 return showDecorations; 172 } 173 174 public void setShowDecorations(boolean showDecorations) { 175 this.showDecorations = showDecorations; 176 } 177 178}