KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > xml > catalog > readers > TextCatalogReader


1 // TextCatalogReader.java - Read text/plain Catalog files
2

3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" must
29  * not be used to endorse or promote products derived from this
30  * software without prior written permission. For written
31  * permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * nor may "Apache" appear in their name, without prior written
35  * permission of the Apache Software Foundation.
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 APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 package org.jboss.util.xml.catalog.readers;
58
59 import java.io.InputStream JavaDoc;
60 import java.io.IOException JavaDoc;
61 import java.io.FileNotFoundException JavaDoc;
62 import java.net.URL JavaDoc;
63 import java.net.URLConnection JavaDoc;
64 import java.net.MalformedURLException JavaDoc;
65 import java.util.Vector JavaDoc;
66 import java.util.Stack JavaDoc;
67 import org.jboss.util.xml.catalog.Catalog;
68 import org.jboss.util.xml.catalog.CatalogEntry;
69 import org.jboss.util.xml.catalog.CatalogException;
70 import org.jboss.util.xml.catalog.readers.CatalogReader;
71
72 /**
73  * Parses plain text Catalog files.
74  *
75  * <p>This class reads plain text Open Catalog files.</p>
76  *
77  * @see Catalog
78  *
79  * @author Norman Walsh
80  * <a HREF="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
81  *
82  * @version 1.0
83  */

84 public class TextCatalogReader implements CatalogReader {
85   /** The input stream used to read the catalog */
86   protected InputStream JavaDoc catfile = null;
87
88   /**
89    * Character lookahead stack. Reading a catalog sometimes requires
90    * up to two characters of lookahead.
91    */

92   protected int[] stack = new int[3];
93
94   /**
95    * Token stack. Recognizing an unexpected catalog entry requires
96    * the ability to "push back" a token.
97    */

98   protected Stack JavaDoc tokenStack = new Stack JavaDoc();
99
100   /** The current position on the lookahead stack */
101   protected int top = -1;
102
103   /** Are keywords in the catalog case sensitive? */
104   protected boolean caseSensitive = false;
105
106   /**
107    * Construct a CatalogReader object.
108    */

109   public TextCatalogReader() { }
110
111   public void setCaseSensitive(boolean isCaseSensitive) {
112     caseSensitive = isCaseSensitive;
113   }
114
115   public boolean getCaseSensitive() {
116     return caseSensitive;
117   }
118
119   /**
120    * Start parsing a text catalog file. The file is
121    * actually read and parsed
122    * as needed by <code>nextEntry</code>.</p>
123    *
124    * @param fileUrl The URL or filename of the catalog file to process
125    *
126    * @throws MalformedURLException Improper fileUrl
127    * @throws IOException Error reading catalog file
128    */

129   public void readCatalog(Catalog catalog, String JavaDoc fileUrl)
130     throws MalformedURLException JavaDoc, IOException JavaDoc {
131     URL JavaDoc catURL = null;
132
133     try {
134       catURL = new URL JavaDoc(fileUrl);
135     } catch (MalformedURLException JavaDoc e) {
136       catURL = new URL JavaDoc("file:///" + fileUrl);
137     }
138
139     URLConnection JavaDoc urlCon = catURL.openConnection();
140     try {
141       readCatalog(catalog, urlCon.getInputStream());
142     } catch (FileNotFoundException JavaDoc e) {
143       catalog.getCatalogManager().debug.message(1, "Failed to load catalog, file not found",
144                         catURL.toString());
145     }
146   }
147
148   public void readCatalog(Catalog catalog, InputStream JavaDoc is)
149     throws MalformedURLException JavaDoc, IOException JavaDoc {
150
151     catfile = is;
152
153     if (catfile == null) {
154       return;
155     }
156
157     Vector JavaDoc unknownEntry = null;
158
159     while (true) {
160       String JavaDoc token = nextToken();
161
162       if (token == null) {
163     if (unknownEntry != null) {
164       catalog.unknownEntry(unknownEntry);
165       unknownEntry = null;
166     }
167     catfile.close();
168     catfile = null;
169     return;
170       }
171
172       String JavaDoc entryToken = null;
173       if (caseSensitive) {
174     entryToken = token;
175       } else {
176     entryToken = token.toUpperCase();
177       }
178
179       try {
180     int type = CatalogEntry.getEntryType(entryToken);
181     int numArgs = CatalogEntry.getEntryArgCount(type);
182     Vector JavaDoc args = new Vector JavaDoc();
183
184     if (unknownEntry != null) {
185       catalog.unknownEntry(unknownEntry);
186       unknownEntry = null;
187     }
188
189     for (int count = 0; count < numArgs; count++) {
190       args.addElement(nextToken());
191     }
192
193     catalog.addEntry(new CatalogEntry(entryToken, args));
194       } catch (CatalogException cex) {
195     if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
196       if (unknownEntry == null) {
197         unknownEntry = new Vector JavaDoc();
198       }
199       unknownEntry.addElement(token);
200     } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
201       catalog.getCatalogManager().debug.message(1, "Invalid catalog entry", token);
202       unknownEntry = null;
203     }
204       }
205     }
206   }
207
208   /**
209      * The destructor.
210      *
211      * <p>Makes sure the catalog file is closed.</p>
212      */

213   protected void finalize() {
214     if (catfile != null) {
215       try {
216     catfile.close();
217       } catch (IOException JavaDoc e) {
218     // whatever...
219
}
220     }
221     catfile = null;
222   }
223
224   // -----------------------------------------------------------------
225

226     /**
227      * Return the next token in the catalog file.
228      *
229      * @return The Catalog file token from the input stream.
230      * @throws IOException If an error occurs reading from the stream.
231      */

232   protected String JavaDoc nextToken() throws IOException JavaDoc {
233     String JavaDoc token = "";
234     int ch, nextch;
235
236     if (!tokenStack.empty()) {
237       return (String JavaDoc) tokenStack.pop();
238     }
239
240     // Skip over leading whitespace and comments
241
while (true) {
242       // skip leading whitespace
243
ch = catfile.read();
244       while (ch <= ' ') { // all ctrls are whitespace
245
ch = catfile.read();
246     if (ch < 0) {
247       return null;
248     }
249       }
250
251       // now 'ch' is the current char from the file
252
nextch = catfile.read();
253       if (nextch < 0) {
254     return null;
255       }
256
257       if (ch == '-' && nextch == '-') {
258     // we've found a comment, skip it...
259
ch = ' ';
260     nextch = nextChar();
261     while (ch != '-' || nextch != '-') {
262       ch = nextch;
263       nextch = nextChar();
264     }
265
266     // Ok, we've found the end of the comment,
267
// loop back to the top and start again...
268
} else {
269     stack[++top] = nextch;
270     stack[++top] = ch;
271     break;
272       }
273     }
274
275     ch = nextChar();
276     if (ch == '"' || ch == '\'') {
277       int quote = ch;
278       while ((ch = nextChar()) != quote) {
279     char[] chararr = new char[1];
280     chararr[0] = (char) ch;
281     String JavaDoc s = new String JavaDoc(chararr);
282     token = token.concat(s);
283       }
284       return token;
285     } else {
286       // return the next whitespace or comment delimited
287
// string
288
while (ch > ' ') {
289     nextch = nextChar();
290     if (ch == '-' && nextch == '-') {
291       stack[++top] = ch;
292       stack[++top] = nextch;
293       return token;
294     } else {
295       char[] chararr = new char[1];
296       chararr[0] = (char) ch;
297       String JavaDoc s = new String JavaDoc(chararr);
298       token = token.concat(s);
299       ch = nextch;
300     }
301       }
302       return token;
303     }
304   }
305
306   /**
307      * Return the next logical character from the input stream.
308      *
309      * @return The next (logical) character from the input stream. The
310      * character may be buffered from a previous lookahead.
311      *
312      * @throws IOException If an error occurs reading from the stream.
313      */

314   protected int nextChar() throws IOException JavaDoc {
315     if (top < 0) {
316       return catfile.read();
317     } else {
318       return stack[top--];
319     }
320   }
321 }
322
Popular Tags