001: /*
002: * Include.java February 2006
003: *
004: * Copyright (C) 2006, Niall Gallagher <niallg@users.sf.net>
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General
016: * Public License along with this library; if not, write to the
017: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
018: * Boston, MA 02111-1307 USA
019: */
020:
021: package simple.page.translate;
022:
023: import java.io.IOException;
024:
025: /**
026: * The <code>Include</code> object is used to process JSP includes.
027: * This require recursive processing of the document, as its source
028: * lies in seperate files. The following token is processed.
029: * <pre>
030: *
031: * <%@ include file="path" %>
032: *
033: * </pre>
034: * This above token requires that the "path" refers to a file that
035: * exists relative to the parent JSP source. For example if the
036: * parent was "/path/Parent.jsp" and the file parameter was the
037: * path "../File.jsp" then "/File.jsp" is the sourc evaluated.
038: *
039: * @author Niall Gallagher
040: */
041: class Include extends Token {
042:
043: /**
044: * This is used to accumulate the bytes for the file path.
045: */
046: private TokenBuffer include;
047:
048: /**
049: * Constructor for the <code>Include</code> token. This will
050: * create a buffer, which can be used to accumulate the data
051: * extracted from the supplied include token.
052: */
053: public Include() {
054: this .include = new TokenBuffer();
055: }
056:
057: /**
058: * Constructor for the <code>Include</code> token. This will
059: * create a buffer, which can be used to accumulate the data
060: * extracted from the supplied insert token before parsing.
061: *
062: * @param token this is the include token to be parsed
063: */
064: public Include(String token) {
065: this ();
066: parse(token);
067: }
068:
069: /**
070: * This will use the extracted path from the include token to
071: * recursively process the document definition. This basically
072: * uses asks the builder to build and the evaluate the named
073: * file, if the file does not exist an exception is throws.
074: *
075: * @param source this is the document definition processed
076: * @param builder this is used for recursive JSP processing
077: */
078: public void process(Definition source, Builder builder)
079: throws IOException {
080: builder.build(include.text(), source);
081: }
082:
083: /**
084: * This will clear the name token so that the parse can be reused
085: * by the builder. In practice this method just satisfies the
086: * contract of the token so that this object is not abstract.
087: */
088: protected void init() {
089: include.clear();
090: }
091:
092: /**
093: * This does not verify the token type, instead this will seek
094: * the '=' character. Once the '=' character has been encountered
095: * the file is extracted as a quoted string, for example "path".
096: */
097: protected void parse() {
098: scrap();
099: include();
100: }
101:
102: /**
103: * This is a quick and dirty means of parsing the token. This
104: * will basically seek the '=' character such the offset of
105: * the buffer is on the start of the name, like "[p]ath".
106: */
107: private void scrap() {
108: while (off < count) {
109: char next = buf[off];
110:
111: if (next == '=') {
112: while (off < count) {
113: next = buf[off++];
114: if (quote(next)) {
115: break;
116: }
117: }
118: break;
119: }
120: off++;
121: }
122: }
123:
124: /**
125: * This method will read all characters up to a space or the
126: * next quotation chatacter, for example "'" or '"' will be
127: * considered a terminal. Once this has finished the name will
128: * be stored in the internal name buffer for processing.
129: */
130: private void include() {
131: while (off < count) {
132: char next = buf[off++];
133:
134: if (space(next)) {
135: break;
136: } else if (quote(next)) {
137: break;
138: }
139: include.append(next);
140: }
141: }
142:
143: /**
144: * This is used to determine when the start and end of the name
145: * has been encountered. The terminals are '"' and '"', which
146: * are legal quotations within the JSP syntax.
147: *
148: * @param ch this is the character to be evaluated
149: *
150: * @return this returns true if the character is a quote
151: */
152: private boolean quote(char ch) {
153: return ch == '"' || ch == '\'';
154: }
155: }
|