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;
}
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;
}
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);
}
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;
}
Aggregations