All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drools.util.ChainedProperties Maven / Gradle / Ivy

There is a newer version: 5.1.1
Show newest version
package org.drools.util;

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()
 * @author mproctor
 *
 */
public class ChainedProperties
    implements
    Externalizable {

    private List props;
    private List defaultProps;

    public ChainedProperties() {
    }

    public ChainedProperties(String confFileName) {
        this( null,
              confFileName );
    }

    public ChainedProperties(ClassLoader classLoader,
                             String confFileName) {
        this( classLoader,
              confFileName,
              true );
    }

    public ChainedProperties(ClassLoader classLoader,
                             String confFileName,
                             boolean populateDefaults) {
        if ( classLoader == null ) {
            classLoader = Thread.currentThread().getContextClassLoader();
            if ( classLoader == null ) {
                classLoader = this.getClass().getClassLoader();
            }
        }

        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 );

        // check META-INF directories for all known ClassLoaders
        ClassLoader confClassLoader = classLoader;
        if ( confClassLoader != null ) {
            loadProperties( getResources( "META-INF/drools." + confFileName,
                                          confClassLoader ),
                            this.props );
        }

        confClassLoader = getClass().getClassLoader();
        if ( confClassLoader != null && confClassLoader != classLoader ) {
            loadProperties( getResources( "META-INF/drools." + confFileName,
                                          confClassLoader ),
                            this.props );
        }

        confClassLoader = Thread.currentThread().getContextClassLoader();
        if ( confClassLoader != null && confClassLoader != classLoader ) {
            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 );
        }

        if ( !populateDefaults ) {
            return;
        }

        // load defaults
        confClassLoader = classLoader;
        if ( confClassLoader != null ) {
            loadProperties( getResources( "META-INF/drools.default." + confFileName,
                                          confClassLoader ),
                            this.defaultProps );
        }

        confClassLoader = getClass().getClassLoader();
        if ( confClassLoader != null && confClassLoader != classLoader ) {
            loadProperties( getResources( "META-INF/drools.default." + confFileName,
                                          confClassLoader ),
                            this.defaultProps );
        }

        confClassLoader = Thread.currentThread().getContextClassLoader();
        if ( confClassLoader != null && confClassLoader != classLoader ) {
            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 );
        }
    }

    @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 ) {
            e.printStackTrace();
        }
        return enumeration;
    }

    public void addProperties(Properties properties) {
        this.props.add( 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 {
            properties.load( confURL.openStream() );
            chain.add( properties );
        } catch ( IOException e ) {
            //throw new IllegalArgumentException( "Invalid URL to properties file '" + confURL.toExternalForm() + "'" );
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy