org.jboss.util.xml.catalog.readers.TextCatalogReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jboss-common-core Show documentation
Show all versions of jboss-common-core Show documentation
JBoss Common Core Utility classes
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2015, Red Hat, Inc., and individual contributors as indicated
* by the @authors tag.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// TextCatalogReader.java - Read text/plain Catalog files
package org.jboss.util.xml.catalog.readers;
import java.io.InputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;
import java.util.Vector;
import java.util.Stack;
import org.jboss.util.xml.catalog.Catalog;
import org.jboss.util.xml.catalog.CatalogEntry;
import org.jboss.util.xml.catalog.CatalogException;
import org.jboss.util.xml.catalog.readers.CatalogReader;
/**
* Parses plain text Catalog files.
*
* This class reads plain text Open Catalog files.
*
* @see Catalog
*
* @author Norman Walsh
* [email protected]
*
* @version 1.0
*/
@SuppressWarnings("unchecked")
public class TextCatalogReader implements CatalogReader {
/** The input stream used to read the catalog */
protected InputStream catfile = null;
/**
* Character lookahead stack. Reading a catalog sometimes requires
* up to two characters of lookahead.
*/
protected int[] stack = new int[3];
/**
* Token stack. Recognizing an unexpected catalog entry requires
* the ability to "push back" a token.
*/
protected Stack tokenStack = new Stack();
/** The current position on the lookahead stack */
protected int top = -1;
/** Are keywords in the catalog case sensitive? */
protected boolean caseSensitive = false;
/**
* Construct a CatalogReader object.
*/
public TextCatalogReader() { }
public void setCaseSensitive(boolean isCaseSensitive) {
caseSensitive = isCaseSensitive;
}
public boolean getCaseSensitive() {
return caseSensitive;
}
/**
* Start parsing a text catalog file. The file is
* actually read and parsed
* as needed by nextEntry
.
*
* @param fileUrl The URL or filename of the catalog file to process
*
* @throws MalformedURLException Improper fileUrl
* @throws IOException Error reading catalog file
*/
public void readCatalog(Catalog catalog, String fileUrl)
throws MalformedURLException, IOException {
URL catURL = null;
try {
catURL = new URL(fileUrl);
} catch (MalformedURLException e) {
catURL = new URL("file:///" + fileUrl);
}
URLConnection urlCon = catURL.openConnection();
try {
readCatalog(catalog, urlCon.getInputStream());
} catch (FileNotFoundException e) {
catalog.getCatalogManager().debug.message(1, "Failed to load catalog, file not found",
catURL.toString());
}
}
public void readCatalog(Catalog catalog, InputStream is)
throws MalformedURLException, IOException {
catfile = is;
if (catfile == null) {
return;
}
Vector unknownEntry = null;
while (true) {
String token = nextToken();
if (token == null) {
if (unknownEntry != null) {
catalog.unknownEntry(unknownEntry);
unknownEntry = null;
}
catfile.close();
catfile = null;
return;
}
String entryToken = null;
if (caseSensitive) {
entryToken = token;
} else {
entryToken = token.toUpperCase();
}
try {
int type = CatalogEntry.getEntryType(entryToken);
int numArgs = CatalogEntry.getEntryArgCount(type);
Vector args = new Vector();
if (unknownEntry != null) {
catalog.unknownEntry(unknownEntry);
unknownEntry = null;
}
for (int count = 0; count < numArgs; count++) {
args.addElement(nextToken());
}
catalog.addEntry(new CatalogEntry(entryToken, args));
} catch (CatalogException cex) {
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
if (unknownEntry == null) {
unknownEntry = new Vector();
}
unknownEntry.addElement(token);
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
catalog.getCatalogManager().debug.message(1, "Invalid catalog entry", token);
unknownEntry = null;
}
}
}
}
/**
* The destructor.
*
* Makes sure the catalog file is closed.
*/
protected void finalize() {
if (catfile != null) {
try {
catfile.close();
} catch (IOException e) {
// whatever...
}
}
catfile = null;
}
// -----------------------------------------------------------------
/**
* Return the next token in the catalog file.
*
* @return The Catalog file token from the input stream.
* @throws IOException If an error occurs reading from the stream.
*/
protected String nextToken() throws IOException {
String token = "";
int ch, nextch;
if (!tokenStack.empty()) {
return (String) tokenStack.pop();
}
// Skip over leading whitespace and comments
while (true) {
// skip leading whitespace
ch = catfile.read();
while (ch <= ' ') { // all ctrls are whitespace
ch = catfile.read();
if (ch < 0) {
return null;
}
}
// now 'ch' is the current char from the file
nextch = catfile.read();
if (nextch < 0) {
return null;
}
if (ch == '-' && nextch == '-') {
// we've found a comment, skip it...
ch = ' ';
nextch = nextChar();
while (ch != '-' || nextch != '-') {
ch = nextch;
nextch = nextChar();
}
// Ok, we've found the end of the comment,
// loop back to the top and start again...
} else {
stack[++top] = nextch;
stack[++top] = ch;
break;
}
}
ch = nextChar();
if (ch == '"' || ch == '\'') {
int quote = ch;
while ((ch = nextChar()) != quote) {
char[] chararr = new char[1];
chararr[0] = (char) ch;
String s = new String(chararr);
token = token.concat(s);
}
return token;
} else {
// return the next whitespace or comment delimited
// string
while (ch > ' ') {
nextch = nextChar();
if (ch == '-' && nextch == '-') {
stack[++top] = ch;
stack[++top] = nextch;
return token;
} else {
char[] chararr = new char[1];
chararr[0] = (char) ch;
String s = new String(chararr);
token = token.concat(s);
ch = nextch;
}
}
return token;
}
}
/**
* Return the next logical character from the input stream.
*
* @return The next (logical) character from the input stream. The
* character may be buffered from a previous lookahead.
*
* @throws IOException If an error occurs reading from the stream.
*/
protected int nextChar() throws IOException {
if (top < 0) {
return catfile.read();
} else {
return stack[top--];
}
}
}