Search in sources :

Example 11 with FHIRLexerException

use of org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException in project org.hl7.fhir.core by hapifhir.

the class StructureMapUtilities method parseConceptMap.

private void parseConceptMap(StructureMap result, FHIRLexer lexer) throws FHIRLexerException {
    lexer.token("conceptmap");
    ConceptMap map = new ConceptMap();
    String id = lexer.readConstant("map id");
    if (id.startsWith("#")) {
        throw lexer.error("Concept Map identifier must start with #");
    }
    map.setId(id);
    // todo: how to add this to the text format
    map.setStatus(PublicationStatus.DRAFT);
    result.getContained().add(map);
    lexer.token("{");
    // lexer.token("source");
    // map.setSource(new UriType(lexer.readConstant("source")));
    // lexer.token("target");
    // map.setSource(new UriType(lexer.readConstant("target")));
    Map<String, String> prefixes = new HashMap<String, String>();
    while (lexer.hasToken("prefix")) {
        lexer.token("prefix");
        String n = lexer.take();
        lexer.token("=");
        String v = lexer.readConstant("prefix url");
        prefixes.put(n, v);
    }
    while (lexer.hasToken("unmapped")) {
        lexer.token("unmapped");
        lexer.token("for");
        String n = readPrefix(prefixes, lexer);
        ConceptMapGroupComponent g = getGroup(map, n, null);
        lexer.token("=");
        String v = lexer.take();
        if (v.equals("provided")) {
            g.getUnmapped().setMode(ConceptMapGroupUnmappedMode.PROVIDED);
        } else {
            throw lexer.error("Only unmapped mode PROVIDED is supported at this time");
        }
    }
    while (!lexer.hasToken("}")) {
        String srcs = readPrefix(prefixes, lexer);
        lexer.token(":");
        String sc = lexer.getCurrent().startsWith("\"") ? lexer.readConstant("code") : lexer.take();
        ConceptMapEquivalence eq = readEquivalence(lexer);
        String tgts = (eq != ConceptMapEquivalence.UNMATCHED) ? readPrefix(prefixes, lexer) : "";
        ConceptMapGroupComponent g = getGroup(map, srcs, tgts);
        SourceElementComponent e = g.addElement();
        e.setCode(sc);
        if (e.getCode().startsWith("\"")) {
            e.setCode(lexer.processConstant(e.getCode()));
        }
        TargetElementComponent tgt = e.addTarget();
        tgt.setEquivalence(eq);
        if (tgt.getEquivalence() != ConceptMapEquivalence.UNMATCHED) {
            lexer.token(":");
            tgt.setCode(lexer.take());
            if (tgt.getCode().startsWith("\"")) {
                tgt.setCode(lexer.processConstant(tgt.getCode()));
            }
        }
        tgt.setComment(lexer.getFirstComment());
    }
    lexer.token("}");
}
Also used : TargetElementComponent(org.hl7.fhir.r4b.model.ConceptMap.TargetElementComponent) ConceptMapEquivalence(org.hl7.fhir.r4b.model.ConceptMap.ConceptMapEquivalence) ConceptMapGroupComponent(org.hl7.fhir.r4b.model.ConceptMap.ConceptMapGroupComponent) SourceElementComponent(org.hl7.fhir.r4b.model.ConceptMap.SourceElementComponent)

Example 12 with FHIRLexerException

use of org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException in project org.hl7.fhir.core by hapifhir.

the class FHIRPathEngine method processConstantString.

private String processConstantString(String s, FHIRLexer lexer) throws FHIRLexerException {
    StringBuilder b = new StringBuilder();
    int i = 1;
    while (i < s.length() - 1) {
        char ch = s.charAt(i);
        if (ch == '\\') {
            i++;
            switch(s.charAt(i)) {
                case 't':
                    b.append('\t');
                    break;
                case 'r':
                    b.append('\r');
                    break;
                case 'n':
                    b.append('\n');
                    break;
                case 'f':
                    b.append('\f');
                    break;
                case '\'':
                    b.append('\'');
                    break;
                case '"':
                    b.append('"');
                    break;
                case '`':
                    b.append('`');
                    break;
                case '\\':
                    b.append('\\');
                    break;
                case '/':
                    b.append('/');
                    break;
                case 'u':
                    i++;
                    int uc = Integer.parseInt(s.substring(i, i + 4), 16);
                    b.append((char) uc);
                    i = i + 3;
                    break;
                default:
                    throw lexer.error("Unknown character escape \\" + s.charAt(i));
            }
            i++;
        } else {
            b.append(ch);
            i++;
        }
    }
    return b.toString();
}
Also used : CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder)

Example 13 with FHIRLexerException

use of org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException in project org.hl7.fhir.core by hapifhir.

the class FHIRLexer method processFixedName.

public String processFixedName(String s) throws FHIRLexerException {
    StringBuilder b = new StringBuilder();
    int i = 1;
    while (i < s.length() - 1) {
        char ch = s.charAt(i);
        if (ch == '\\') {
            i++;
            switch(s.charAt(i)) {
                case 't':
                    b.append('\t');
                    break;
                case 'r':
                    b.append('\r');
                    break;
                case 'n':
                    b.append('\n');
                    break;
                case 'f':
                    b.append('\f');
                    break;
                case '\'':
                    b.append('\'');
                    break;
                case '"':
                    b.append('"');
                    break;
                case '\\':
                    b.append('\\');
                    break;
                case '/':
                    b.append('/');
                    break;
                case 'u':
                    i++;
                    int uc = Integer.parseInt(s.substring(i, i + 4), 16);
                    b.append((char) uc);
                    i = i + 4;
                    break;
                default:
                    throw new FHIRLexerException("Unknown character escape \\" + s.charAt(i));
            }
        } else {
            b.append(ch);
            i++;
        }
    }
    return b.toString();
}
Also used : CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder)

Example 14 with FHIRLexerException

use of org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException in project org.hl7.fhir.core by hapifhir.

the class FHIRLexer method takeDottedToken.

public String takeDottedToken() throws FHIRLexerException {
    StringBuilder b = new StringBuilder();
    b.append(take());
    while (!done() && getCurrent().equals(".")) {
        b.append(take());
        b.append(take());
    }
    return b.toString();
}
Also used : CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder)

Example 15 with FHIRLexerException

use of org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException in project org.hl7.fhir.core by hapifhir.

the class InstanceValidator method sliceMatches.

/**
 * @param element - the candidate that might be in the slice
 * @param path    - for reporting any errors. the XPath for the element
 * @param slicer  - the definition of how slicing is determined
 * @param ed      - the slice for which to test membership
 * @param errors
 * @param stack
 * @param srcProfile
 * @return
 * @throws DefinitionException
 * @throws DefinitionException
 * @throws IOException
 * @throws FHIRException
 */
private boolean sliceMatches(ValidatorHostContext hostContext, Element element, String path, ElementDefinition slicer, ElementDefinition ed, StructureDefinition profile, List<ValidationMessage> errors, List<ValidationMessage> sliceInfo, NodeStack stack, StructureDefinition srcProfile) throws DefinitionException, FHIRException {
    if (!slicer.getSlicing().hasDiscriminator())
        // cannot validate in this case
        return false;
    ExpressionNode n = (ExpressionNode) ed.getUserData("slice.expression.cache");
    if (n == null) {
        long t = System.nanoTime();
        // GG: this approach is flawed because it treats discriminators individually rather than collectively
        StringBuilder expression = new StringBuilder("true");
        boolean anyFound = false;
        Set<String> discriminators = new HashSet<>();
        for (ElementDefinitionSlicingDiscriminatorComponent s : slicer.getSlicing().getDiscriminator()) {
            String discriminator = s.getPath();
            discriminators.add(discriminator);
            List<ElementDefinition> criteriaElements = getCriteriaForDiscriminator(path, ed, discriminator, profile, s.getType() == DiscriminatorType.PROFILE, srcProfile);
            boolean found = false;
            for (ElementDefinition criteriaElement : criteriaElements) {
                found = true;
                if (s.getType() == DiscriminatorType.TYPE) {
                    String type = null;
                    if (!criteriaElement.getPath().contains("[") && discriminator.contains("[")) {
                        discriminator = discriminator.substring(0, discriminator.indexOf('['));
                        String lastNode = tail(discriminator);
                        type = tail(criteriaElement.getPath()).substring(lastNode.length());
                        type = type.substring(0, 1).toLowerCase() + type.substring(1);
                    } else if (!criteriaElement.hasType() || criteriaElement.getType().size() == 1) {
                        if (discriminator.contains("["))
                            discriminator = discriminator.substring(0, discriminator.indexOf('['));
                        if (criteriaElement.hasType()) {
                            type = criteriaElement.getType().get(0).getWorkingCode();
                        } else if (!criteriaElement.getPath().contains(".")) {
                            type = criteriaElement.getPath();
                        } else {
                            throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
                        }
                    } else if (criteriaElement.getType().size() > 1) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary()));
                    } else
                        throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
                    if (discriminator.isEmpty())
                        expression.append(" and $this is " + type);
                    else
                        expression.append(" and " + discriminator + " is " + type);
                } else if (s.getType() == DiscriminatorType.PROFILE) {
                    if (criteriaElement.getType().size() == 0) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
                    }
                    if (criteriaElement.getType().size() != 1) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_ONLY_ONE_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
                    }
                    List<CanonicalType> list = discriminator.endsWith(".resolve()") || discriminator.equals("resolve()") ? criteriaElement.getType().get(0).getTargetProfile() : criteriaElement.getType().get(0).getProfile();
                    if (list.size() == 0) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE_WITH_A_PROFILE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
                    } else if (list.size() > 1) {
                        CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or ");
                        for (CanonicalType c : list) {
                            b.append(discriminator + ".conformsTo('" + c.getValue() + "')");
                        }
                        expression.append(" and (" + b + ")");
                    } else {
                        expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')");
                    }
                } else if (s.getType() == DiscriminatorType.EXISTS) {
                    if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1)
                        expression.append(" and (" + discriminator + ".exists())");
                    else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0"))
                        expression.append(" and (" + discriminator + ".exists().not())");
                    else
                        throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId()));
                } else if (criteriaElement.hasFixed()) {
                    buildFixedExpression(ed, expression, discriminator, criteriaElement);
                } else if (criteriaElement.hasPattern()) {
                    buildPattternExpression(ed, expression, discriminator, criteriaElement);
                } else if (criteriaElement.hasBinding() && criteriaElement.getBinding().hasStrength() && criteriaElement.getBinding().getStrength().equals(BindingStrength.REQUIRED) && criteriaElement.getBinding().hasValueSet()) {
                    expression.append(" and (" + discriminator + " memberOf '" + criteriaElement.getBinding().getValueSet() + "')");
                } else {
                    found = false;
                }
                if (found)
                    break;
            }
            if (found)
                anyFound = true;
        }
        if (!anyFound) {
            if (slicer.getSlicing().getDiscriminator().size() > 1)
                throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_ANY_DISCRIMINATORS__FOR_SLICE__IN_PROFILE___NONE_OF_THE_DISCRIMINATOR__HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
            else
                throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_DISCRIMINATOR__FOR_SLICE__IN_PROFILE___THE_DISCRIMINATOR__DOES_NOT_HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
        }
        try {
            n = fpe.parse(fixExpr(expression.toString(), null));
        } catch (FHIRLexerException e) {
            if (STACK_TRACE)
                e.printStackTrace();
            throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, expression, profile.getUrl(), path, e.getMessage()));
        }
        timeTracker.fpe(t);
        ed.setUserData("slice.expression.cache", n);
    }
    ValidatorHostContext shc = hostContext.forSlicing();
    boolean pass = evaluateSlicingExpression(shc, element, path, profile, n);
    if (!pass) {
        slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString()), null);
        for (String url : shc.getSliceRecords().keySet()) {
            slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), context.formatMessage(I18nConstants.PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__, url, stack.getLiteralPath(), errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url))), errorSummaryForSlicingAsText(shc.getSliceRecords().get(url)));
        }
    }
    return pass;
}
Also used : CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) FHIRLexerException(org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) CanonicalType(org.hl7.fhir.r5.model.CanonicalType) FHIRException(org.hl7.fhir.exceptions.FHIRException) ElementDefinitionSlicingDiscriminatorComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent) ExpressionNode(org.hl7.fhir.r5.model.ExpressionNode) ValidatorHostContext(org.hl7.fhir.validation.instance.utils.ValidatorHostContext) ArrayList(java.util.ArrayList) List(java.util.List) TypedElementDefinition(org.hl7.fhir.r5.utils.FHIRPathEngine.TypedElementDefinition) ElementDefinition(org.hl7.fhir.r5.model.ElementDefinition) DefinitionException(org.hl7.fhir.exceptions.DefinitionException) HashSet(java.util.HashSet)

Aggregations

CommaSeparatedStringBuilder (org.hl7.fhir.utilities.CommaSeparatedStringBuilder)9 ExpressionNode (org.hl7.fhir.r5.model.ExpressionNode)6 ExpressionNode (org.hl7.fhir.dstu2.model.ExpressionNode)5 ExpressionNode (org.hl7.fhir.r4.model.ExpressionNode)4 ExpressionNode (org.hl7.fhir.r4b.model.ExpressionNode)4 BigDecimal (java.math.BigDecimal)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 ExpressionNode (org.hl7.fhir.dstu2016may.model.ExpressionNode)3 ExpressionNode (org.hl7.fhir.dstu3.model.ExpressionNode)3 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)3 SourceLocation (org.hl7.fhir.utilities.SourceLocation)3 Base (org.hl7.fhir.dstu2.model.Base)2 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)2 FHIRException (org.hl7.fhir.exceptions.FHIRException)2 IOException (java.io.IOException)1 HashSet (java.util.HashSet)1 List (java.util.List)1 NotImplementedException (org.apache.commons.lang3.NotImplementedException)1 TypeRefComponent (org.hl7.fhir.dstu2.model.ElementDefinition.TypeRefComponent)1