001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.util;
027:
028: import java.io.BufferedReader;
029: import java.io.File;
030: import java.io.FileInputStream;
031: import java.io.IOException;
032: import java.io.InputStream;
033: import java.io.InputStreamReader;
034: import java.util.HashMap;
035: import java.util.Map;
036:
037: import org.cougaar.bootstrap.SystemProperties;
038: import org.cougaar.util.log.Logging;
039: import org.cougaar.util.log.Logger;
040:
041: /**
042: * COUGAAR Parameter String utilities.
043: *
044: * @see #findParameter(String,Map) for parameter lookup details
045: *
046: * @property user.home Used to find .cougaarrc.
047: */
048: public class Parameters {
049:
050: private static HashMap parameterMap = new HashMap(89);
051:
052: static {
053: // initialize parameter map from
054: // "$HOME/.cougaarrc" and "./cougaar.rc"
055:
056: String home = SystemProperties.getProperty("user.home");
057: boolean found = false;
058:
059: try {
060: File f = new File(home + File.separator + ".cougaarrc");
061: if (!f.exists()) {
062: // System.err.println("Warning: no \""+f+"\"");
063: } else {
064: parseParameterStream(f.toString(), new FileInputStream(
065: f));
066: found = true;
067: }
068: } catch (IOException e) {
069: e.printStackTrace();
070: }
071:
072: try {
073: InputStream in = ConfigFinder.getInstance().open(
074: "cougaar.rc");
075: if (in != null) {
076: parseParameterStream("cougaar.rc", in);
077: found = true;
078: }
079: } catch (IOException e) {
080: //e.printStackTrace();
081: }
082: if (!found) {
083: Logger log = Logging.getLogger(Parameters.class);
084: if (log.isInfoEnabled()) {
085: log
086: .info("Found no source for (Database) Parameters"
087: + " - looked for ~/.cougaarrc or [ConfigPath]/cougaar.rc"
088: + " (see doc/OnlineManual/DataAccess.html)");
089: }
090: }
091: }
092:
093: private static String OPEN = "${";
094: private static String CLOSE = "}";
095:
096: private static void parseParameterStream(String sname,
097: InputStream in) throws IOException {
098: BufferedReader br = new BufferedReader(
099: new InputStreamReader(in));
100: int l = 0;
101: String line;
102: while ((line = br.readLine()) != null) {
103: l++;
104: line = line.trim();
105: if (line.startsWith("#") || line.startsWith(";")
106: || line.length() == 0)
107: continue;
108: try {
109: int i = line.indexOf("=");
110: String param = line.substring(0, i).trim();
111: String value = line.substring(i + 1).trim();
112: // don't overwrite values - first wins forever
113: if (parameterMap.get(param) == null)
114: parameterMap.put(param, value);
115: } catch (RuntimeException re) {
116: System.err.println("Badly formed line in \"" + sname
117: + "\" (" + l + "):\n" + line);
118: }
119: }
120: br.close();
121: }
122:
123: /**
124: * Replace occurances of ${PARAM} in the argument with the result
125: * of calling findParameter("PARAM");
126: * Note: this is ugly, slow, inflexible and wastes lots of memory.
127: * This code handles recursive expansions, but not nested parameter references.
128: * Example: "${FOO}" -> "This is a ${BAR}" -> "This is a test"
129: * but not "${FOO:${BAR}}"
130: */
131: public static String replaceParameters(String arg, Map map) {
132: if (arg == null)
133: return null;
134: if (arg.indexOf(OPEN) == -1)
135: return arg; // bail out quickly
136:
137: StringBuffer buf = new StringBuffer(arg);
138: int i;
139: int l = buf.length();
140: while ((i = sbIndexOf(buf, OPEN, 0, l)) != -1) {
141: int j = sbIndexOf(buf, CLOSE, i + 2, l);
142: if (j == -1) {
143: throw new RuntimeException("Unclosed Parameter in '"
144: + buf + "'");
145: }
146: String name = buf.substring(i + 2, j);
147: String param = findParameter(name, map);
148: if (param == null) {
149: throw new RuntimeException(
150: "Cannot find value for parameter '" + name
151: + "'");
152: }
153: buf.replace(i, j + 1, param);
154: l = buf.length();
155: }
156: return buf.toString();
157: }
158:
159: /**
160: * @see #replaceParameters(String,Map) where the "map" is null
161: */
162: public static String replaceParameters(String arg) {
163: return replaceParameters(arg, null);
164: }
165:
166: /** find a string pattern in the buffer, returning -1 if not found. **/
167: private static int sbIndexOf(StringBuffer buf, String pat, int s,
168: int e) {
169: int pl = pat.length();
170: int f = 0;
171: for (int p = s; p < e; p++) {
172: if (buf.charAt(p) == pat.charAt(f)) {
173: f++;
174: if (f == pl)
175: return (p - f + 1);
176: } else {
177: f = 0;
178: }
179: }
180: return -1;
181: }
182:
183: /**
184: * Look in various places for the value of a parameter.
185: * <p>
186: * The parameter may be specifed in the form "NAME" or
187: * "NAME:DEFAULT", where "DEFAULT" is the default value.
188: * <p>
189: * The NAME will be looked up in this order:
190: * <ol>
191: * <li>the passed-in parameter table (if supplied)</li>
192: * <li>the System properties</li>
193: * <li>the "$HOME/.cougaarrc" (if that file exists)</li>
194: * <li>the "./cougaar.rc" (if that file exists)</li>
195: * <li>the DEFAULT value (if "NAME:DEFAULT" is used)</li>
196: * <li>lastly, if the NAME is not found in any of the above
197: * cases, <tt>null</tt> will be returned.</li>
198: * </ol>
199: */
200: public static String findParameter(String param, Map map) {
201: // parse "name:default"
202: String defval = null;
203: int di = param.indexOf(":");
204: if (di > -1) {
205: defval = param.substring(di + 1);
206: param = param.substring(0, di);
207: }
208:
209: // check the given map argument
210: if (map != null) {
211: Object o = map.get(param);
212: if (o != null)
213: return o.toString();
214: }
215:
216: // check the System properties
217: String v = SystemProperties.getProperty(param);
218: if (v != null && v.length() > 0)
219: return v;
220:
221: // check our parameter map
222: if (parameterMap != null) {
223: Object o = parameterMap.get(param);
224: if (o != null)
225: return o.toString();
226: }
227:
228: // use the default value if specified
229: if (defval != null)
230: return defval;
231:
232: return null;
233: }
234:
235: /**
236: * @see #findParameter(String,Map) where the "map" is null
237: */
238: public static String findParameter(String param) {
239: return findParameter(param, null);
240: }
241: }
|