Methods Summary |
---|
java.lang.String | getFile(int fileid)Returns the file at the given position in the list.
return (String) sourceFiles.get(fileid);
|
org.apache.jasper.JspCompilationContext | getJspCompilationContext()
return context;
|
java.net.URL | getResource(java.lang.String path)Gets the URL for the given path name.
return context.getResource(path);
|
java.lang.String | getText(Mark start, Mark stop)
Mark oldstart = mark();
reset(start);
CharArrayWriter caw = new CharArrayWriter();
while (!stop.equals(mark()))
caw.write(nextChar());
caw.close();
reset(oldstart);
return caw.toString();
|
boolean | hasMoreInput()Checks if the current file has more input.
if (current.cursor >= current.stream.length) {
if (singleFile) return false;
while (popFile()) {
if (current.cursor < current.stream.length) return true;
}
return false;
}
return true;
|
private boolean | isDelimiter()Parse utils - Is current character a token delimiter ?
Delimiters are currently defined to be =, >, <, ", and ' or any
any space character as defined by isSpace .
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;
}
|
final boolean | isSpace()
// Note: If this logic changes, also update Node.TemplateText.rtrim()
return peekChar() <= ' ";
|
Mark | mark()
return new Mark(current);
|
boolean | matches(java.lang.String string)search the stream for a match to a string
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());
return true;
|
boolean | matchesETag(java.lang.String tagName)
Mark mark = mark();
if (!matches("</" + tagName))
return false;
skipSpaces();
if (nextChar() == '>")
return true;
reset(mark);
return false;
|
boolean | matchesETagWithoutLessThan(java.lang.String tagName)
Mark mark = mark();
if (!matches("/" + tagName))
return false;
skipSpaces();
if (nextChar() == '>")
return true;
reset(mark);
return false;
|
boolean | matchesIgnoreCase(java.lang.String string)
Mark mark = mark();
int ch = 0;
int i = 0;
do {
ch = nextChar();
if (Character.toLowerCase((char) ch) != string.charAt(i++)) {
reset(mark);
return false;
}
} while (i < string.length());
reset(mark);
return true;
|
boolean | matchesOptionalSpacesFollowedBy(java.lang.String s)Looks ahead to see if there are optional spaces followed by
the given String. If so, true is returned and those spaces and
characters are skipped. If not, false is returned and the
position is restored to where we were before.
Mark mark = mark();
skipSpaces();
boolean result = matches( s );
if( !result ) {
reset( mark );
}
return result;
|
int | nextChar()
if (!hasMoreInput())
return -1;
int ch = current.stream[current.cursor];
current.cursor++;
if (ch == '\n") {
current.line++;
current.col = 0;
} else {
current.col++;
}
return ch;
|
java.lang.String | parseToken(boolean quoted)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.
StringBuffer stringBuffer = new StringBuffer();
skipSpaces();
stringBuffer.setLength(0);
if (!hasMoreInput()) {
return "";
}
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) {
err.jspError(mark(), "jsp.error.quotes.unterminated");
}
} else {
err.jspError(mark(), "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();
|
int | peekChar()
if (!hasMoreInput())
return -1;
return current.stream[current.cursor];
|
private boolean | popFile()Pop a file from the file stack. The field "current" is retored
to the value to point to the previous files, if any, and is set
to null otherwise.
// Is stack created ? (will happen if the Jsp file we're looking at is
// missing.
if (current == null || currFileId < 0) {
return false;
}
// Restore parser state:
String fName = getFile(currFileId);
currFileId = unregisterSourceFile(fName);
if (currFileId < -1) {
err.jspError("jsp.error.file.not.registered", fName);
}
Mark previous = current.popStream();
if (previous != null) {
master = current.baseDir;
current = previous;
return true;
}
// Note that although the current file is undefined here, "current"
// is not set to null just for convience, for it maybe used to
// set the current (undefined) position.
return false;
|
void | pushChar()Back up the current cursor by one char, assumes current.cursor > 0,
and that the char to be pushed back is not '\n'.
current.cursor--;
current.col--;
|
private void | pushFile(java.lang.String file, java.lang.String encoding, java.io.InputStreamReader reader)Push a file (and its associated Stream) on the file stack. THe
current position in the current file is remembered.
// Register the file
String longName = file;
int fileid = registerSourceFile(longName);
if (fileid == -1) {
// Bugzilla 37407: http://issues.apache.org/bugzilla/show_bug.cgi?id=37407
if(reader != null) {
try {
reader.close();
} catch (Exception any) {
if(log.isDebugEnabled()) {
log.debug("Exception closing reader: ", any);
}
}
}
err.jspError("jsp.error.file.already.registered", file);
}
currFileId = fileid;
try {
CharArrayWriter caw = new CharArrayWriter();
char buf[] = new char[1024];
for (int i = 0 ; (i = reader.read(buf)) != -1 ;)
caw.write(buf, 0, i);
caw.close();
if (current == null) {
current = new Mark(this, caw.toCharArray(), fileid,
getFile(fileid), master, encoding);
} else {
current.pushStream(caw.toCharArray(), fileid, getFile(fileid),
longName, encoding);
}
} catch (Throwable ex) {
log.error("Exception parsing file ", ex);
// Pop state being constructed:
popFile();
err.jspError("jsp.error.file.cannot.read", file);
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception any) {
if(log.isDebugEnabled()) {
log.debug("Exception closing reader: ", any);
}
}
}
}
|
private int | registerSourceFile(java.lang.String file)Register a new source file.
This method is used to implement file inclusion. Each included file
gets a unique identifier (which is the index in the array of source
files).
if (sourceFiles.contains(file)) {
return -1;
}
sourceFiles.add(file);
this.size++;
return sourceFiles.size() - 1;
|
void | reset(Mark mark)
current = new Mark(mark);
|
void | setSingleFile(boolean val)
singleFile = val;
|
int | skipSpaces()
int i = 0;
while (hasMoreInput() && isSpace()) {
i++;
nextChar();
}
return i;
|
Mark | skipUntil(java.lang.String limit)Skip until the given string is matched in the stream.
When returned, the context is positioned past the end of the match.
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)) {
Mark restart = mark();
for (int i = 1 ; i < limlen ; i++) {
if (peekChar() == limit.charAt(i))
nextChar();
else {
reset(restart);
continue skip;
}
}
return ret;
}
}
return null;
|
Mark | skipUntilETag(java.lang.String tag)Skip until the given end tag is matched in the stream.
When returned, the context is positioned past the end of the tag.
Mark ret = skipUntil("</" + tag);
if (ret != null) {
skipSpaces();
if (nextChar() != '>")
ret = null;
}
return ret;
|
Mark | skipUntilIgnoreEsc(java.lang.String limit)Skip until the given string is matched in the stream, but ignoring
chars initially escaped by a '\'.
When returned, the context is positioned past the end of the match.
Mark ret = null;
int limlen = limit.length();
int ch;
int prev = 'x"; // Doesn't matter
skip:
for (ret = mark(), ch = nextChar() ; ch != -1 ;
ret = mark(), prev = ch, ch = nextChar()) {
if (ch == '\\" && prev == '\\") {
ch = 0; // Double \ is not an escape char anymore
}
else if (ch == limit.charAt(0) && prev != '\\") {
for (int i = 1 ; i < limlen ; i++) {
if (peekChar() == limit.charAt(i))
nextChar();
else
continue skip;
}
return ret;
}
}
return null;
|
private int | unregisterSourceFile(java.lang.String file)Unregister the source file.
This method is used to implement file inclusion. Each included file
gets a uniq identifier (which is the index in the array of source
files).
if (!sourceFiles.contains(file)) {
return -1;
}
sourceFiles.remove(file);
this.size--;
return sourceFiles.size() - 1;
|