KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > go > trove > io > SourceReader


1 /* ====================================================================
2  * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3  * ====================================================================
4  * The Tea Software License, Version 1.1
5  *
6  * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Walt Disney Internet Group (http://opensource.go.com/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact opensource@dig.com.
31  *
32  * 5. Products derived from this software may not be called "Tea",
33  * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34  * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35  * written permission of the Walt Disney Internet Group.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * For more information about Tea, please see http://opensource.go.com/.
51  */

52
53 package com.go.trove.io;
54
55 import java.io.*;
56
57 /******************************************************************************
58  * The SourceReader provides several services for reading source input.
59  * It calculates line numbers, position in the source file, supports two
60  * character pushback, extracts code from text that allows mixed code and
61  * plain text, and it processes unicode escape sequences that appear in
62  * source code.
63  *
64  * <p>Readers return -1 when the end of the stream, has been reached, and so
65  * does SourceReader. SourceReader will also return other special negative
66  * values to indicate a tag substitution. ENTER_CODE is returned to indicate
67  * that characters read are in source code, and ENTER_TEXT is returned to
68  * indicate that characters read are in plain text. The first character read
69  * from a SourceReader is either ENTER_CODE or ENTER_TEXT;
70  *
71  * @author Brian S O'Neill
72  * @version
73  * <!--$$Revision:--> 18 <!-- $-->, <!--$$JustDate:--> 4/26/01 <!-- $-->
74  */

75 public class SourceReader extends PushbackPositionReader {
76     public static final int ENTER_CODE = -2;
77     public static final int ENTER_TEXT = -3;
78
79     private static Reader createReader(Reader source,
80                                        String JavaDoc beginTag, String JavaDoc endTag) {
81         String JavaDoc[] tags = new String JavaDoc[4];
82         int[] codes = new int[4];
83
84         int i = 0;
85         // Convert different kinds of line breaks into the newline character.
86
tags[i] = "\r\n"; codes[i++] = '\n';
87         tags[i] = "\r"; codes[i++] = '\n';
88
89         if (beginTag != null && beginTag.length() > 0) {
90             tags[i] = beginTag; codes[i++] = ENTER_CODE;
91         }
92
93         if (endTag != null && endTag.length() > 0) {
94             tags[i] = endTag; codes[i++] = ENTER_TEXT;
95         }
96
97         if (i < 4) {
98             String JavaDoc[] newTags = new String JavaDoc[i];
99             System.arraycopy(tags, 0, newTags, 0, i);
100             tags = newTags;
101
102             int[] newCodes = new int[i];
103             System.arraycopy(codes, 0, newCodes, 0, i);
104             codes = newCodes;
105         }
106
107         return new UnicodeReader(new TagReader(source, tags, codes));
108     }
109
110     private UnicodeReader mUnicodeReader;
111     private TagReader mTagReader;
112     private boolean mClosed = false;
113
114     // The current line in the source. (1..)
115
private int mLine = 1;
116
117     private int mFirst;
118
119     private String JavaDoc mBeginTag;
120     private String JavaDoc mEndTag;
121
122     /**
123      * The begin and end tags for a SourceReader are optional. If the begin
124      * tag is null or has zero length, then the SourceReader starts reading
125      * characters as if they were source code.
126      *
127      * <p>If the end tag is null or has zero length, then a source code
128      * region continues to the end of the input Reader's characters.
129      *
130      * @param source the source reader
131      * @param beginTag tag that marks the beginning of a source code region
132      * @param endTag tag that marks the end of a source code region
133      */

134     public SourceReader(Reader source, String JavaDoc beginTag, String JavaDoc endTag) {
135         this(source, beginTag, endTag, false);
136     }
137
138     /**
139      * The begin and end tags for a SourceReader are optional. If the begin
140      * tag is null or has zero length, then the SourceReader starts reading
141      * characters as if they were source code.
142      *
143      * <p>If the end tag is null or has zero length, then a source code
144      * region continues to the end of the input Reader's characters.
145      *
146      * @param source the source reader
147      * @param beginTag tag that marks the beginning of a source code region
148      * @param endTag tag that marks the end of a source code region
149      * @param inCode flag that indicates if the stream is starting in code
150      */

151     public SourceReader(Reader source, String JavaDoc beginTag, String JavaDoc endTag,
152                         boolean inCode) {
153         super(createReader(source, beginTag, endTag), 2);
154         mUnicodeReader = (UnicodeReader)in;
155         mTagReader = (TagReader)mUnicodeReader.getOriginalSource();
156
157         boolean codeMode = ((beginTag == null || beginTag.length() == 0) ||
158                             inCode);
159         mFirst = (codeMode) ? ENTER_CODE : ENTER_TEXT;
160
161         mBeginTag = beginTag;
162         mEndTag = endTag;
163     }
164
165     public String JavaDoc getBeginTag() {
166         return mBeginTag;
167     }
168
169     public String JavaDoc getEndTag() {
170         return mEndTag;
171     }
172
173     /**
174      * All newline character patterns are are converted to \n.
175      */

176     public int read() throws IOException {
177         int c;
178
179         if (mFirst != 0) {
180             c = mFirst;
181             mFirst = 0;
182         }
183         else {
184             c = super.read();
185         }
186
187         if (c == '\n') {
188             mLine++;
189         }
190         else if (c == ENTER_CODE) {
191             mUnicodeReader.setEscapesEnabled(true);
192         }
193         else if (c == ENTER_TEXT) {
194             mUnicodeReader.setEscapesEnabled(false);
195         }
196         
197         return c;
198     }
199
200     public int getLineNumber() {
201         return mLine;
202     }
203
204     /**
205      * The position in the reader where the last read character ended. The
206      * position of the first character read from a Reader is zero.
207      *
208      * <p>The end position is usually the same as the start position, but
209      * sometimes a SourceReader may combine multiple characters into a
210      * single one.
211      *
212      * @return the end position where the last character was read
213      */

214     public int getEndPosition() {
215         int e = getNextPosition() - 1;
216         return (e < getStartPosition()) ? getStartPosition() : e;
217     }
218
219     public void ignoreTags(boolean ignore) {
220         mTagReader.setEscapesEnabled(!ignore);
221     }
222
223     public boolean isClosed() {
224         return mClosed;
225     }
226
227     public void close() throws IOException {
228         mClosed = true;
229         super.close();
230     }
231
232     protected void unreadHook(int c) {
233         if (c == '\n') {
234             mLine--;
235         }
236         else if (c == ENTER_CODE) {
237             mUnicodeReader.setEscapesEnabled(false);
238         }
239         else if (c == ENTER_TEXT) {
240             mUnicodeReader.setEscapesEnabled(true);
241         }
242     }
243
244     /**
245      * Simple test program
246      */

247     public static void main(String JavaDoc[] arg) throws Exception JavaDoc {
248         Tester.test(arg);
249     }
250
251     private static class Tester {
252         public static void test(String JavaDoc[] arg) throws Exception JavaDoc {
253             String JavaDoc str =
254                 "This is \\" + "u0061 test.\n" +
255                 "This is \\" + "u00612 test.\n" +
256                 "This is \\" + "u0061" + "\\" + "u0061" + " test.\n" +
257                 "This is \\" + "u061 test.\n" +
258                 "This is \\\\" + "u0061 test.\n" +
259                 "This is \\" + "a test.\n" +
260                 "Plain text <%put code here%> plain text.\n" +
261                 "Plain text <\\" + "u0025put code here%> plain text.\n" +
262                 "Plain text <%put code here\\" + "u0025> plain text.\n";
263
264             Reader reader;
265
266             if (arg.length > 0) {
267                 reader = new java.io.FileReader JavaDoc(arg[0]);
268             }
269             else {
270                 System.out.println("\nOriginal:\n");
271                 
272                 reader = new StringReader(str);
273
274                 int c;
275                 while ( (c = reader.read()) != -1 ) {
276                     System.out.print((char)c);
277                 }
278             }
279
280             System.out.println("\nTest 1:\n");
281
282             if (arg.length > 0) {
283                 reader = new java.io.FileReader JavaDoc(arg[0]);
284             }
285             else {
286                 reader = new StringReader(str);
287             }
288
289             SourceReader sr = new SourceReader(reader, "<%", "%>");
290
291             int c;
292             while ( (c = sr.read()) != -1 ) {
293                 System.out.print((char)c);
294                 System.out.print("\t" + c);
295                 System.out.print("\t" + sr.getLineNumber());
296                 System.out.print("\t" + sr.getStartPosition());
297                 System.out.println("\t" + sr.getEndPosition());
298             }
299
300             System.out.println("\nTest 2:\n");
301             if (arg.length > 0) {
302                 reader = new java.io.FileReader JavaDoc(arg[0]);
303             }
304             else {
305                 reader = new StringReader(str);
306             }
307
308             sr = new SourceReader(reader, null, null);
309
310             while ( (c = sr.read()) != -1 ) {
311                 System.out.print((char)c);
312                 System.out.print("\t" + c);
313                 System.out.print("\t" + sr.getLineNumber());
314                 System.out.print("\t" + sr.getStartPosition());
315                 System.out.println("\t" + sr.getEndPosition());
316             }
317         }
318     }
319 }
320
Popular Tags