📄 jspreader.java
字号:
ch = nextChar();
if (Character.toLowerCase((char) ch) != string.charAt(i++)) {
reset(mark);
return false;
}
} while (i < string.length());
reset(mark);
return true;
}
public boolean matches(String string) throws ParseException {
Mark mark = mark();
int ch = 0;
int i = 0;
do {
ch = nextChar();
if (((char) ch) != string.charAt(i++)) {
reset(mark);
return false;
}
} while (i < string.length());
reset(mark);
return true;
}
public void advance(int n) throws ParseException {
while (--n >= 0)
nextChar();
}
public int skipSpaces() throws ParseException {
int i = 0;
while (isSpace()) {
i++;
nextChar();
}
return i;
}
/**
* Skip until the given string is matched in the stream.
* When returned, the context is positioned past the end of the match.
* @param s The String to match.
* @return A non-null <code>Mark</code> instance if found,
* <strong>null</strong> otherwise.
*/
public Mark skipUntil(String limit)
throws ParseException {
Mark ret = null;
int limlen = limit.length();
int ch;
skip:
for (ret = mark(), ch = nextChar() ; ch != -1 ; ret = mark(), ch = nextChar()) {
if ( ch == limit.charAt(0) ) {
for (int i = 1 ; i < limlen ; i++) {
if (Character.toLowerCase((char) nextChar()) != limit.charAt(i))
continue skip;
}
return ret;
}
}
return null;
}
final boolean isSpace() {
return peekChar() <= ' ';
}
/**
* Parse a space delimited token.
* If quoted the token will consume all characters up to a matching quote,
* otherwise, it consumes up to the first delimiter character.
* @param quoted If <strong>true</strong> accept quoted strings.
*/
public String parseToken(boolean quoted)
throws ParseException
{
StringBuffer stringBuffer = new StringBuffer();
skipSpaces();
stringBuffer.setLength(0);
int ch = peekChar();
if (quoted) {
if ( ch == '"' || ch == '\'') {
char endQuote = ch == '"' ? '"' : '\'';
// Consume the open quote:
ch = nextChar();
for(ch = nextChar(); ch != -1 && ch != endQuote; ch = nextChar()) {
if (ch == '\\')
ch = nextChar();
stringBuffer.append((char) ch);
}
// Check end of quote, skip closing quote:
if ( ch == -1 )
throw new ParseException(mark(),
Constants.getString("jsp.error.quotes.unterminated"));
}
else throw new ParseException(mark(),
Constants.getString("jsp.error.attr.quoted"));
} else {
if (!isDelimiter())
// Read value until delimiter is found:
do {
ch = nextChar();
// Take care of the quoting here.
if (ch == '\\') {
if (peekChar() == '"' || peekChar() == '\'' ||
peekChar() == '>' || peekChar() == '%')
ch = nextChar();
}
stringBuffer.append((char) ch);
} while ( !isDelimiter() );
}
return stringBuffer.toString();
}
/**
* Parse an attribute/value pair, and store it in provided hash table.
* The attribute/value pair is defined by:
* <pre>
* av := spaces token spaces '=' spaces token spaces
* </pre>
* Where <em>token</em> is defined by <code>parseToken</code> and
* <em>spaces</em> is defined by <code>skipSpaces</code>.
* The name is always considered case insensitive, hence stored in its
* lower case version.
* @param into The Hashtable instance to save the result to.
*/
private void parseAttributeValue(Hashtable into)
throws ParseException
{
// Get the attribute name:
skipSpaces();
String name = parseToken(false);
// Check for an equal sign:
skipSpaces();
if ( peekChar() != '=' )
throw new ParseException(mark(), Constants.getString("jsp.error.attr.novalue",
new Object[] { name }));
char ch = (char) nextChar();
// Get the attribute value:
skipSpaces();
String value = parseToken(true);
skipSpaces();
// Add the binding to the provided hashtable:
into.put(name, value);
return;
}
/**
* Parse some tag attributes for Beans.
* The stream is assumed to be positioned right after the tag name. The
* syntax recognized is:
* <pre>
* tag-attrs := empty | attr-list (">" | "-->" | %>)
* attr-list := empty | av spaces attr-list
* empty := spaces
* </pre>
* Where <em>av</em> is defined by <code>parseAttributeValue</code>.
* @return A Hashtable mapping String instances (variable names) into
* String instances (variable values).
*/
public Hashtable parseTagAttributesBean()
throws ParseException
{
Hashtable values = new Hashtable(11);
while ( true ) {
skipSpaces();
int ch = peekChar();
if ( ch == '>' ) {
// End of the useBean tag.
return values;
} else if ( ch == '/' ) {
Mark mark = mark();
nextChar();
// XMLesque Close tags
try {
if ( nextChar() == '>' )
return values;
} finally {
reset(mark);
}
}
if ( ch == -1 )
break;
// Parse as an attribute=value:
parseAttributeValue(values);
}
// Reached EOF:
throw new ParseException(mark(),
Constants.getString("jsp.error.tag.attr.unterminated"));
}
/**
* Parse some tag attributes.
* The stream is assumed to be positioned right after the tag name. The
* syntax recognized is:
* <pre>
* tag-attrs := empty | attr-list (">" | "-->" | %>)
* attr-list := empty | av spaces attr-list
* empty := spaces
* </pre>
* Where <em>av</em> is defined by <code>parseAttributeValue</code>.
* @return A Hashtable mapping String instances (variable names) into
* String instances (variable values).
*/
public Hashtable parseTagAttributes()
throws ParseException
{
Hashtable values = new Hashtable(11);
while ( true ) {
skipSpaces();
int ch = peekChar();
if ( ch == '>' ) {
return values;
}
if ( ch == '-' ) {
Mark mark = mark();
nextChar();
// Close NCSA like attributes "->"
try {
if ( nextChar() == '-' && nextChar() == '>' )
return values;
} finally {
reset(mark);
}
} else if ( ch == '%' ) {
Mark mark = mark();
nextChar();
// Close variable like attributes "%>"
try {
if ( nextChar() == '>' )
return values;
} finally {
reset(mark);
}
} else if ( ch == '/' ) {
Mark mark = mark();
nextChar();
// XMLesque Close tags
try {
if ( nextChar() == '>' )
return values;
} finally {
reset(mark);
}
}
if ( ch == -1 )
break;
// Parse as an attribute=value:
parseAttributeValue(values);
}
// Reached EOF:
throw new ParseException(mark(),
Constants.getString("jsp.error.tag.attr.unterminated"));
}
/**
* Parse PARAM tag attributes into the given hashtable.
* Parses the PARAM tag as defined by:
* <pre>
* <PARAM tag-attributes %gt;
* </pre>
* Two special tag attributes are recognized here:
* <ol>
* <li>The <strong>name</strong> attribute,
* <li>The <strong>value</strong> attribute.
* </ol>
* The resulting name, value pair is stored in the provided hash table.
* @param into Storage for parameter values.
*/
public void parseParamTag(Hashtable into)
throws ParseException
{
// Really check for a param tag:
if ( matches("param") ) {
advance(6);
parseParams (into);
} else {
// False alarm, just skip it
}
}
/**
* Parse jsp:param tag attributes into the given hashtable.
* Parses the jsp:param tag as defined by:
* <pre>
* <jsp:param tag-attributes %gt;
* </pre>
* Two special tag attributes are recognized here:
* <ol>
* <li>The <strong>name</strong> attribute,
* <li>The <strong>value</strong> attribute.
* </ol>
* The resulting name, value pair is stored in the provided hash table.
* @param into Storage for parameter values.
*/
public void parsePluginParamTag(Hashtable into)
throws ParseException
{
// Really check for a param tag:
if ( matches("<jsp:param") ) {
advance(11);
parseParams (into);
} else {
// False alarm, just skip it
}
}
private void parseParams (Hashtable into)
throws ParseException
{
Hashtable attrs = parseTagAttributes();
// Check attributes (name and value):
String name = (String) attrs.get("name");
String value = (String) attrs.get("value");
if ( name == null )
throw new ParseException(mark(), Constants.getString("jsp.error.param.noname"));
if ( value == null )
throw new ParseException(mark(), Constants.getString("jsp.error.param.novalue"));
// Put that new binding into the params hashatble:
String oldval[] = (String[]) into.get(name);
if ( oldval == null ) {
String newval[] = new String[1];
newval[0] = value;
into.put(name, newval);
} else {
String newval[] = new String[oldval.length+1];
System.arraycopy(oldval, 0, newval, 0, oldval.length);
newval[oldval.length] = value;
into.put(name, newval);
}
}
/**
* Parse utils - Is current character a token delimiter ?
* Delimiters are currently defined to be =, >, <, ", and ' or any
* any space character as defined by <code>isSpace</code>.
* @return A boolean.
*/
private boolean isDelimiter() throws ParseException {
if ( ! isSpace() ) {
int ch = peekChar();
// Look for a single-char work delimiter:
if ( ch == '=' || ch == '>' || ch == '"' || ch == '\'' || ch == '/')
return true;
// Look for an end-of-comment or end-of-tag:
if ( ch == '-' ) {
Mark mark = mark();
if ( ((ch = nextChar()) == '>')
|| ((ch == '-') && (nextChar() == '>')) ) {
reset(mark);
return true;
} else {
reset(mark);
return false;
}
}
return false;
} else {
return true;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -