001: package com.protomatter.util;
002:
003: /**
004: * {{{ The Protomatter Software License, Version 1.0
005: * derived from The Apache Software License, Version 1.1
006: *
007: * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
008: *
009: * Redistribution and use in source and binary forms, with or without
010: * modification, are permitted provided that the following conditions
011: * are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution,
022: * if any, must include the following acknowledgment:
023: * "This product includes software developed for the
024: * Protomatter Software Project
025: * (http://protomatter.sourceforge.net/)."
026: * Alternately, this acknowledgment may appear in the software itself,
027: * if and wherever such third-party acknowledgments normally appear.
028: *
029: * 4. The names "Protomatter" and "Protomatter Software Project" must
030: * not be used to endorse or promote products derived from this
031: * software without prior written permission. For written
032: * permission, please contact support@protomatter.com.
033: *
034: * 5. Products derived from this software may not be called "Protomatter",
035: * nor may "Protomatter" appear in their name, without prior written
036: * permission of the Protomatter Software Project
037: * (support@protomatter.com).
038: *
039: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
040: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
041: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
042: * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
043: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
044: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
045: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
046: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
047: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
048: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
049: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
050: * SUCH DAMAGE. }}}
051: */
052:
053: import java.io.*;
054: import java.util.*;
055:
056: /**
057: * A Properties object that allows in-line file imports.
058: * This is just like java.util.Properties, except that
059: * it honors the following directives:<P>
060: *
061: * <blockquote><tt>Import <i>filename</i></tt></blockquote><P>
062: *
063: * Which imports the given filename in place (imported files can
064: * also have imports, but circular refs are <b>NOT</b> checked).
065: */
066: public class ProtoProperties extends Properties {
067: /**
068: * Create a blank properties object with nothing defined.
069: *
070: * @see java.util.Properties
071: */
072: public ProtoProperties() {
073: super ();
074: }
075:
076: /**
077: * Create a properties object with the given default settings.
078: *
079: * @see java.util.Properties
080: */
081: public ProtoProperties(Properties props) {
082: super (props);
083: }
084:
085: public synchronized void load(InputStream in) throws IOException {
086: read(new BufferedReader(new InputStreamReader(in)));
087: }
088:
089: /**
090: * Read lines from the given buffered reader and append them
091: * to the given vector.
092: */
093: private void read(BufferedReader reader) throws IOException {
094: String line = null;
095: while (true) {
096: if (line == null)
097: line = reader.readLine();
098: if (line == null)
099: return;
100:
101: if ((line.length() > 0) && (line.charAt(0) != '#')) {
102: if (line.startsWith("Import ")) {
103: String file = line.substring(7); // "Import ".length()
104: read(new BufferedReader(new FileReader(new File(
105: file))));
106: line = null; // don't re-use this line.
107: } else if (line.charAt(line.length() - 1) == '\\') {
108: line = line.substring(0, line.length() - 1);
109: StringBuffer b = new StringBuffer();
110: b.append(line);
111:
112: boolean done = false;
113: while (!done) {
114: line = reader.readLine();
115: if (line != null)
116: line = line.trim();
117: if (line == null || line.length() == 0) {
118: line = null; // don't re-use this line
119: done = true;
120: } else if (line.charAt(0) == '#') // comment (skip)
121: {
122: ; // no-op
123: } else {
124: if (line.charAt(line.length() - 1) == '\\') {
125: line = line.substring(0,
126: line.length() - 1);
127: b.append(line);
128: } else {
129: b.append(line);
130: line = null; // don't re-use this line
131: done = true;
132: }
133: }
134: }
135:
136: addProp(b.toString());
137: } else // "normal" line
138: {
139: addProp(line);
140: line = null;
141: }
142: } else {
143: line = null; // want to read the next line.
144: }
145: }
146: }
147:
148: private void addProp(String line) {
149: int index = line.indexOf("=");
150: if (index != -1) {
151: String key = line.substring(0, index).trim();
152: String val = line.substring(index + 1).trim();
153: put(key, val);
154: }
155: }
156:
157: /**
158: * A simple test program that reads a properties file defined as the
159: * first command-line argument, and then lists the properties to
160: * Standard Out.
161: */
162: public static void main(String args[]) {
163: if (args.length != 1) {
164: System.out
165: .println("Usage: com.protomatter.util.ProtoProperties file");
166: System.exit(0);
167: }
168: try {
169: Properties p = new ProtoProperties();
170: p.load(new FileInputStream(new File(args[0])));
171:
172: Enumeration e = p.keys();
173: while (e.hasMoreElements()) {
174: String key = (String) e.nextElement();
175: String val = p.getProperty(key);
176: System.out.println("'" + key + "' = '" + val + "'");
177: System.out.println("");
178: }
179: } catch (Exception x) {
180: x.printStackTrace();
181: }
182: }
183: }
|