/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* A content model state. This is basically a list of pointers to
* the BNF expression representing the model (the ContentModel).
* Each element in a DTD has a content model which describes the
* elements that may occur inside, and the order in which they can
* occur.
* <p>
* Each time a token is reduced a new state is created.
* <p>
* See Annex H on page 556 of the SGML handbook for more information.
*
* @see Parser
* @see DTD
* @see Element
* @see ContentModel
* @author Arthur van Hoff
*/
class ContentModelState {
long value;
/**
* Create a content model state for a content model.
*/
}
/**
* Create a content model state for a content model given the
* remaining state that needs to be reduce.
*/
}
/**
* Create a content model state for a content model given the
* remaining state that needs to be reduce.
*/
}
/**
* Return the content model that is relevant to the current state.
*/
ContentModel m = model;
for (int i = 0; i < value; i++) {
m = m.next;
} else {
return null;
}
}
return m;
}
/**
* Check if the state can be terminated. That is there are no more
* tokens required in the input stream.
* @return true if the model can terminate without further input
*/
public boolean terminate() {
case '+':
return false;
}
case '*':
case '?':
case '|':
if (m.empty()) {
}
}
return false;
case '&': {
if (!m.empty()) {
return false;
}
}
}
}
case ',': {
if (m != null) {
return false;
}
}
default:
return false;
}
}
/**
* Check if the state can be terminated. That is there are no more
* tokens required in the input stream.
* @return the only possible element that can occur next
*/
case '*':
case '?':
case '|':
case '&':
return null;
case '+':
case ',': {
return m.first();
}
default:
}
}
/**
* Advance this state to a new state. An exception is thrown if the
* token is illegal at this point in the content model.
* @return next state after reducing a token
*/
case '+':
}
if (value != 0) {
} else {
return null;
}
}
break;
case '*':
}
} else {
return null;
}
case '?':
}
} else {
return null;
}
case '|':
}
}
break;
case ',': {
} else {
return new ContentModelState(m,
}
}
break;
}
case '&': {
boolean complete = true;
return new ContentModelState(m,
}
if (!m.empty()) {
complete = false;
}
}
}
if (complete) {
} else {
return null;
}
}
break;
}
default:
}
return next;
}
// PENDING: Currently we don't correctly deal with optional start
// tags. This can most notably be seen with the 4.01 spec where
// TBODY's start and end tags are optional.
// Uncommenting this and the PENDING in ContentModel will
// correctly skip the omit tags, but the delegate is not notified.
// Some additional API needs to be added to track skipped tags,
// and this can then be added back.
/*
if ((model.content instanceof Element)) {
Element e = (Element)model.content;
if (e.omitStart() && e.content != null) {
return new ContentModelState(e.content, next).advance(
token);
}
}
*/
}
// We used to throw this exception at this point. However, it
// was determined that throwing this exception was more expensive
// than returning null, and we could not justify to ourselves why
// it was necessary to throw an exception, rather than simply
// returning null. I'm leaving it in a commented out state so
// that it can be easily restored if the situation ever arises.
//
// throw new IllegalArgumentException("invalid token: " + token);
return null;
}
}