com.helger.schematron.pure.bound.AbstractPSBoundSchema Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ph-schematron Show documentation
Show all versions of ph-schematron Show documentation
Library for validating XML documents with Schematron
/**
* Copyright (C) 2014-2020 Philip Helger (www.helger.com)
* philip[at]helger[dot]com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.helger.schematron.pure.bound;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.OverridingMethodsMustInvokeSuper;
import org.w3c.dom.Node;
import com.helger.commons.ValueEnforcer;
import com.helger.commons.annotation.OverrideOnDemand;
import com.helger.commons.annotation.ReturnsMutableCopy;
import com.helger.commons.collection.impl.CommonsArrayList;
import com.helger.commons.collection.impl.ICommonsList;
import com.helger.commons.error.SingleError;
import com.helger.commons.location.SimpleLocation;
import com.helger.commons.state.EValidity;
import com.helger.commons.string.ToStringGenerator;
import com.helger.schematron.CSchematron;
import com.helger.schematron.pure.binding.IPSQueryBinding;
import com.helger.schematron.pure.errorhandler.IPSErrorHandler;
import com.helger.schematron.pure.errorhandler.LoggingPSErrorHandler;
import com.helger.schematron.pure.model.IPSElement;
import com.helger.schematron.pure.model.PSActive;
import com.helger.schematron.pure.model.PSPattern;
import com.helger.schematron.pure.model.PSPhase;
import com.helger.schematron.pure.model.PSSchema;
import com.helger.schematron.pure.validation.IPSPartialValidationHandler;
import com.helger.schematron.pure.validation.IPSValidationHandler;
import com.helger.schematron.pure.validation.PSValidationHandlerBreakOnFirstError;
import com.helger.schematron.pure.validation.SchematronValidationException;
import com.helger.schematron.pure.validation.xpath.PSXPathValidationHandlerSVRL;
import com.helger.schematron.svrl.jaxb.SchematronOutputType;
import com.helger.xml.namespace.MapBasedNamespaceContext;
/**
* Base implementation of {@link IPSBoundSchema} with all common elements. It is
* independent of the used query binding.
*
* @author Philip Helger
*/
public abstract class AbstractPSBoundSchema implements IPSBoundSchema
{
private final IPSQueryBinding m_aQueryBinding;
private final PSSchema m_aOrigSchema;
private final IPSErrorHandler m_aErrorHandler;
private final boolean m_bDefaultErrorHandler;
private final MapBasedNamespaceContext m_aNamespaceContext;
private final String m_sPhaseID;
private final PSPhase m_aPhase;
private final ICommonsList m_aPatterns = new CommonsArrayList <> ();
private final IPSValidationHandler m_aCustomValidationHandler;
public AbstractPSBoundSchema (@Nonnull final IPSQueryBinding aQueryBinding,
@Nonnull final PSSchema aOrigSchema,
@Nullable final String sPhaseID,
@Nullable final IPSErrorHandler aCustomErrorHandler,
@Nullable final IPSValidationHandler aCustomValidationHandler)
{
ValueEnforcer.notNull (aQueryBinding, "QueryBinding");
ValueEnforcer.notNull (aOrigSchema, "OrigSchema");
m_aQueryBinding = aQueryBinding;
m_aOrigSchema = aOrigSchema;
m_aErrorHandler = aCustomErrorHandler != null ? aCustomErrorHandler : new LoggingPSErrorHandler ();
m_bDefaultErrorHandler = aCustomErrorHandler == null;
// Determine all namespaces of the schema
m_aNamespaceContext = aOrigSchema.getAsNamespaceContext ();
// Determine the phase ID to use
String sRealPhaseID = sPhaseID != null ? sPhaseID : CSchematron.PHASE_DEFAULT;
if (sRealPhaseID.equals (CSchematron.PHASE_DEFAULT))
{
sRealPhaseID = aOrigSchema.getDefaultPhase ();
if (sRealPhaseID == null)
sRealPhaseID = CSchematron.PHASE_ALL;
}
if (!sRealPhaseID.equals (CSchematron.PHASE_ALL))
{
m_aPhase = aOrigSchema.getPhaseOfID (sRealPhaseID);
if (m_aPhase == null)
warn (aOrigSchema, "Failed to resolve phase with ID '" + sRealPhaseID + "' - default to all patterns");
}
else
m_aPhase = null;
m_sPhaseID = sRealPhaseID;
// Determine all patterns of the phase to use
if (m_aPhase == null)
{
// Apply all patterns
m_aPatterns.addAll (aOrigSchema.getAllPatterns ());
}
else
{
// Scan all active phases
for (final PSActive aActive : m_aPhase.getAllActives ())
{
final String sActivePatternID = aActive.getPattern ();
final PSPattern aPattern = aOrigSchema.getPatternOfID (sActivePatternID);
if (aPattern == null)
{
warn (aOrigSchema,
"Failed to resolve pattern with ID '" + sActivePatternID + "' - ignoring this pattern in phase '" + sRealPhaseID + "'");
}
else
{
// Add the pattern of this phase
m_aPatterns.add (aPattern);
}
}
}
if (m_aPatterns.isEmpty ())
if (m_aPhase == null)
error (aOrigSchema, "No patterns found in schema!");
else
error (aOrigSchema, "No patterns found in schema for phase '" + m_aPhase.getID () + "!");
m_aCustomValidationHandler = aCustomValidationHandler;
}
@Nonnull
public final IPSErrorHandler getErrorHandler ()
{
return m_aErrorHandler;
}
public final boolean isDefaultErrorHandler ()
{
return m_bDefaultErrorHandler;
}
@OverridingMethodsMustInvokeSuper
protected void warn (@Nonnull final IPSElement aSourceElement, @Nonnull final String sMsg)
{
getErrorHandler ().handleError (SingleError.builderWarn ()
.setErrorLocation (new SimpleLocation (m_aOrigSchema.getResource ().getPath ()))
.setErrorFieldName (IPSErrorHandler.getErrorFieldName (aSourceElement))
.setErrorText (sMsg)
.build ());
}
@OverridingMethodsMustInvokeSuper
protected void error (@Nonnull final IPSElement aSourceElement, @Nonnull final String sMsg)
{
error (aSourceElement, sMsg, (Throwable) null);
}
@OverridingMethodsMustInvokeSuper
protected void error (@Nonnull final IPSElement aSourceElement, @Nonnull final String sMsg, @Nullable final Throwable t)
{
getErrorHandler ().handleError (SingleError.builderError ()
.setErrorLocation (new SimpleLocation (m_aOrigSchema.getResource ().getPath ()))
.setErrorFieldName (IPSErrorHandler.getErrorFieldName (aSourceElement))
.setErrorText (sMsg)
.setLinkedException (t)
.build ());
}
@Nonnull
public final IPSQueryBinding getQueryBinding ()
{
return m_aQueryBinding;
}
@Nonnull
public final PSSchema getOriginalSchema ()
{
return m_aOrigSchema;
}
@Nonnull
public final MapBasedNamespaceContext getNamespaceContext ()
{
return m_aNamespaceContext;
}
@Nonnull
public final String getPhaseID ()
{
return m_sPhaseID;
}
@Nullable
public final PSPhase getPhase ()
{
return m_aPhase;
}
public final boolean isPhaseSpecified ()
{
return m_aPhase != null;
}
@Nonnull
@ReturnsMutableCopy
public final ICommonsList getAllRelevantPatterns ()
{
return m_aPatterns.getClone ();
}
@Nullable
public final IPSValidationHandler getCustomValidationHandler ()
{
return m_aCustomValidationHandler;
}
/**
* Override this implementation in a derived class to modify the behavior.
*
* @return An implementation of {@link IPSPartialValidationHandler} to use for
* partial validation. May not be null
.
*/
@Nonnull
@OverrideOnDemand
protected IPSPartialValidationHandler createPartialValidationHandler ()
{
return new PSValidationHandlerBreakOnFirstError ();
}
@Nonnull
public EValidity validatePartially (@Nonnull final Node aNode, @Nullable final String sBaseURI) throws SchematronValidationException
{
final IPSPartialValidationHandler aValidationHandler = createPartialValidationHandler ();
validate (aNode, sBaseURI, aValidationHandler.and (m_aCustomValidationHandler));
return aValidationHandler.getValidity ();
}
@Nonnull
public SchematronOutputType validateComplete (@Nonnull final Node aNode,
@Nullable final String sBaseURI) throws SchematronValidationException
{
final PSXPathValidationHandlerSVRL aValidationHandler = new PSXPathValidationHandlerSVRL (getErrorHandler ());
validate (aNode, sBaseURI, aValidationHandler.and (m_aCustomValidationHandler));
return aValidationHandler.getSVRL ();
}
@Override
public String toString ()
{
return new ToStringGenerator (this).append ("queryBinding", m_aQueryBinding)
.append ("origSchema", m_aOrigSchema)
.appendIfNotNull ("errorHandler", m_aErrorHandler)
.append ("namespaceContext", m_aNamespaceContext)
.appendIfNotNull ("phaseID", m_sPhaseID)
.appendIfNotNull ("phase", m_aPhase)
.append ("patterns", m_aPatterns)
.getToString ();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy