📄 configreader.java
字号:
/**
* The contents of this file are subject to the OAA Community Research
* 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.ai.sri.com/~oaa/. Software distributed under the License
* is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific language governing
* rights and limitations under the License. Portions of the software are
* Copyright (c) SRI International, 1999-2003. All rights reserved.
* "OAA" is a registered trademark, and "Open Agent Architecture" is a
* trademark, of SRI International, a California nonprofit public benefit
* corporation.
*/
package com.sri.oaa2.agt.startit;
import java.util.*;
import java.io.*;
public class ConfigReader {
private LineReader topLevelreader;
private String line;
private String token1;
private String rest;
private HashSet includedFilenames = new HashSet();
public ConfigReader(String filename) throws FileNotFoundException {
topLevelreader = new LineReader(filename);
}
private LineReader getReader() {
return topLevelreader.getReader();
}
/** Reads a single line, ignoring blank lines and comments, and
* piecing together multiple lines as one, if lines end in
* backslash.
*
* Calls may then be made to getFirstToken(), getNextToken(), etc.
*/
public boolean readLine() {
line = topLevelreader.readLine();
if (line == null) return false;
rest = line;
token1 = splitRest();
if (token1.equals("include")) {
if (includedFilenames.contains(rest)) {
printError("File include loop detected");
}
else {
getReader().include(rest);
}
return readLine();
}
return true;
}
public String getWholeLine() {
return nonNull(line);
}
/** Always returns the first token on a line, even on subsequent calls
*/
public String getFirstToken() {
return nonNull(token1);
}
/** Unlike getFirstToken(), subsequent calls to getNextToken()
* progressively return the next token (ie. first call returns 2nd
* token, next returns 3rd, etc.
*/
public String getNextToken() {
return splitRest();
}
/** Returns everything left over on the line not yet returned by
* getFirstToken() or getNextToken()
*/
public String getRest() {
if (rest != null && rest.startsWith("\"")) {
return concat(getRemainingTokens());
}
else return nonNull(rest);
}
public Vector/*String*/ getRemainingTokens() {
Vector toks = new Vector();
String s;
do {
s = splitRest();
if (s != null) toks.add(s);
}
while (s != null);
return toks;
}
// returns the next token, AND updates the rest variable
private String splitRest() {
if (rest == null) return null;
// the messy case - start with quote, find its matching end quote,
// allowing for escaped (backslash) quotes along the way
if (rest.startsWith("\"")) {
String tok;
int end = 0;
do {
end = rest.indexOf('"', end+1);
}
// keep going if it's preceded by an escape char (\)
while (rest.charAt(end-1) == '\\');
if (end == 1) { // a pair of double-quotes with nothing between ("")
tok = "";
}
else { // return what's btwn the quotes, but also replace the escaped
// quotes (\") sans escape char (")
tok = rest.substring(1, end).replaceAll("\\\\\"", "\"");
}
if (end+1 == rest.length()) { // we ran off the end of the line
rest = null;
}
else {
rest = rest.substring(end+1).trim();
}
return nonNull(tok);
}
// the easy case - not quotes - just split by white space
else {
String[] lineArr = rest.split("[ \t]+", 2); // only split into 2 Strings max
rest = (lineArr.length == 1) ? null : lineArr[1];
return nonNull(lineArr[0]);
}
}
private String nonNull(String s) {
return (s == null ? "" : s);
}
private String concat(Vector v) {
StringBuffer buf = new StringBuffer();
for(Iterator i = v.iterator(); i.hasNext(); ) {
buf.append((String) i.next());
}
return nonNull(buf.toString());
}
public void printWarning(String msg) {
System.err.println("WARNING: " + getReader().getInfo() + ": " + msg);
}
public void printError(String msg) {
System.err.println("ERROR: " + getReader().getInfo() + ": " + msg);
}
public class LineReader {
private String filename;
private BufferedReader reader;
private LineReader includedReader = null;
private int lineNumber = 0;
public LineReader(String fn) throws FileNotFoundException {
filename = fn;
reader = new BufferedReader(new FileReader(filename));
includedFilenames.add(fn);
}
public LineReader getReader() {
if (includedReader != null) return includedReader.getReader();
else return this;
}
public String getInfo() {
return filename + ", line " + lineNumber;
}
public void include(String fn) {
try {
includedReader = new LineReader(fn);
}
catch (FileNotFoundException e) {
printError("Couldn't include file: " + e);
}
}
public String readLine() {
String line;
if (includedReader != null) {
line = includedReader.readLine();
if (line != null) {
return line;
}
else { // includedReader is all done (returned null)
includedFilenames.remove(includedReader.filename);
includedReader = null;
}
}
try {
do {
line = reader.readLine().trim();
lineNumber++;
// if it ends in a backslash it's to-be-continued, so...
while (line.endsWith("\\")) {
line = line.substring(0, line.length()-1) + // ...truncate final backslash
" " + // insert a single space
reader.readLine().trim(); // and tack on next line.
lineNumber++;
}
}
// if it was a comment line or blank line, skip it and keep reading
while (line.startsWith("#") || line.matches("^[ \t]*$"));
}
catch(NullPointerException e) { // line was null, so we're done
return null;
}
catch(IOException e) { // don't expect this to happen...
System.out.println(e);
return null;
}
return line;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -