📄 extendedproperties.java
字号:
* @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 (endsWithSlash(token)) {
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 ExtendedProperties() {
super();
}
/**
* Creates and loads the extended properties from the specified file.
*
* @param file the filename to load
* @throws IOException if a file error occurs
*/
public ExtendedProperties(String file) throws IOException {
this(file, null);
}
/**
* Creates and loads the extended properties from the specified file.
*
* @param file the filename to load
* @param defaultFile a second filename to load default values from
* @throws IOException if a file error occurs
*/
public ExtendedProperties(String file, String defaultFile) throws IOException {
this.file = file;
basePath = new File(file).getAbsolutePath();
basePath = basePath.substring(0, basePath.lastIndexOf(fileSeparator) + 1);
FileInputStream in = null;
try {
in = new FileInputStream(file);
this.load(in);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {}
}
if (defaultFile != null) {
defaults = new ExtendedProperties(defaultFile);
}
}
/**
* 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 include;
}
/**
* Sets the property value for including other properties files.
* By default it is "include".
*
* @param inc A String.
*/
public void setInclude(String inc) {
include = inc;
}
/**
* Load the properties from the given input stream.
*
* @param input the InputStream to load from
* @throws IOException if an IO error occurs
*/
public void load(InputStream input) throws IOException {
load(input, null);
}
/**
* Load the properties from the given input stream
* and using the specified encoding.
*
* @param input the InputStream to load from
* @param enc the encoding to use
* @throws IOException if an IO error occurs
*/
public synchronized void load(InputStream input, String enc) throws IOException {
PropertiesReader reader = null;
if (enc != null) {
try {
reader = new PropertiesReader(new InputStreamReader(input, enc));
} catch (UnsupportedEncodingException ex) {
// Another try coming up....
}
}
if (reader == null) {
try {
reader = new PropertiesReader(new InputStreamReader(input, "8859_1"));
} catch (UnsupportedEncodingException ex) {
// ISO8859-1 support is required on java platforms but....
// If it's not supported, use the system default encoding
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 use this
file = new File(value);
} else {
// We have a relative path, and we have two
// possible forms here. If we have the "./" form
// then just strip that off first before continuing.
if (value.startsWith("." + fileSeparator)) {
value = value.substring(2);
}
file = new File(basePath + value);
}
if (file != null && file.exists() && file.canRead()) {
load(new FileInputStream(file));
}
} else {
addProperty(key, value);
}
}
}
} catch (NullPointerException ex) {
// Should happen only when EOF is reached.
return;
} finally {
// Loading is initializing
isInitialized = true;
}
}
/**
* Gets a property from the configuration.
*
* @param key property to retrieve
* @return value as object. Will return user value if exists,
* if not then default value if exists, otherwise null
*/
public Object getProperty(String key) {
// first, try to get from the 'user value' store
Object obj = this.get(key);
if (obj == null) {
// if there isn't a value there, get it from the
// defaults if we have them
if (defaults != null) {
obj = defaults.get(key);
}
}
return obj;
}
/**
* Add a property to the configuration. If it already
* exists then the value stated here will be added
* to the configuration entry. For example, if
*
* <code>resource.loader = file</code>
*
* is already present in the configuration and you
*
* <code>addProperty("resource.loader", "classpath")</code>
*
* Then you will end up with a Vector like the
* following:
*
* <code>["file", "classpath"]</code>
*
* @param key the key to add
* @param value the value to add
*/
public void addProperty(String key, Object value) {
if (value instanceof String) {
String str = (String) value;
if (str.indexOf(PropertiesTokenizer.DELIMITER) > 0) {
// token contains commas, so must be split apart then added
PropertiesTokenizer tokenizer = new PropertiesTokenizer(str);
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
addPropertyInternal(key, unescape(token));
}
} else {
// token contains no commas, so can be simply added
addPropertyInternal(key, unescape(str));
}
} else {
addPropertyInternal(key, value);
}
// Adding a property connotes initialization
isInitialized = true;
}
/**
* Adds a key/value pair to the map. This routine does
* no magic morphing. It ensures the keylist is maintained
*
* @param key the key to store at
* @param value the decoded object to store
*/
private void addPropertyDirect(String key, Object value) {
// safety check
if (!containsKey(key)) {
keysAsListed.add(key);
}
put(key, value);
}
/**
* Adds a decoded property to the map w/o checking for commas - used
* internally when a property has been broken up into
* strings that could contain escaped commas to prevent
* the inadvertent vectorization.
* <p>
* Thanks to Leon Messerschmidt for this one.
*
* @param key the key to store at
* @param value the decoded object to store
*/
private void addPropertyInternal(String key, Object value) {
Object current = this.get(key);
if (current instanceof String) {
// one object already in map - convert it to a vector
Vector v = new Vector(2);
v.addElement(current);
v.addElement(value);
put(key, v);
} else if (current instanceof Vector) {
// already a vector - just add the new token
((Vector) current).addElement(value);
} else {
// brand new key - store in keysAsListed to retain order
if (!containsKey(key)) {
keysAsListed.add(key);
}
put(key, value);
}
}
/**
* Set a property, this will replace any previously
* set values. Set values is implicitly a call
* to clearProperty(key), addProperty(key,value).
*
* @param key the key to set
* @param value the value to set
*/
public void setProperty(String key, Object value) {
clearProperty(key);
addProperty(key, value);
}
/**
* Save the properties to the given output stream.
* <p>
* The stream is not closed, but it is flushed.
*
* @param output an OutputStream, may be null
* @param header a textual comment to act as a file header
* @throws IOException if an IO error occurs
*/
public synchronized void save(OutputStream output, String header) {
if (output == null) {
return;
}
PrintWriter theWrtr = new PrintWriter(output);
if (header != null) {
theWrtr.println(header);
}
Enumeration theKeys = keys();
while (theKeys.hasMoreElements()) {
String key = (String) theKeys.nextElement();
Object value = get(key);
if (value != null) {
if (value instanceof String) {
StringBuffer currentOutput = new StringBuffer();
currentOutput.append(key);
currentOutput.append("=");
currentOutput.append(escape((String) value));
theWrtr.println(currentOutput.toString());
} else if (value instanceof Vector) {
Vector values = (Vector) value;
Enumeration valuesEnum = values.elements();
while (valuesEnum.hasMoreElements()) {
String currentElement = (String) valuesEnum.nextElement();
StringBuffer currentOutput = new StringBuffer();
currentOutput.append(key);
currentOutput.append("=");
currentOutput.append(escape(currentElement));
theWrtr.println(currentOutput.toString());
}
}
}
theWrtr.println();
theWrtr.flush();
}
}
/**
* Combines an existing Hashtable with this Hashtable.
* <p>
* Warning: It will overwrite previous entries without warning.
*
* @param props the properties to combine
*/
public void combine(ExtendedProperties props) {
for (Iterator it = props.getKeys(); it.hasNext();) {
String key = (String) it.next();
setProperty(key, props.get(key));
}
}
/**
* Clear a property in the configuration.
*
* @param key the property key to remove along with corresponding value
*/
public void clearProperty(String key) {
if (containsKey(key)) {
// we also need to rebuild the keysAsListed or else
// things get *very* confusing
for (int i = 0; i < keysAsListed.size(); i++) {
if (( keysAsListed.get(i)).equals(key)) {
keysAsListed.remove(i);
break;
}
}
remove(key);
}
}
/**
* Get the list of the keys contained in the configuration
* repository.
*
* @return an Iterator over the keys
*/
public Iterator getKeys() {
return keysAsListed.iterator();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -