package com.thaiopensource.relaxng.match;
import com.thaiopensource.xml.util.Name;
import java.util.Set;
/**
* Represents the state of matching an XML document against a RELAX NG pattern.
* The XML document is considered as a linear sequence of events of different
* kinds. For each kind of event <var>E</var> in the sequence, a call must be made
* to a corresponding method <code>match<var>E</var></code> on the
* <var>Matcher</var> object. The kinds of event are:
* <p/>
* <ul>
* <li>StartDocument</li>
* <li>StartTagOpen</li>
* <li>AttributeName</li>
* <li>AttributeValue</li>
* <li>StartTagClose</li>
* <li>Text</li>
* <li>EndTag</li>
* <li>EndDocument</li>
* </ul>
* <p/>
* <p>The method calls must occur in an order corresponding to a well-formed XML
* document. In a well-formed document the sequence of events matches
* the following grammar:
* <p/>
* <pre>
* document ::= StartDocument <var>element</var> EndDocument
* element ::= <var>startTag</var> <var>child</var>* EndTag
* startTag ::= StartTagOpen <var>attribute</var>* StartTagClose
* attribute ::= AttributeName AttributeValue
* child ::= <var>element</var> | Text
* </pre>
* <p/>
* <p>Text events must be maximal. Two consecutive Text events are not allowed.
* Matching text is special, and is done with <code>matchTextBeforeStartTag</code>
* or <code>matchTextBeforeEndTag</code>, according as the Text event is
* followed by a StartTagOpen or an EndTag event. Callers may optionally choose
* to optimize calls to <code>matchTextBeforeStartTag</code>
* or <code>matchTextBeforeEndTag</code> into calls to <code>matchUntypedText</code>,
* but this is only allowed when <code>isTextTyped</code> returns false.
* <p/>
* <p>Each method <code>match<var>E</var></code> returns false if matching
* the event against the document resulted in an error and true otherwise.
* If it returned false, then the error message can be obtained using
* <code>getErrorMessage</code>. In either case, the state of the
* <code>Matcher</code> changes so the <code>Matcher</code> is prepared
* to match the next event.
* <p/>
* <p>The <code>copy()</code> and <code>equals()</code> methods allow
* applications to perform incremental revalidation.
*/
public interface Matcher {
/**
* Return a copy of the current <code>Matcher</code>.
* Future changes to the state of the copy will not affect this and vice-versa.
*
* @return a <code>Matcher</code> that is a copy of this
*/
Matcher copy();
/**
* Return a copy of this <code>Matcher</code> reset to its starting state.
* @return a new <code>Matcher</code>
*/
Matcher start();
/**
* Test whether obj is an equivalent <code>Matcher</code>.
* @return true if they are obj is known to be equivalent, false otherwise
*/
boolean equals(Object obj);
/**
* Return a hashCode for the Matcher. This is consistent with equals.
* @return a hash code
*/
int hashCode();
/**
* Match a StartDocument event. This can only generate an error if the schema was
* equivalent to <code>notAllowed</code>.
*
* @return false if there was an error, true otherwise
*/
boolean matchStartDocument();
/**
* Match an EndDocument event.
*
* @return false if there was an error, true otherwise
*/
boolean matchEndDocument();
/**
* Match a StartTagOpen event.
* @param name the element name
* @param qName the element qName (may be empty or null if unknown)
* @param context the MatchContext
* @return false if there was an error, true otherwise
*/
boolean matchStartTagOpen(Name name, String qName, MatchContext context);
/**
* Match an AttributeName event.
*
* @param name the attribute name
* @param qName the attribute qName (may be empty or null if unknown)
* @param context the MatchContext
* @return false if there was an error, true otherwise
*/
boolean matchAttributeName(Name name, String qName, MatchContext context);
/**
* Match an AttributeValue event.
* The MatchContext must include all the namespace declarations in the start-tag
* including those that lexically follow the attribute.
*
* @param value the attribute value, normalized in accordance with XML 1.0
* @param name the attribute name (included for use in error messages)
* @param qName the attribute qName (included for use in error messages)
* @param context the MatchContext
* @return false if there was an error, true otherwise
*/
boolean matchAttributeValue(String value, Name name, String qName, MatchContext context);
/**
* Match a StartTagClose event. This corresponds to the <code>></code> character
* that ends the start-tag).
* It may cause an error if there are required attributes that have not been matched.
* The parameters are used to generate error messages.
*
* @param name the element name
* @param qName the element qName (may be null or empty)
* @param context the MatchContext
* @return false if there was an error, true otherwise
*/
boolean matchStartTagClose(Name name, String qName, MatchContext context);
/**
* Match a Text event that occurs immediately before an EndTag event.
* All text between two tags must be collected together: consecutive
* calls to <code>matchTextBeforeEndTag</code>/<code>matchTextBeforeStartTag</code> are not
* allowed unless separated by a call to <code>matchStartTagOpen</code> or <code>matchEndTag</code>.
* Calls to <code>matchTextBeforeEndTag</code> can sometimes be optimized into
* calls to <code>matchUntypedText</code>.
*
* @param string the text to be matched
* @param name the name of the parent element (i.e. the name of the element of the following
* EndTag event)
* @param qName the qName of the parent element
* @param context a match context
* @return false if there was an error, true otherwise
*/
boolean matchTextBeforeEndTag(String string, Name name, String qName, MatchContext context);
/**
* Match a Text event that occurs immediately before a StartTagOpen event.
* All text between two tags must be collected together: consecutive
* calls to <code>matchTextBeforeEndTag</code>/<code>matchTextBeforeStartTag</code> are not
* allowed unless separated by a call to <code>matchStartTagOpen</code> or <code>matchEndTag</code>.
* Calls to <code>matchTextBeforeStartTag</code> can sometimes be optimized into
* calls to <code>matchUntypedText</code>.
*
* @param string the text to be matched
* @param context a match context
* @return false if there was an error, true otherwise
*/
boolean matchTextBeforeStartTag(String string, MatchContext context);
/**
* An optimization of <code>matchTextBeforeStartTag</code>/<code>matchTextBeforeEndTag</code>.
* Unlike these functions, <code>matchUntypedText</code> does not
* need to examine the text.
* If <code>isTextTyped</code> returns false, then in this state
* text that consists of whitespace (' ', '\r', '\n', '\t') may be ignored and text that contains
* non-whitespace characters may be processed using <code>matchUntypedText</code>.
* Furthermore it is not necessary to collect up all the text between tags;
* consecutive calls to <code>matchUntypedText</code> are allowed.
* <code>matchUntypedText</code> must not be used unless <code>isTextTyped</code>
* returns false.
* @param context a match context
* @return false if there was an error, true otherwise
*/
boolean matchUntypedText(MatchContext context);
/**
* Return true if text may be typed in the current state, false otherwise.
* If text may be typed, then a call to <code>matchText</code> must <em>not</em> be optimized
* to <code>matchUntypedText</code>.
*
* @return true if text may be typed, false otherwise
*/
boolean isTextTyped();
/**
* Match an EndTag event.
*
* @param name the element name
* @param qName the elememt qname (may be empty or null if unknown)
* @param context a match context
* @return false if there was an error, true otherwise
*/
boolean matchEndTag(Name name, String qName, MatchContext context);
/**
* Return the current error message.
* The current error message is changed by any <code>match<var>E</var></code> method
* that returns false. Initially, the current error message is null.
*
* @return a string with the current error message, or null if there has not yet
* been an error.
*/
String getErrorMessage();
/**
* Return true if the document is valid so far.
* A document is valid so far if and only if no errors have yet been
* encountered.
*
* @return true if the document is valid so far, false otherwise
*/
boolean isValidSoFar();
/**
* Return a NameClass containing the names of elements whose start-tags are valid
* in the current state. This must be called only in a state in
* which a call to <code>matchStartTagOpen</code> would be allowed.
*
* @return a NameClass contains the names of elements whose start-tags are possible
*/
NameClass possibleStartTagNames();
/**
* Return a NameClass containing the names of attributes that are valid
* in the current state. This must be called only in a state in
* which a call to <code>matchAttributeName</code> would be allowed.
*
* @return a NameClass containing the names of attributes that are possible
*/
NameClass possibleAttributeNames();
/**
* Return a Set containing the names of attributes that are required in the
* current state. This must be called only in a state in
* which a call to <code>matchAttributeName</code> would be allowed. Note
* that in a schema such as attribute foo|bar { text } neither foo nor
* bar are considered required attributes; an attribute name x is required
* only if every matching pattern contains an attribute named x. Similarly,
* this function provides no information about wildcard attribute names.
* @return a non-null Set each member of which is a non-null Name corresponding
* to the name of a required attribute
* @see Name
*/
Set<Name> requiredAttributeNames();
Set<Name> requiredElementNames();
}