Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.apache.jasper.compiler;
 
 import static org.jboss.web.JasperMessages.MESSAGES;
 
 import java.util.List;
 import java.net.URL;
 
JspReader is an input buffer for the JSP parser. It should allow unlimited lookahead and pushback. It also has a bunch of parsing utility methods for understanding htmlesque thingies.

Author(s):
Anil K. Vijendran
Anselm Baird-Smith
Harish Prabandham
Rajiv Mordani
Mandar Raje
Danno Ferrin
Kin-man Chung
Shawn Bayern
Mark Roth
 
 
 class JspReader {

    
The current spot in the file.
 
     private Mark current;

    
What is this?
 
     private String master;

    
The list of source files.
 
     private List sourceFiles;

    
The current file ID (-1 indicates an error or no file).
 
     private int currFileId;

    
Seems redundant.
 
     private int size;

    
The compilation context.
 
     private JspCompilationContext context;

    
The Jasper error dispatcher.
 
     private ErrorDispatcher err;

    
Set to true when using the JspReader on a single file where we read up to the end and reset to the beginning many times. (as in ParserController.figureOutJspDocument()).
 
     private boolean singleFile;

    
Constructor.

Parameters:
ctxt The compilation context
fname The file name
encoding The file encoding
jarFile ?
err The error dispatcher
Throws:
org.apache.jasper.JasperException If a Jasper-internal error occurs
java.io.FileNotFoundException If the JSP file is not found (or is unreadable)
java.io.IOException If an IO-level error occurs, e.g. reading the file
    public JspReader(JspCompilationContext ctxt,
                     String fname,
                     String encoding,
                     JarFile jarFile,
                     ErrorDispatcher err)
            throws JasperExceptionFileNotFoundExceptionIOException {
        this(ctxtfnameencoding,
             JspUtil.getReader(fnameencodingjarFilectxterr),
             err);
    }

    
Constructor: same as above constructor but with initialized reader to the file given.
    public JspReader(JspCompilationContext ctxt,
                     String fname,
                     String encoding,
                     InputStreamReader reader,
                     ErrorDispatcher err)
            throws JasperExceptionFileNotFoundException {
        this. = ctxt;
        this. = err;
         = new Vector();
         = 0;
         = 0;
         = false;
        pushFile(fnameencodingreader);
    }

    

Returns:
JSP compilation context with which this JspReader is associated
        return ;
    }
    
    
Returns the file at the given position in the list.

Parameters:
fileid The file position in the list
Returns:
The file at that position, if found, null otherwise
    String getFile(final int fileid) {
        return (String.get(fileid);
    }
       
    
Checks if the current file has more input.

Returns:
True if more reading is possible
Throws:
org.apache.jasper.JasperException if an error occurs
 
    boolean hasMoreInput() throws JasperException {
        if (. >= ..) {
            if (return false
            while (popFile()) {
                if (. < ..return true;
            }
            return false;
        }
        return true;
    }
    
    int nextChar() throws JasperException {
        if (!hasMoreInput())
            return -1;
        
        int ch = .[.];
        .++;
        
        if (ch == '\n') {
            .++;
            . = 0;
        } else {
            .++;
        }
        return ch;
    }

    
Back up the current cursor by one char, assumes current.cursor > 0, and that the char to be pushed back is not '\n'.
    void pushChar() {
        .--;
        .--;
    }
    String getText(Mark startMark stopthrows JasperException {
        Mark oldstart = mark();
        reset(start);
        CharArrayWriter caw = new CharArrayWriter();
        while (!stop.equals(mark()))
            caw.write(nextChar());
        caw.close();
        reset(oldstart);
        return caw.toString();
    }
    int peekChar() throws JasperException {
        if (!hasMoreInput())
            return -1;
        return .[.];
    }
    Mark mark() {
        return new Mark();
    }
    void reset(Mark mark) {
         = new Mark(mark);
    }
    boolean matchesIgnoreCase(String stringthrows JasperException {
        Mark mark = mark();
        int ch = 0;
        int i = 0;
        do {
            ch = nextChar();
            if (Character.toLowerCase((charch) != string.charAt(i++)) {
                reset(mark);
                return false;
            }
        } while (i < string.length());
        reset(mark);
        return true;
    }

    
search the stream for a match to a string

Parameters:
string The string to match
Returns:
true is one is found, the current position in stream is positioned after the search string, false otherwise, position in stream unchanged.
    boolean matches(String stringthrows JasperException {
        Mark mark = mark();
        int ch = 0;
        int i = 0;
        do {
            ch = nextChar();
            if (((charch) != string.charAt(i++)) {
                reset(mark);
                return false;
            }
        } while (i < string.length());
        return true;
    }
    boolean matchesETag(String tagNamethrows JasperException {
        Mark mark = mark();
        if (!matches("</" + tagName))
            return false;
        skipSpaces();
        if (nextChar() == '>')
            return true;
        reset(mark);
        return false;
    }
    boolean matchesETagWithoutLessThan(String tagName)
        throws JasperException
    {
       Mark mark = mark();
       if (!matches("/" + tagName))
           return false;
       skipSpaces();
       if (nextChar() == '>')
           return true;
       reset(mark);
       return false;
    }


    
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.
        throws JasperException
    {
        Mark mark = mark();
        skipSpaces();
        boolean result = matchess );
        if( !result ) {
            resetmark );
        }
        return result;
    }
    int skipSpaces() throws JasperException {
        int i = 0;
        while (hasMoreInput() && 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.

Parameters:
s The String to match.
Returns:
A non-null Mark instance (positioned immediately before the search string) if found, null otherwise.
    Mark skipUntil(String limitthrows JasperException {
        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;
    }

    
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.

Parameters:
s The String to match.
Returns:
A non-null Mark instance (positioned immediately before the search string) if found, null otherwise.
    Mark skipUntilIgnoreEsc(String limitthrows JasperException {
        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 = chch = 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;
    }
    
    
Skip until the given end tag is matched in the stream. When returned, the context is positioned past the end of the tag.

Parameters:
tag The name of the tag whose ETag (</tag>) to match.
Returns:
A non-null Mark instance (positioned immediately before the ETag) if found, null otherwise.
    Mark skipUntilETag(String tagthrows JasperException {
        Mark ret = skipUntil("</" + tag);
        if (ret != null) {
            skipSpaces();
            if (nextChar() != '>')
                ret = null;
        }
        return ret;
    }
    final boolean isSpace() throws JasperException {
        // Note: If this logic changes, also update Node.TemplateText.rtrim()
        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.

Parameters:
quoted If true accept quoted strings.
    String parseToken(boolean quotedthrows JasperException {
        StringBuilder StringBuilder = new StringBuilder();
        skipSpaces();
        StringBuilder.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();
                    StringBuilder.append((charch);
                }
                // Check end of quote, skip closing quote:
                if (ch == -1) {
                    .jspError(mark(), .unterminatedQuotes());
                }
            } else {
                .jspError(mark(), .unquotedAttributeValue());
            }
        } 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();
                    }
                    StringBuilder.append((charch);
                } while (!isDelimiter());
            }
        }
        return StringBuilder.toString();
    }
    void setSingleFile(boolean val) {
         = val;
    }


    
Gets the URL for the given path name.

Parameters:
path Path name
Returns:
URL for the given path name.
Throws:
java.net.MalformedURLException if the path name is not given in the correct form
    URL getResource(String paththrows MalformedURLException {
        return .getResource(path);
    }


    
Parse utils - Is current character a token delimiter ? Delimiters are currently defined to be =, >, <, ", and ' or any any space character as defined by isSpace.

Returns:
A boolean.
    private boolean isDelimiter() throws JasperException {
        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;
        }
    }

    
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).

Returns:
The index of the now registered file.
    private int registerSourceFile(final String file) {
        if (.contains(file)) {
            return -1;
        }
        .add(file);
        this.++;
        return .size() - 1;
    }
    

    
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).

Returns:
The index of the now registered file.
    private int unregisterSourceFile(final String file) {
        if (!.contains(file)) {
            return -1;
        }
        .remove(file);
        this.--;
        return .size() - 1;
    }

    
Push a file (and its associated Stream) on the file stack. THe current position in the current file is remembered.
    private void pushFile(String fileString encoding
                           InputStreamReader reader
                throws JasperExceptionFileNotFoundException {
        // 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) {
                    ..errorClosingReader(any);
                }
            }
            .jspError(.invalidRecursiveInclude(file));
        }
         = 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 ( == null) {
                 = new Mark(thiscaw.toCharArray(), fileid
                                   getFile(fileid), encoding);
            } else {
                .pushStream(caw.toCharArray(), fileidgetFile(fileid),
                                   longNameencoding);
            }
        } catch (Throwable ex) {
            // Pop state being constructed:
            popFile();
            .jspError(.errorReadingFile(file));
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception any) {
                    ..errorClosingReader(any);
                }
            }
        }
    }

    
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.

Returns:
true is there is a previous file on the stack. false otherwise.
    private boolean popFile() throws JasperException {
        // Is stack created ? (will happen if the Jsp file we're looking at is
        // missing.
        if ( == null ||  < 0) {
            return false;
        }
        // Restore parser state:
        String fName = getFile();
         = unregisterSourceFile(fName);
        if ( < -1) {
            .jspError(.invalidInclude(fName));
        }
        Mark previous = .popStream();
        if (previous != null) {
             = .;
             = 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;
    }
New to GrepCode? Check out our FAQ X