org.drools.util.ChainedProperties Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of knowledge-api Show documentation
Show all versions of knowledge-api Show documentation
The Drools and jBPM public API which is backwards compatible between releases.
The newest version!
/*
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.drools.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Externalizable;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Priority
*
* System properties, home directory, working directory, META-INF/ of optionally provided classLoader
* META-INF/ of Thread.currentThread().getContextClassLoader() and META-INF/ of ClassLoader.getSystemClassLoader()
*/
public class ChainedProperties
implements
Externalizable {
protected static final transient Logger logger = LoggerFactory.getLogger(ChainedProperties.class);
private List props;
private List defaultProps;
public ChainedProperties() {
}
public ChainedProperties(String confFileName, ClassLoader classLoader) {
this( confFileName,
classLoader,
true );
}
public ChainedProperties(String confFileName,
ClassLoader classLoader,
boolean populateDefaults) {
this.props = new ArrayList();
this.defaultProps = new ArrayList();
// Properties added in precedence order
// System defined properties always get precedence
addProperties( System.getProperties() );
// System property defined properties file
loadProperties( System.getProperty( "drools." + confFileName ),
this.props );
// User home properties file
loadProperties( System.getProperty( "user.home" ) + "/drools." + confFileName,
this.props );
// Working directory properties file
loadProperties( "drools." + confFileName,
this.props );
// if ( classLoader == null ) {
// classLoader = Thread.currentThread().getContextClassLoader();
// if ( classLoader == null ) {
// classLoader = cls.getClassLoader();
// }
// }
// check META-INF directories for all known ClassLoaders
ClassLoader confClassLoader = classLoader;
loadProperties( getResources( "META-INF/drools." + confFileName,
confClassLoader ),
this.props );
loadProperties( getResources( "/META-INF/drools." + confFileName,
confClassLoader ),
this.props );
confClassLoader = ClassLoader.getSystemClassLoader();
if ( confClassLoader != null && confClassLoader != classLoader ) {
loadProperties( getResources( "META-INF/drools." + confFileName,
confClassLoader ),
this.props );
loadProperties( getResources( "/META-INF/drools." + confFileName,
confClassLoader ),
this.props );
}
if ( !populateDefaults ) {
return;
}
// load defaults
confClassLoader = classLoader;
loadProperties( getResources( "META-INF/drools.default." + confFileName,
confClassLoader ),
this.defaultProps );
loadProperties( getResources( "/META-INF/drools.default." + confFileName,
confClassLoader ),
this.defaultProps );
confClassLoader = ClassLoader.getSystemClassLoader();
if ( confClassLoader != null && confClassLoader != classLoader ) {
loadProperties( getResources( "META-INF/drools.default." + confFileName,
confClassLoader ),
this.defaultProps );
loadProperties( getResources( "/META-INF/drools.default." + confFileName,
confClassLoader ),
this.defaultProps );
}
}
@SuppressWarnings("unchecked")
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
props = (List) in.readObject();
defaultProps = (List) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( props );
out.writeObject( defaultProps );
}
private Enumeration getResources(String name,
ClassLoader classLoader) {
Enumeration enumeration = null;
try {
enumeration = classLoader.getResources( name );
} catch ( IOException e ) {
logger.error("error", e);
}
return enumeration;
}
/**
* Specifically added properties take priority, so they go to the front of the list.
* @param properties
*/
public void addProperties(Properties properties) {
this.props.add( 0, properties );
}
public String getProperty(String key,
String defaultValue) {
String value = null;
for ( Properties props : this.props ) {
value = props.getProperty( key );
if ( value != null ) {
break;
}
}
if ( value == null ) {
for ( Properties props : this.defaultProps ) {
value = props.getProperty( key );
if ( value != null ) {
break;
}
}
}
return (value != null) ? value : defaultValue;
}
public void mapStartsWith(Map map,
String startsWith,
boolean includeSubProperties) {
for ( Properties props : this.props ) {
mapStartsWith( map,
props,
startsWith,
includeSubProperties );
}
for ( Properties props : this.defaultProps ) {
mapStartsWith( map,
props,
startsWith,
includeSubProperties );
}
}
private void mapStartsWith(Map map,
Properties properties,
String startsWith,
boolean includeSubProperties) {
Enumeration< ? > enumeration = properties.propertyNames();
while ( enumeration.hasMoreElements() ) {
String key = (String) enumeration.nextElement();
if ( key.startsWith( startsWith ) ) {
if ( !includeSubProperties && key.substring( startsWith.length() + 1 ).indexOf( '.' ) > 0 ) {
// +1 to the length, as we do allow the direct property, just not ones below it
// This key has sub properties beyond the given startsWith, so skip
continue;
}
if ( !map.containsKey( key ) ) {
map.put( key,
properties.getProperty( key ) );
}
}
}
}
private void loadProperties(Enumeration enumeration,
List chain) {
if ( enumeration == null ) {
return;
}
while ( enumeration.hasMoreElements() ) {
URL url = (URL) enumeration.nextElement();
loadProperties( url,
chain );
}
}
private void loadProperties(String fileName,
List chain) {
if ( fileName != null ) {
File file = new File( fileName );
if ( file != null && file.exists() ) {
try {
loadProperties( file.toURL(),
chain );
} catch ( MalformedURLException e ) {
throw new IllegalArgumentException( "file.toURL() failed for " + fileName + " properties value '" + file + "'" );
}
} else {
//throw new IllegalArgumentException( fileName + " is specified but cannot be found '" + file + "'" );
}
}
}
private void loadProperties(URL confURL,
List chain) {
if ( confURL == null ) {
return;
}
Properties properties = new Properties();
try {
java.io.InputStream is = confURL.openStream();
properties.load( is );
is.close();
chain.add( properties );
} catch ( IOException e ) {
//throw new IllegalArgumentException( "Invalid URL to properties file '" + confURL.toExternalForm() + "'" );
}
}
}