Search in sources :

Example 1 with PSPhase

use of com.helger.schematron.pure.model.PSPhase in project ph-schematron by phax.

the class PSPreprocessor method getForcedPreprocessedSchema.

/**
 * Convert the passed schema to a pre-processed schema independent if it is
 * already minimal or not.
 *
 * @param aSchema
 *        The schema to be made minimal. May not be <code>null</code>
 * @return A minimal copy of the schema. May be <code>null</code> if the
 *         original schema is not yet minimal and {@link #isKeepEmptySchema()}
 *         is set to <code>false</code>.
 * @throws SchematronPreprocessException
 *         In case a preprocessing error occurs
 */
@Nullable
public PSSchema getForcedPreprocessedSchema(@Nonnull final PSSchema aSchema) throws SchematronPreprocessException {
    ValueEnforcer.notNull(aSchema, "Schema");
    final PreprocessorLookup aLookup = new PreprocessorLookup(aSchema);
    final PreprocessorIDPool aIDPool = new PreprocessorIDPool();
    final PSSchema ret = new PSSchema(aSchema.getResource());
    ret.setID(aIDPool.getUniqueID(aSchema.getID()));
    ret.setRich(aSchema.getRichClone());
    ret.setSchemaVersion(aSchema.getSchemaVersion());
    ret.setDefaultPhase(aSchema.getDefaultPhase());
    ret.setQueryBinding(aSchema.getQueryBinding());
    if (m_bKeepTitles && aSchema.hasTitle())
        ret.setTitle(aSchema.getTitle().getClone());
    if (aSchema.hasAnyInclude())
        throw new SchematronPreprocessException("Cannot preprocess <schema> with an <include>");
    for (final PSNS aNS : aSchema.getAllNSs()) ret.addNS(aNS.getClone());
    // start ps are skipped
    for (final PSLet aLet : aSchema.getAllLets()) ret.addLet(aLet.getClone());
    for (final PSPhase aPhase : aSchema.getAllPhases()) ret.addPhase(_getPreprocessedPhase(aPhase, aIDPool));
    for (final PSPattern aPattern : aSchema.getAllPatterns()) {
        final PSPattern aMinifiedPattern = _getPreprocessedPattern(aPattern, aLookup, aIDPool);
        if (aMinifiedPattern != null) {
            // Pattern without rules?
            if (aMinifiedPattern.getRuleCount() > 0 || m_bKeepEmptyPatterns)
                ret.addPattern(aMinifiedPattern);
        }
    }
    // Schema without patterns?
    if (aSchema.getPatternCount() == 0 && !m_bKeepEmptySchema)
        return null;
    // end ps are skipped
    if (m_bKeepDiagnostics && aSchema.hasDiagnostics())
        ret.setDiagnostics(_getPreprocessedDiagnostics(aSchema.getDiagnostics()));
    ret.addForeignElements(aSchema.getAllForeignElements());
    ret.addForeignAttributes(aSchema.getAllForeignAttributes());
    return ret;
}
Also used : PSPhase(com.helger.schematron.pure.model.PSPhase) PSLet(com.helger.schematron.pure.model.PSLet) PSPattern(com.helger.schematron.pure.model.PSPattern) PSSchema(com.helger.schematron.pure.model.PSSchema) PSNS(com.helger.schematron.pure.model.PSNS) Nullable(javax.annotation.Nullable)

Example 2 with PSPhase

use of com.helger.schematron.pure.model.PSPhase in project ph-schematron by phax.

the class PSPreprocessor method _getPreprocessedPhase.

@Nonnull
private static PSPhase _getPreprocessedPhase(@Nonnull final PSPhase aPhase, @Nonnull final PreprocessorIDPool aIDPool) throws SchematronPreprocessException {
    final PSPhase ret = new PSPhase();
    ret.setID(aIDPool.getUniqueID(aPhase.getID()));
    ret.setRich(aPhase.getRichClone());
    if (aPhase.hasAnyInclude())
        throw new SchematronPreprocessException("Cannot preprocess <phase> with an <include>");
    for (final IPSElement aElement : aPhase.getAllContentElements()) {
        if (aElement instanceof PSActive)
            ret.addActive(((PSActive) aElement).getClone());
        else if (aElement instanceof PSLet)
            ret.addLet(((PSLet) aElement).getClone());
    // ps are ignored
    }
    ret.addForeignElements(aPhase.getAllForeignElements());
    ret.addForeignAttributes(aPhase.getAllForeignAttributes());
    return ret;
}
Also used : IPSElement(com.helger.schematron.pure.model.IPSElement) PSPhase(com.helger.schematron.pure.model.PSPhase) PSLet(com.helger.schematron.pure.model.PSLet) PSActive(com.helger.schematron.pure.model.PSActive) Nonnull(javax.annotation.Nonnull)

Example 3 with PSPhase

use of com.helger.schematron.pure.model.PSPhase in project ph-schematron by phax.

the class PSXPathBoundSchema method validate.

public void validate(@Nonnull final Node aNode, @Nullable final String sBaseURI, @Nonnull final IPSValidationHandler aValidationHandler) throws SchematronValidationException {
    ValueEnforcer.notNull(aNode, "Node");
    ValueEnforcer.notNull(aValidationHandler, "ValidationHandler");
    if (m_aBoundPatterns == null)
        throw new IllegalStateException("bind was never called!");
    final PSSchema aSchema = getOriginalSchema();
    final PSPhase aPhase = getPhase();
    // Call the "start" callback method
    aValidationHandler.onStart(aSchema, aPhase, sBaseURI);
    // For all bound patterns
    for (final PSXPathBoundPattern aBoundPattern : m_aBoundPatterns) {
        final PSPattern aPattern = aBoundPattern.getPattern();
        aValidationHandler.onPattern(aPattern);
        // For all bound rules
        rules: for (final PSXPathBoundRule aBoundRule : aBoundPattern.getAllBoundRules()) {
            final PSRule aRule = aBoundRule.getRule();
            // Find all nodes matching the rules
            NodeList aRuleMatchingNodes = null;
            try {
                aRuleMatchingNodes = XPathEvaluationHelper.evaluate(aBoundRule.getBoundRuleExpression(), aNode, XPathConstants.NODESET, sBaseURI);
            } catch (final XPathExpressionException ex) {
                // Handle the cause, because it is usually a wrapper only
                error(aRule, "Failed to evaluate XPath expression to a nodeset: '" + aBoundRule.getRuleExpression() + "'", ex.getCause() != null ? ex.getCause() : ex);
                continue rules;
            }
            final int nRuleMatchingNodes = aRuleMatchingNodes.getLength();
            if (nRuleMatchingNodes > 0) {
                // For all contained assert and report elements
                for (final PSXPathBoundAssertReport aBoundAssertReport : aBoundRule.getAllBoundAssertReports()) {
                    // XSLT does "fired-rule" for each node
                    aValidationHandler.onRule(aRule, aBoundRule.getRuleExpression());
                    final PSAssertReport aAssertReport = aBoundAssertReport.getAssertReport();
                    final boolean bIsAssert = aAssertReport.isAssert();
                    final XPathExpression aTestExpression = aBoundAssertReport.getBoundTestExpression();
                    // Check each node, if it matches the assert/report
                    for (int i = 0; i < nRuleMatchingNodes; ++i) {
                        final Node aRuleMatchingNode = aRuleMatchingNodes.item(i);
                        try {
                            final boolean bTestResult = ((Boolean) XPathEvaluationHelper.evaluate(aTestExpression, aRuleMatchingNode, XPathConstants.BOOLEAN, sBaseURI)).booleanValue();
                            if (bIsAssert) {
                                // It's an assert
                                if (!bTestResult) {
                                    // Assert failed
                                    if (aValidationHandler.onFailedAssert(aAssertReport, aBoundAssertReport.getTestExpression(), aRuleMatchingNode, i, aBoundAssertReport).isBreak()) {
                                        return;
                                    }
                                }
                            } else {
                                // It's a report
                                if (bTestResult) {
                                    // Successful report
                                    if (aValidationHandler.onSuccessfulReport(aAssertReport, aBoundAssertReport.getTestExpression(), aRuleMatchingNode, i, aBoundAssertReport).isBreak()) {
                                        return;
                                    }
                                }
                            }
                        } catch (final XPathExpressionException ex) {
                            error(aRule, "Failed to evaluate XPath expression to a boolean: '" + aBoundAssertReport.getTestExpression() + "'", ex.getCause() != null ? ex.getCause() : ex);
                        }
                    }
                }
                if (false) {
                    // the next pattern
                    break rules;
                }
            }
        }
    }
    // Call the "end" callback method
    aValidationHandler.onEnd(aSchema, aPhase);
}
Also used : XPathExpression(javax.xml.xpath.XPathExpression) PSRule(com.helger.schematron.pure.model.PSRule) XPathExpressionException(javax.xml.xpath.XPathExpressionException) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) PSSchema(com.helger.schematron.pure.model.PSSchema) PSPhase(com.helger.schematron.pure.model.PSPhase) PSAssertReport(com.helger.schematron.pure.model.PSAssertReport) PSPattern(com.helger.schematron.pure.model.PSPattern)

Example 4 with PSPhase

use of com.helger.schematron.pure.model.PSPhase 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

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