📄 configuration.java
字号:
package org.apache.velocity.runtime.configuration;
/*
* Copyright (c) 2001 The Java Apache Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
* "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.commons.collections.ExtendedProperties;
/**
* This class extends normal Java properties by adding the possibility
* to use the same key many times concatenating the value strings
* instead of overwriting them.
*
* <p>The Extended Properties syntax is explained here:
*
* <ul>
* <li>
* Each property has the syntax <code>key = value</code>
* </li>
* <li>
* The <i>key</i> may use any character but the equal sign '='.
* </li>
* <li>
* <i>value</i> may be separated on different lines if a backslash
* is placed at the end of the line that continues below.
* </li>
* <li>
* If <i>value</i> is a list of strings, each token is separated
* by a comma ','.
* </li>
* <li>
* Commas in each token are escaped placing a backslash right before
* the comma.
* </li>
* <li>
* If a <i>key</i> is used more than once, the values are appended
* like if they were on the same line separated with commas.
* </li>
* <li>
* Blank lines and lines starting with character '#' are skipped.
* </li>
* <li>
* If a property is named "include" (or whatever is defined by
* setInclude() and getInclude() and the value of that property is
* the full path to a file on disk, that file will be included into
* the ConfigurationsRepository. You can also pull in files relative
* to the parent configuration file. So if you have something
* like the following:
*
* include = additional.properties
*
* Then "additional.properties" is expected to be in the same
* directory as the parent configuration file.
*
* Duplicate name values will be replaced, so be careful.
*
* </li>
* </ul>
*
* <p>Here is an example of a valid extended properties file:
*
* <p><pre>
* # lines starting with # are comments
*
* # This is the simplest property
* key = value
*
* # A long property may be separated on multiple lines
* longvalue = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
*
* # This is a property with many tokens
* tokens_on_a_line = first token, second token
*
* # This sequence generates exactly the same result
* tokens_on_multiple_lines = first token
* tokens_on_multiple_lines = second token
*
* # commas may be escaped in tokens
* commas.excaped = Hi\, what'up?
* </pre>
*
* <p><b>NOTE</b>: this class has <b>not</b> been written for
* performance nor low memory usage. In fact, it's way slower than it
* could be and generates too much memory garbage. But since
* performance is not an issue during intialization (and there is not
* much time to improve it), I wrote it this way. If you don't like
* it, go ahead and tune it up!
*
*
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
* @author <a href="mailto:daveb@miceda-data">Dave Bryson</a>
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
* @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
* @author <a href="mailto:kjohnson@transparent.com>Kent Johnson</a>
* @version $Id: Configuration.java,v 1.34 2003/05/04 17:14:37 geirm Exp $
*
* @deprecated As of version 1.1, please use ExtendedProperties from
* the Jakarta Commons Collections component.
*/
public class Configuration extends Hashtable
{
// $$$ GMJ : remove post version 1.1
// intended to help deprecate this class w/o having to modify
// the jakarta commons collections class which contains
// extended properties. We need this when someone wants to
// configure velocity w/ a Configuration : the strategy is simply
// to shadow the Configuration with the EP
private ExtendedProperties deprecationCrutch = new ExtendedProperties();
/**
* Default configurations repository.
*/
private Configuration defaults;
/**
* The file connected to this repository (holding comments and
* such).
*
* @serial
*/
protected String file;
/**
* Base path of the configuration file used to create
* this Configuration object.
*/
protected String basePath;
/**
* File separator.
*/
protected String fileSeparator = System.getProperty("file.separator");
/**
* Has this configuration been intialized.
*/
protected boolean isInitialized = false;
/**
* This is the name of the property that can point to other
* properties file for including other properties files.
*/
protected static String include = "include";
/**
* These are the keys in the order they listed
* in the configuration file. This is useful when
* you wish to perform operations with configuration
* information in a particular order.
*/
protected ArrayList keysAsListed = new ArrayList();
/**
* This class is used to read properties lines. These lines do
* not terminate with new-line chars but rather when there is no
* backslash sign a the end of the line. This is used to
* concatenate multiple lines for readability.
*/
class PropertiesReader extends LineNumberReader
{
/**
* Constructor.
*
* @param reader A Reader.
*/
public PropertiesReader(Reader reader)
{
super(reader);
}
/**
* Read a property.
*
* @return A String.
* @exception IOException.
*/
public String readProperty() throws IOException
{
StringBuffer buffer = new StringBuffer();
try
{
while (true)
{
String line = readLine().trim();
if ((line.length() != 0) && (line.charAt(0) != '#'))
{
if (line.endsWith("\\"))
{
line = line.substring(0, line.length() - 1);
buffer.append(line);
}
else
{
buffer.append(line);
break;
}
}
}
}
catch (NullPointerException e)
{
return null;
}
return buffer.toString();
}
}
/**
* This class divides into tokens a property value. Token
* separator is "," but commas into the property value are escaped
* using the backslash in front.
*/
class PropertiesTokenizer extends StringTokenizer
{
/**
* The property delimiter used while parsing (a comma).
*/
static final String DELIMITER = ",";
/**
* Constructor.
*
* @param string A String.
*/
public PropertiesTokenizer(String string)
{
super(string, DELIMITER);
}
/**
* Check whether the object has more tokens.
*
* @return True if the object has more tokens.
*/
public boolean hasMoreTokens()
{
return super.hasMoreTokens();
}
/**
* Get next token.
*
* @return A String.
*/
public String nextToken()
{
StringBuffer buffer = new StringBuffer();
while (hasMoreTokens())
{
String token = super.nextToken();
if (token.endsWith("\\"))
{
buffer.append(token.substring(0, token.length() - 1));
buffer.append(DELIMITER);
}
else
{
buffer.append(token);
break;
}
}
return buffer.toString().trim();
}
}
/**
* Creates an empty extended properties object.
*/
public Configuration ()
{
super();
}
/**
* Creates and loads the extended properties from the specified
* file.
*
* @param file A String.
* @exception IOException.
*/
public Configuration (String file) throws IOException
{
this(file,null);
}
/**
* Creates and loads the extended properties from the specified
* file.
*
* @param file A String.
* @exception IOException.
*/
public Configuration (String file, String defaultFile)
throws IOException
{
this.file = file;
basePath = new File(file).getAbsolutePath();
basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1);
this.load(new FileInputStream(file));
if (defaultFile != null)
{
defaults = new Configuration(defaultFile);
}
}
/**
* Private initializer method that sets up the generic
* resources.
*
* @exception IOException, if there was an I/O problem.
*/
private void init( Configuration exp ) throws IOException
{
isInitialized = true;
}
/**
* Indicate to client code whether property
* resources have been initialized or not.
*/
public boolean isInitialized()
{
return isInitialized;
}
/**
* Gets the property value for including other properties files.
* By default it is "include".
*
* @return A String.
*/
public String getInclude()
{
return Configuration.include;
}
/**
* Sets the property value for including other properties files.
* By default it is "include".
*
* @param inc A String.
*/
public void setInclude(String inc)
{
Configuration.include = inc;
}
/**
* Load the properties from the given input stream.
*
* @param input An InputStream.
* @exception IOException.
*/
public synchronized void load(InputStream input)
throws IOException
{
PropertiesReader reader =
new PropertiesReader(new InputStreamReader(input));
try
{
while (true)
{
String line = reader.readProperty();
int equalSign = line.indexOf('=');
if (equalSign > 0)
{
String key = line.substring(0, equalSign).trim();
String value = line.substring(equalSign + 1).trim();
/*
* Configure produces lines like this ... just
* ignore them.
*/
if ("".equals(value))
continue;
if (getInclude() != null &&
key.equalsIgnoreCase(getInclude()))
{
/*
* Recursively load properties files.
*/
File file = null;
if (value.startsWith(fileSeparator))
{
/*
* We have an absolute path so we'll
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -