package org.hl7.fhir.dstu3.elementmodel; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import org.hl7.fhir.dstu3.context.IWorkerContext; import org.hl7.fhir.dstu3.formats.FormatUtilities; import org.hl7.fhir.dstu3.formats.IParser.OutputStyle; import org.hl7.fhir.dstu3.model.StructureDefinition; import org.hl7.fhir.dstu3.model.StructureDefinition.StructureDefinitionKind; import org.hl7.fhir.dstu3.utils.ToolingExtensions; import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; public abstract class ParserBase { public interface ILinkResolver { String resolveType(String type); String resolveProperty(Property property); String resolvePage(String string); } public enum ValidationPolicy { NONE, QUICK, EVERYTHING } public boolean isPrimitive(String code) { return Utilities.existsInList(code, "boolean", "integer", "string", "decimal", "uri", "base64Binary", "instant", "date", "dateTime", "time", "code", "oid", "id", "markdown", "unsignedInt", "positiveInt", "xhtml"); // StructureDefinition sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+code); // return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE; } protected IWorkerContext context; protected ValidationPolicy policy; protected List<ValidationMessage> errors; protected ILinkResolver linkResolver; public ParserBase(IWorkerContext context) { super(); this.context = context; policy = ValidationPolicy.NONE; } public void setupValidation(ValidationPolicy policy, List<ValidationMessage> errors) { this.policy = policy; this.errors = errors; } public abstract Element parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException; public abstract void compose(Element e, OutputStream destination, OutputStyle style, String base) throws Exception; public void logError(int line, int col, String path, IssueType type, String message, IssueSeverity level) throws FHIRFormatError { if (policy == ValidationPolicy.EVERYTHING) { ValidationMessage msg = new ValidationMessage(Source.InstanceValidator, type, line, col, path, message, level); errors.add(msg); } else if (level == IssueSeverity.FATAL || (level == IssueSeverity.ERROR && policy == ValidationPolicy.QUICK)) throw new FHIRFormatError(message+String.format(" at line %d col %d", line, col)); } protected StructureDefinition getDefinition(int line, int col, String ns, String name) throws FHIRFormatError { if (ns == null) { logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no namespace)", IssueSeverity.FATAL); return null; } if (name == null) { logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no name)", IssueSeverity.FATAL); return null; } for (StructureDefinition sd : context.allStructures()) { if (name.equals(sd.getIdElement().getIdPart())) { if((ns == null || ns.equals(FormatUtilities.FHIR_NS)) && !ToolingExtensions.hasExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) return sd; String sns = ToolingExtensions.readStringExtension(sd, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"); if (ns != null && ns.equals(sns)) return sd; } } logError(line, col, name, IssueType.STRUCTURE, "This does not appear to be a FHIR resource (unknown namespace/name '"+ns+"::"+name+"')", IssueSeverity.FATAL); return null; } protected StructureDefinition getDefinition(int line, int col, String name) throws FHIRFormatError { if (name == null) { logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no name)", IssueSeverity.FATAL); return null; } // first pass: only look at base definitions for (StructureDefinition sd : context.allStructures()) { if (sd.getUrl().equals("http://hl7.org/fhir/StructureDefinition/"+name)) { return sd; } } for (StructureDefinition sd : context.allStructures()) { if (name.equals(sd.getIdElement().getIdPart())) { return sd; } } logError(line, col, name, IssueType.STRUCTURE, "This does not appear to be a FHIR resource (unknown name '"+name+"')", IssueSeverity.FATAL); return null; } public ILinkResolver getLinkResolver() { return linkResolver; } public ParserBase setLinkResolver(ILinkResolver linkResolver) { this.linkResolver = linkResolver; return this; } }