001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 1999 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
027: * Foundation" must not be used to endorse or promote products derived
028: * from this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of the Apache Software Foundation. For more
051: * information on the Apache Software Foundation, please see
052: * <http://www.apache.org/>.
053: *
054: */
055:
056: package com.rimfaxe.webserver.compiler.jsp;
057:
058: import java.util.Stack;
059:
060: /**
061: * Mark represents a point in the JSP input.
062: *
063: * @author Anil K. Vijendran
064: * @author Lars Andersen
065: */
066: public final class Mark {
067: int cursor, line, col; // position within current stream
068: int fileid; // fileid of current stream
069: String fileName; // name of the current file
070: String baseDir; // directory of file for current stream
071: char[] stream = null; // current stream
072: Stack includeStack = null; // stack of stream and stream state of streams
073: // that have included current stream
074: String encoding = null; // encoding of current file
075: private JspReader reader; // reader that owns this mark
076:
077: // (so we can look up fileid's)
078:
079: /**
080: * Keep track of parser before parsing an included file.
081: * This class keeps track of the parser before we switch to parsing an
082: * included file. In other words, it's the parser's continuation to be
083: * reinstalled after the included file parsing is done.
084: */
085: class IncludeState {
086: int cursor, line, col;
087: int fileid;
088: String fileName;
089: String baseDir;
090: String encoding;
091: char[] stream = null;
092:
093: IncludeState(int inCursor, int inLine, int inCol, int inFileid,
094: String name, String inBaseDir, String inEncoding,
095: char[] inStream) {
096: cursor = inCursor;
097: line = inLine;
098: col = inCol;
099: fileid = inFileid;
100: fileName = name;
101: baseDir = inBaseDir;
102: encoding = inEncoding;
103: stream = inStream;
104: }
105: }
106:
107: /**
108: * Creates a new mark
109: * @param inReader JspReader this mark belongs to
110: * @param inStream current stream for this mark
111: * @param inFileid id of requested jsp file
112: * @param inEncoding encoding of current file
113: * @param inBaseDir base directory of requested jsp file
114: */
115: Mark(JspReader reader, char[] inStream, int fileid, String name,
116: String inBaseDir, String inEncoding) {
117: this .reader = reader;
118: this .stream = inStream;
119: this .cursor = this .line = this .col = 0;
120: this .fileid = fileid;
121: this .fileName = name;
122: this .baseDir = inBaseDir;
123: this .encoding = inEncoding;
124: this .includeStack = new Stack();
125: }
126:
127: Mark(Mark other) {
128: this .reader = other.reader;
129: this .stream = other.stream;
130: this .fileid = other.fileid;
131: this .fileName = other.fileName;
132: this .cursor = other.cursor;
133: this .line = other.line;
134: this .col = other.col;
135: this .baseDir = other.baseDir;
136: this .encoding = other.encoding;
137:
138: // clone includeStack without cloning contents
139: includeStack = new Stack();
140: for (int i = 0; i < other.includeStack.size(); i++) {
141: includeStack.addElement(other.includeStack.elementAt(i));
142: }
143: }
144:
145: Mark(String filename, int line, int col) {
146: //System.out.println("MARK: filename is: " + filename);
147: this .reader = null;
148: this .stream = null;
149: this .cursor = 0;
150: this .line = line;
151: this .col = col;
152: this .fileid = -1;
153: this .fileName = filename;
154: this .baseDir = "le-basedir";
155: this .encoding = "le-endocing";
156: this .includeStack = null;
157: }
158:
159: /** Sets this mark's state to a new stream.
160: * It will store the current stream in it's includeStack.
161: * @param inStream new stream for mark
162: * @param inFileid id of new file from which stream comes from
163: * @param inBaseDir directory of file
164: * @param inEncoding encoding of new file
165: */
166: public void pushStream(char[] inStream, int inFileid, String name,
167: String inBaseDir, String inEncoding) {
168:
169: // store current state in stack
170: includeStack.push(new IncludeState(cursor, line, col, fileid,
171: fileName, baseDir, encoding, stream));
172:
173: // set new variables
174: cursor = 0;
175: line = 0;
176: col = 0;
177: fileid = inFileid;
178: fileName = name;
179: baseDir = inBaseDir;
180: encoding = inEncoding;
181: stream = inStream;
182: }
183:
184: /** Restores this mark's state to a previously stored stream.
185: */
186: public boolean popStream() {
187: // make sure we have something to pop
188: if (includeStack.size() <= 0)
189: return false;
190:
191: // get previous state in stack
192: IncludeState state = (IncludeState) includeStack.pop();
193:
194: // set new variables
195: cursor = state.cursor;
196: line = state.line;
197: col = state.col;
198: fileid = state.fileid;
199: fileName = state.fileName;
200: baseDir = state.baseDir;
201: stream = state.stream;
202: return true;
203: }
204:
205: // -------------------- Locator interface --------------------
206:
207: public int getLineNumber() {
208: return line;
209: }
210:
211: public int getColumnNumber() {
212: return col;
213: }
214:
215: public String getSystemId() {
216: return getFile();
217: }
218:
219: public String getPublicId() {
220: return null;
221: }
222:
223: public String toString() {
224: return getFile() + "(" + line + "," + col + ")";
225: }
226:
227: public String getFile() {
228: return this .fileName;
229: }
230:
231: public String toShortString() {
232: return "(" + line + "," + col + ")";
233: }
234:
235: public boolean equals(Object other) {
236: if (other instanceof Mark) {
237: Mark m = (Mark) other;
238: return this .reader == m.reader && this .fileid == m.fileid
239: && this .cursor == m.cursor && this .line == m.line
240: && this .col == m.col;
241: }
242: return false;
243: }
244: }
|