blob: f4a0c3ef8e13a0ab2cd04bf00e591a735b9d6b0a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.apache.commons.daemon.support;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.text.ParseException;
/**
* Used by jsvc for Daemon configuration.
* <p>
* Configuration is read from properties file.
* If no properties file is given the <code>daemon.properties</code>
* is used from the current directory.
* </p>
* <p>
* The properties file can have property values expanded at runtime
* by using System properties or execution environment. The part
* of the property value between <code>${</code> and <code>}</code>
* will be used as System property or environment key. If found then
* the entire <code>${foo}</code> will be replaced by the value of
* either system property or environment variable named <code>foo</code>.
* </p>
* <p>
* If no variable is found the <code>${foo}</code> will be passed as is.
* In case of <code>$${foo}</code> this will be unescaped and resulting
* value will be <code>${foo}</code>.
* </p>
*
* @version $Id$
* @author Mladen Turk
*/
public final class DaemonConfiguration
{
/**
* Default configuration file name.
*/
protected final static String DEFAULT_CONFIG = "daemon.properties";
/**
* Property prefix
*/
protected final static String PREFIX = "daemon.";
private final static String BTOKEN = "${";
private final static String ETOKEN = "}";
private final Properties configurationProperties;
private final Properties systemProperties;
/**
* Default constructor
*/
public DaemonConfiguration()
{
configurationProperties = new Properties();
systemProperties = System.getProperties();
}
/**
* Loads the configuration properties file.
*
* @param fileName The properties file to load.
* @return <code>true</code> if the file was loaded.
*/
public boolean load(String fileName)
{
boolean ok = false;
FileInputStream file = null;
try {
if (fileName == null) {
fileName = DEFAULT_CONFIG;
}
file = new FileInputStream(fileName);
configurationProperties.clear();
configurationProperties.load(file);
ok = true;
}
catch (FileNotFoundException ex) {
// fileName does not exist
}
catch (IOException ex) {
// Error reading properties file
} finally {
try {
if (file != null) {
file.close();
}
} catch (IOException ex) {
}
}
return ok;
}
private String expandProperty(String propValue)
throws ParseException
{
StringBuffer expanded;
int btoken;
int ctoken = 0;
if (propValue == null)
return null;
expanded = new StringBuffer();
btoken = propValue.indexOf(BTOKEN);
while (btoken != -1) {
if (btoken > 0 && propValue.charAt(btoken - 1) == BTOKEN.charAt(0)) {
// Skip and unquote.
expanded.append(propValue.substring(ctoken, btoken));
ctoken = btoken + 1;
btoken = propValue.indexOf(BTOKEN, btoken + BTOKEN.length());
continue;
}
int etoken = propValue.indexOf(ETOKEN, btoken);
if (etoken != -1) {
String variable = propValue.substring(btoken + BTOKEN.length(), etoken);
String sysvalue = systemProperties.getProperty(variable);
if (sysvalue == null) {
// Try with the environment if there was no
// property by that name.
sysvalue = System.getenv(variable); // N.B. Deprecated in Java 1.3/1.4, but re-instated in Java 1.5+
}
if (sysvalue != null) {
String strtoken = propValue.substring(ctoken, btoken);
expanded.append(strtoken);
expanded.append(sysvalue);
ctoken = etoken + ETOKEN.length();
}
}
else {
// We have "${" without "}"
throw new ParseException("Error while looking for teminating '" +
ETOKEN + "'", btoken);
}
btoken = propValue.indexOf(BTOKEN, etoken + ETOKEN.length());
}
// Add what's left.
expanded.append(propValue.substring(ctoken, propValue.length()));
return expanded.toString();
}
/**
* Gets the configuration property.
*
* @param name The name of the property to get.
*
* @throws ParseException if the property is wrongly formatted.
*/
public String getProperty(String name)
throws ParseException
{
if (name == null) {
return null;
}
return expandProperty(configurationProperties.getProperty(PREFIX + name));
}
/**
* Gets the configuration property array.
* <p>
* Property array is constructed form the lsit of properties
* which end with <code>[index]</code>
* </p>
* <pre>
* daemon.arg[0] = argument 1
* daemon.arg[1] = argument 2
* daemon.arg[2] = argument 3
* </pre>
* @param name The name of the property array to get.
*
* @throws ParseException if the property is wrongly formatted.
*/
public String[] getPropertyArray(String name)
throws ParseException
{
ArrayList list = new ArrayList();
String args;
// Load daemon.arg[0] ... daemon.arg[n] into the String array.
//
while ((args = getProperty(name + "[" + list.size() + "]")) != null) {
list.add(args);
}
return (String[])list.toArray(new String[list.size()]);
}
}