Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/go/trove/io/SourceReader.java


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 beginTag, String endTag) {
81          String[] tags = new String[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[] newTags = new String[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 mBeginTag;
120     private String 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 beginTag, String 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 beginTag, String 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 getBeginTag() {
166         return mBeginTag;
167     }
168 
169     public String 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[] arg) throws Exception {
248         Tester.test(arg);
249     }
250 
251     private static class Tester {
252         public static void test(String[] arg) throws Exception {
253             String 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(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(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(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 }