Search in sources :

Example 1 with PSXPathVariables

use of com.helger.schematron.pure.binding.xpath.PSXPathVariables in project ph-schematron by phax.

the class PSXPathBoundSchema method _createBoundPatterns.

/**
 * Pre-compile all patterns incl. their content
 *
 * @param aXPathContext
 * @param aXPathContext
 *        Global XPath object to use. May not be <code>null</code>.
 * @param aBoundDiagnostics
 *        A map from DiagnosticID to its mapped counterpart. May not be
 *        <code>null</code>.
 * @param aGlobalVariables
 *        The global Schematron-let variables. May not be <code>null</code>.
 * @return <code>null</code> if an XPath error is contained
 */
@Nullable
private ICommonsList<PSXPathBoundPattern> _createBoundPatterns(@Nonnull final XPath aXPathContext, @Nonnull final ICommonsMap<String, PSXPathBoundDiagnostic> aBoundDiagnostics, @Nonnull final IPSXPathVariables aGlobalVariables) {
    final ICommonsList<PSXPathBoundPattern> ret = new CommonsArrayList<>();
    boolean bHasAnyError = false;
    // For all relevant patterns
    for (final PSPattern aPattern : getAllRelevantPatterns()) {
        // Handle pattern specific variables
        final PSXPathVariables aPatternVariables = aGlobalVariables.getClone();
        if (aPattern.hasAnyLet()) {
            // map
            for (final Map.Entry<String, String> aEntry : aPattern.getAllLetsAsMap().entrySet()) if (aPatternVariables.add(aEntry).isUnchanged())
                error(aPattern, "Duplicate <let> with name '" + aEntry.getKey() + "' in <pattern>");
        }
        // For all rules of the current pattern
        final ICommonsList<PSXPathBoundRule> aBoundRules = new CommonsArrayList<>();
        for (final PSRule aRule : aPattern.getAllRules()) {
            // Handle rule specific variables
            final PSXPathVariables aRuleVariables = aPatternVariables.getClone();
            if (aRule.hasAnyLet()) {
                // variable map
                for (final Map.Entry<String, String> aEntry : aRule.getAllLetsAsMap().entrySet()) if (aRuleVariables.add(aEntry).isUnchanged())
                    error(aRule, "Duplicate <let> with name '" + aEntry.getKey() + "' in <rule>");
            }
            // For all contained assert and reports within the current rule
            final ICommonsList<PSXPathBoundAssertReport> aBoundAssertReports = new CommonsArrayList<>();
            for (final PSAssertReport aAssertReport : aRule.getAllAssertReports()) {
                final String sTest = aRuleVariables.getAppliedReplacement(aAssertReport.getTest());
                try {
                    final XPathExpression aTestExpr = _compileXPath(aXPathContext, sTest);
                    final ICommonsList<PSXPathBoundElement> aBoundElements = _createBoundElements(aAssertReport, aXPathContext, aRuleVariables);
                    if (aBoundElements == null) {
                        // Error already emitted
                        bHasAnyError = true;
                    } else {
                        final PSXPathBoundAssertReport aBoundAssertReport = new PSXPathBoundAssertReport(aAssertReport, sTest, aTestExpr, aBoundElements, aBoundDiagnostics);
                        aBoundAssertReports.add(aBoundAssertReport);
                    }
                } catch (final Throwable t) {
                    error(aAssertReport, "Failed to compile XPath expression in <" + (aAssertReport.isAssert() ? "assert" : "report") + ">: '" + sTest + "' with the following variables: " + aRuleVariables.getAll(), t);
                    bHasAnyError = true;
                }
            }
            // Evaluate base node set for this rule
            final String sRuleContext = aGlobalVariables.getAppliedReplacement(getValidationContext(aRule.getContext()));
            PSXPathBoundRule aBoundRule = null;
            try {
                final XPathExpression aRuleContext = _compileXPath(aXPathContext, sRuleContext);
                aBoundRule = new PSXPathBoundRule(aRule, sRuleContext, aRuleContext, aBoundAssertReports);
                aBoundRules.add(aBoundRule);
            } catch (final XPathExpressionException ex) {
                error(aRule, "Failed to compile XPath expression in <rule>: '" + sRuleContext + "'", ex.getCause() != null ? ex.getCause() : ex);
                bHasAnyError = true;
            }
        }
        // Create the bound pattern
        final PSXPathBoundPattern aBoundPattern = new PSXPathBoundPattern(aPattern, aBoundRules);
        ret.add(aBoundPattern);
    }
    if (bHasAnyError)
        return null;
    return ret;
}
Also used : XPathExpression(javax.xml.xpath.XPathExpression) PSRule(com.helger.schematron.pure.model.PSRule) XPathExpressionException(javax.xml.xpath.XPathExpressionException) PSXPathVariables(com.helger.schematron.pure.binding.xpath.PSXPathVariables) IPSXPathVariables(com.helger.schematron.pure.binding.xpath.IPSXPathVariables) PSAssertReport(com.helger.schematron.pure.model.PSAssertReport) PSPattern(com.helger.schematron.pure.model.PSPattern) Map(java.util.Map) CommonsHashMap(com.helger.commons.collection.impl.CommonsHashMap) ICommonsMap(com.helger.commons.collection.impl.ICommonsMap) CommonsArrayList(com.helger.commons.collection.impl.CommonsArrayList) Nullable(javax.annotation.Nullable)

Example 2 with PSXPathVariables

use of com.helger.schematron.pure.binding.xpath.PSXPathVariables in project ph-schematron by phax.

the class PSXPathBoundSchema method bind.

@Nonnull
public PSXPathBoundSchema bind() throws SchematronBindException {
    if (s_aLogger.isDebugEnabled())
        s_aLogger.debug("Binding pure Schematron");
    if (m_aBoundPatterns != null)
        throw new IllegalStateException("bind must only be called once!");
    final PSSchema aSchema = getOriginalSchema();
    final PSPhase aPhase = getPhase();
    // Get all "global" variables that are defined in the schema
    final PSXPathVariables aGlobalVariables = new PSXPathVariables();
    if (aSchema.hasAnyLet())
        for (final Map.Entry<String, String> aEntry : aSchema.getAllLetsAsMap().entrySet()) if (aGlobalVariables.add(aEntry).isUnchanged())
            error(aSchema, "Duplicate <let> with name '" + aEntry.getKey() + "' in global <schema>");
    if (aPhase != null) {
        // Get all variables that are defined in the specified phase
        for (final Map.Entry<String, String> aEntry : aPhase.getAllLetsAsMap().entrySet()) if (aGlobalVariables.add(aEntry).isUnchanged())
            error(aSchema, "Duplicate <let> with name '" + aEntry.getKey() + "' in <phase> with name '" + getPhaseID() + "'");
    }
    final XPath aXPathContext = _createXPathContext();
    // Pre-compile all diagnostics first
    final ICommonsMap<String, PSXPathBoundDiagnostic> aBoundDiagnostics = _createBoundDiagnostics(aXPathContext, aGlobalVariables);
    if (aBoundDiagnostics == null)
        throw new SchematronBindException("Failed to precompile the diagnostics of the supplied schema. Check the " + (isDefaultErrorHandler() ? "log output" : "error listener") + " for XPath errors!");
    // Perform the pre-compilation of all XPath expressions in the patterns,
    // rules, asserts/reports and the content elements
    m_aBoundPatterns = _createBoundPatterns(aXPathContext, aBoundDiagnostics, aGlobalVariables);
    if (m_aBoundPatterns == null)
        throw new SchematronBindException("Failed to precompile the supplied schema.");
    return this;
}
Also used : XPath(javax.xml.xpath.XPath) SchematronBindException(com.helger.schematron.pure.binding.SchematronBindException) PSPhase(com.helger.schematron.pure.model.PSPhase) PSXPathVariables(com.helger.schematron.pure.binding.xpath.PSXPathVariables) IPSXPathVariables(com.helger.schematron.pure.binding.xpath.IPSXPathVariables) PSSchema(com.helger.schematron.pure.model.PSSchema) Map(java.util.Map) CommonsHashMap(com.helger.commons.collection.impl.CommonsHashMap) ICommonsMap(com.helger.commons.collection.impl.ICommonsMap) Nonnull(javax.annotation.Nonnull)

Aggregations

CommonsHashMap (com.helger.commons.collection.impl.CommonsHashMap)2 ICommonsMap (com.helger.commons.collection.impl.ICommonsMap)2 IPSXPathVariables (com.helger.schematron.pure.binding.xpath.IPSXPathVariables)2 PSXPathVariables (com.helger.schematron.pure.binding.xpath.PSXPathVariables)2 Map (java.util.Map)2 CommonsArrayList (com.helger.commons.collection.impl.CommonsArrayList)1 SchematronBindException (com.helger.schematron.pure.binding.SchematronBindException)1 PSAssertReport (com.helger.schematron.pure.model.PSAssertReport)1 PSPattern (com.helger.schematron.pure.model.PSPattern)1 PSPhase (com.helger.schematron.pure.model.PSPhase)1 PSRule (com.helger.schematron.pure.model.PSRule)1 PSSchema (com.helger.schematron.pure.model.PSSchema)1 Nonnull (javax.annotation.Nonnull)1 Nullable (javax.annotation.Nullable)1 XPath (javax.xml.xpath.XPath)1 XPathExpression (javax.xml.xpath.XPathExpression)1 XPathExpressionException (javax.xml.xpath.XPathExpressionException)1