com.sun.msv.verifier.Acceptor Maven / Gradle / Ivy
/*
* Copyright (c) 2001-2013 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.msv.verifier;
import com.sun.msv.grammar.IDContextProvider;
import com.sun.msv.grammar.IDContextProvider2;
import com.sun.msv.util.DatatypeRef;
import com.sun.msv.util.StartTagInfo;
import com.sun.msv.util.StringRef;
/**
* exposes the low-level validation engine interface.
*
*
* represents a pseudo-automaton acceptor.
* this interface is used to validate content models.
*
*
*
*
Perform Validation
*
* To perform validation, call the createAcceptor method of the DocumentDeclaration
* interface to obtain an Acceptor for validating the document element.
*
*
* Acceptor a = vgm.createAcceptor();
*
*
*
* One acceptor is responsible for validating one element. So you also need
* some form of stack. If you are using a "push" interface like SAX, you need
* an explicit stack. If you are validating in "pull" fashion (like DOM), then
* you can use a recursion instead of an explicit stack.
* The following explanation assumes SAX-like interface.
*
*
* Now, get back to the story. Whenever you encounter a start tag, create a new
* acceptor, which validates the children of newly encountered element.
*
*
* stack.push(a);
* a = a.createChildAcceptor( sti, null );
*
*
*
* If this tag name was unexpected, then this method returns null. See javadoc
* for more details.
*
*
* Then, for every attributes, call the {@link #onAttribute} method.
* After that you call the {@link #onEndAttributes} method.
*
*
* for( int i=0; i
*
*
* An error can occur at any method. See the method documentations for details.
*
*
* If you find an end tag, make sure that the acceptor is satisfied. An acceptor
* is said to be unsatisfied when it needs more elements/text to complete the content
* model. For example, if the content model is (A,B,C) and it only sees (A,B), then
* the acceptor is not satisfied because it needs to see C.
*
*
* if(!a.isAcceptState(null))
* ; // error because the acceptor is unsatisfied.
* Acceptor child = a;
* a = stack.pop();
* a.stepForward(child,null);
*
*
*
* Then, call the stepForward method of the parent acceptor and pass
* the child acceptor to it.
*
*
* Finally, whenever you see a text, call the onText method.
* If the text was unexpected or not allowed, then this method returns null.
* See the documentation for details.
*
*
* a.onText("text",context,null,null);
*
*
*
*
* In this way, you can better control the validation process.
*
*
* If you need even finer control of the validation process
* (e.g., you need to know the list of allowed elements/attributes),
* you may want to rely on the regexp
implementation of VGM.
* see {@link com.sun.msv.verifier.regexp.REDocumentDeclaration} for detail.
*
*
*
*
Downcasting
*
*
* It is often useful to downcast the Acceptor interface to appropriate
* derived class. For example, if you are using
* {@link com.sun.msv.verifier.regexp.REDocumentDeclaration}, then you can always
* downcast an Acceptor to
* {@link com.sun.msv.verifier.regexp.ExpressionAcceptor}, which provides
* more predictable behaviors and some useful methods.
*
*
* @see DocumentDeclaration
* @author Kohsuke KAWAGUCHI
*/
public interface Acceptor
{
/**
* creates an Acceptor that will accept
* the content model of the children of this moment.
*
*
*
* Once you create an acceptor, you need to call the
* {@link #onAttribute} method for each present attribute,
* and then you need to call the {@link #onEndAttributes} method.
*
*
* If an error occurs at this method, the bottom line is that the user cannot
* write this element here.
*
* @param refErr
* if this parameter is non-null, the implementation should
* try to detect the reason of error and recover from it.
* and this object should have the error message as its str field.
*
* @param sti
* this parameter provides the information about the start tag to the
* acceptor object. Usually attribute information is ignored, but
* sometimes they are used as hints.
*
* @return null
* If refErr is null, return null if the given start tag is not accepted.
* If refErr is non-null, return null only when the recovery is impossible.
*/
Acceptor createChildAcceptor( StartTagInfo sti, StringRef refErr );
/**
* processes an attribute.
*
*
* For every attribute present in the document, you need to call this method.
*
*
* An error at this method typically indicates that
*
* - this attribute is not allowed to appear here
*
- the attribute name was OK, but the value was incorrect.
*
*
* @param refErr
* In case of an error, this object will receive the localized error
* message. Null is a valid value for this parameter.
* The implementation must provide some kind of message.
*
* @param refType
* If this parameter is non-null, this object will receive the datatype
* assigned to the attribute value.
*
*
* This feature is optional and therefore the implementation is
* not necessarily provide this information.
*
* @return
* false if an error happens and refErr parameter
* was not provided. Otherwise true.
*/
boolean onAttribute2(
String namespaceURI, String localName, String qName, String value,
IDContextProvider2 context, StringRef refErr, DatatypeRef refType );
/**
* @deprecated
*/
boolean onAttribute(
String namespaceURI, String localName, String qName, String value,
IDContextProvider context, StringRef refErr, DatatypeRef refType );
/**
* notifies the end of attributes.
*
*
* This method needs to be called after the {@link #onAttribute}
* method is called for each present attribute.
*
*
* An error at this method typically indicates that some required
* attributes are missing.
*
* @param sti
* This information is used to produce the error message if that is
* necessary.
*
* @param refErr
* In case of an error, this object will receive the localized error
* message. Null is a valid value for this parameter.
* The implementation must provide some kind of message.
*
* @return
* false if an error happens and refErr parameter
* was not provided. Otherwise true.
*/
boolean onEndAttributes( StartTagInfo sti, StringRef refErr );
/**
* processes a string literal.
*
* @param context
* an object that provides context information necessary to validate
* some datatypes.
* @param refErr
* if this parameter is non-null, the implementation should
* try to detect the reason of error and recover from it.
* and this object should have the error message as its str field.
* @param refType
* if this parameter is non-null and the callee supports
* type-assignment, the callee will assign the DataType object
* to this variable.
* Caller must initialize refType.type to null before calling this method.
* If the callee doesn't support type-assignment or type-assignment
* is impossible for this literal (possibly by ambiguous grammar),
* this variable must kept null.
*
* @return false
* if the literal at this position is not allowed.
*/
boolean onText2( String literal, IDContextProvider2 context, StringRef refErr, DatatypeRef refType );
/**
* @deprecated
*/
boolean onText( String literal, IDContextProvider context, StringRef refErr, DatatypeRef refType );
/**
* eats a child element
*
*
* A child acceptor created by the {@link createChildAcceptor} method
* will be ultimately consumed by the parent through this method.
*
*
* It is the caller's responsibility to make sure that child acceptor
* is in the accept state. If it's not, that indicates that some required
* elements are missing (in other words, contents are not allowed to end here).
*
*
* It is the callee's responsibility to recover from error of
* unsatisified child acceptor. That is, even if the caller finds that
* there are missing elements, it is possible to call this method
* as if there was no such error.
*
* @return false
* if an error happens. For example, if the implementation passes
* an acceptor which is NOT a child of this acceptor, then
* the callee can return false.
*/
boolean stepForward( Acceptor child, StringRef errRef );
/**
* checks if this Acceptor is satisifed.
*
*
* Acceptor is said to be satisfied when given sequence of elements/strings
* is accepted by the content model. This method should be called before
* calling the stepForward method to make sure that the children
* is written properly.
*
* @param errRef
* If this value is non-null, implementation can diagnose the error
* and sets the message to the object.
*/
boolean isAcceptState( StringRef errRef );
/**
* gets the "type" object for which this acceptor is working.
*
* This method is used for type assignment. Actual Java type of
* return value depends on the implementation.
*
* @return null
* the callee should return null when it doesn't support
* type-assignment feature, or type-assignment is impossible
* for this acceptor (for example by ambiguous grammar).
*/
Object getOwnerType();
/**
* clones this acceptor.
*
*
* You can keep a "bookmark" of the acceptor by cloning it.
* This is useful when you are trying to perform "partial validation".
*
*
* Cloned acceptor will behave in exactly the same way as the original one.
*/
Acceptor createClone();
/**
* gets how this acceptor handles characters.
*
*
* This method makes it possible to optimize character handling.
* For many elements of data-oriented schemas, characters are completely prohibited.
* For example, In SVG, only handful elements are allowed to have #PCDATA and
* all other elements have element-only content model. Also, for many elements of
* document-oriented schemas, #PCDATA is allowed just about anywhere.
*
*
* In the former case, this method returns {@link #STRING_PROHIBITED}.
* In other words, this declares that any onText(String) method with
* non-whitespace characters will always result in a failure.
* The caller can then exploit this property of the content model and
* can immediately signal an error when it finds characters, or discard any
* whitespace characters without keeping them in memory.
*
*
* In the latter case, this method returns {@link #STRING_IGNORE}.
* This declares that any onText(String) call does not change anything at all.
* The caller can then exploit this property and discard any characeters it found.
*
*
* If non of the above applies, or the implementation is simply not capable of
* providing this information, then this method returns {@link #STRING_STRICT}.
* In this case, the caller has to faithfully call the onText(String) method
* for all characeters it found.
*
*
* Although this method can be called anytime, it is intended to be called
* only once when the acceptor is first created.
*
* @return
* one of the three constant values shown below.
*/
int getStringCareLevel();
/**
* only whitespaces are allowed. Acceptor will reject any string
* if it's not whitespaces.
*
* for example, <elementRule> of RELAX doesn't allow
* characters (except whitespaces) at all.
*/
static final int STRING_PROHIBITED = 0x00;
/**
* character literals are allowed, but Acceptor doesn't care
* its contents and where it is appeared.
*
* The caller doesn't need to call onText for literal.
* This mode is used for mixed contents.
*/
static final int STRING_IGNORE = 0x01;
/**
* attentive handling of characters is required.
*
* Verifier has to keep track of exact contents of string and
* it must call onText for string accordingly.
*/
static final int STRING_STRICT = 0x02;
// TODO: possible 4th class, STRING_SLOPPY,
// which requires stepForward invocation but don't care about its content.
}