Coverage Report - org.apache.onami.configuration.ConfigurationModule
 
Classes in this File Line Coverage Branch Coverage Complexity
ConfigurationModule
78%
48/61
78%
11/14
1.875
ConfigurationModule$1
100%
4/4
N/A
1.875
 
 1  
 package org.apache.onami.configuration;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import static com.google.inject.name.Names.named;
 23  
 import static java.lang.String.format;
 24  
 import static org.apache.onami.configuration.PropertiesIterator.newPropertiesIterator;
 25  
 
 26  
 import java.io.File;
 27  
 import java.net.MalformedURLException;
 28  
 import java.net.URI;
 29  
 import java.net.URL;
 30  
 import java.util.Iterator;
 31  
 import java.util.LinkedList;
 32  
 import java.util.List;
 33  
 import java.util.Map;
 34  
 import java.util.Map.Entry;
 35  
 import java.util.Properties;
 36  
 
 37  
 import org.apache.onami.configuration.binder.PropertyValueBindingBuilder;
 38  
 import org.apache.onami.configuration.binder.XMLPropertiesFormatBindingBuilder;
 39  
 
 40  
 import com.google.inject.AbstractModule;
 41  
 import com.google.inject.ProvisionException;
 42  
 
 43  
 /**
 44  
  * The ConfigurationModule simplifies the task of loading configurations in Google Guice.
 45  
  */
 46  962
 public abstract class ConfigurationModule
 47  
     extends AbstractModule
 48  
 {
 49  
 
 50  
     /**
 51  
      * The environment variable prefix, {@code env.}
 52  
      */
 53  
     private static final String ENV_PREFIX = "env.";
 54  
 
 55  
     /**
 56  
      * The {@code classpath} URL scheme constant
 57  
      */
 58  
     private static final String CLASSPATH_SCHEME = "classpath";
 59  
 
 60  
     private List<PropertiesURLReader> readers;
 61  
 
 62  
     @Override
 63  
     protected final void configure()
 64  
     {
 65  4
         if ( readers != null )
 66  
         {
 67  0
             throw new IllegalStateException( "Re-entry not allowed" );
 68  
         }
 69  
 
 70  4
         readers = new LinkedList<PropertiesURLReader>();
 71  
 
 72  4
         bindConfigurations();
 73  
 
 74  
         try
 75  
         {
 76  4
             for ( PropertiesURLReader reader : readers )
 77  
             {
 78  
                 try
 79  
                 {
 80  20
                     bindProperties( reader.readConfiguration() );
 81  
                 }
 82  0
                 catch ( Exception e )
 83  
                 {
 84  0
                     addError( "An error occurred while reading properties from '%s': %s", reader.getUrl(),
 85  
                               e.getMessage() );
 86  40
                 }
 87  
             }
 88  
         }
 89  
         finally
 90  
         {
 91  4
             readers = null;
 92  4
         }
 93  4
     }
 94  
 
 95  
     /**
 96  
      *
 97  
      */
 98  
     protected abstract void bindConfigurations();
 99  
 
 100  
     /**
 101  
      * Binds to a property with the given name.
 102  
      *
 103  
      * @param name The property name
 104  
      * @return The property value binder
 105  
      */
 106  
     protected PropertyValueBindingBuilder bindProperty( final String name )
 107  
     {
 108  480
         checkNotNull( name, "Property name cannot be null." );
 109  
 
 110  480
         return new PropertyValueBindingBuilder()
 111  480
         {
 112  
 
 113  
             public void toValue( final String value )
 114  
             {
 115  480
                 checkNotNull( value, "Null value not admitted for property '%s's", name );
 116  
 
 117  480
                 bindConstant().annotatedWith( named( name ) ).to( value );
 118  480
             }
 119  
 
 120  
         };
 121  
     }
 122  
 
 123  
     /**
 124  
      *
 125  
      * @param properties
 126  
      * @return
 127  
      */
 128  
     protected void bindProperties( Properties properties )
 129  
     {
 130  24
         checkNotNull( properties, "Parameter 'properties' must be not null" );
 131  
 
 132  24
         bindProperties( newPropertiesIterator( properties ) );
 133  24
     }
 134  
 
 135  
     /**
 136  
      *
 137  
      * @param properties
 138  
      */
 139  
     protected void bindProperties( Iterable<Entry<String, String>> properties )
 140  
     {
 141  0
         checkNotNull( properties, "Parameter 'properties' must be not null" );
 142  
 
 143  0
         bindProperties( properties.iterator() );
 144  0
     }
 145  
 
 146  
     /**
 147  
      *
 148  
      * @param properties
 149  
      */
 150  
     protected void bindProperties( Iterator<Entry<String, String>> properties )
 151  
     {
 152  28
         checkNotNull( properties, "Parameter 'properties' must be not null" );
 153  
 
 154  504
         while ( properties.hasNext() )
 155  
         {
 156  476
             Entry<String, String> property = properties.next();
 157  476
             bindProperty( property.getKey() ).toValue( property.getValue() );
 158  476
         }
 159  28
     }
 160  
 
 161  
     /**
 162  
      * Add the Environment Variables properties, prefixed by {@code env.}.
 163  
      */
 164  
     protected void bindSystemProperties()
 165  
     {
 166  4
         bindProperties( System.getProperties() );
 167  4
     }
 168  
 
 169  
     /**
 170  
      *
 171  
      * @param properties
 172  
      * @return
 173  
      */
 174  
     protected void bindProperties( Map<String, String> properties )
 175  
     {
 176  0
         checkNotNull( properties, "Parameter 'properties' must be not null" );
 177  
 
 178  0
         bindProperties( newPropertiesIterator( properties ) );
 179  0
     }
 180  
 
 181  
     /**
 182  
      * Add the System Variables properties.
 183  
      */
 184  
     protected void bindEnvironmentVariables()
 185  
     {
 186  4
         bindProperties( newPropertiesIterator( ENV_PREFIX, System.getenv() ) );
 187  4
     }
 188  
 
 189  
     /**
 190  
      *
 191  
      *
 192  
      * @param propertiesResource
 193  
      * @return
 194  
      */
 195  
     protected XMLPropertiesFormatBindingBuilder bindProperties( final File propertiesResource )
 196  
     {
 197  12
         checkNotNull( propertiesResource, "Parameter 'propertiesResource' must be not null" );
 198  
 
 199  12
         return bindProperties( propertiesResource.toURI() );
 200  
     }
 201  
 
 202  
     /**
 203  
      *
 204  
      *
 205  
      * @param propertiesResource
 206  
      * @return
 207  
      */
 208  
     protected XMLPropertiesFormatBindingBuilder bindProperties( final URI propertiesResource )
 209  
     {
 210  16
         checkNotNull( propertiesResource, "Parameter 'propertiesResource' must be not null" );
 211  
 
 212  16
         if ( CLASSPATH_SCHEME.equals( propertiesResource.getScheme() ) )
 213  
         {
 214  4
             String path = propertiesResource.getPath();
 215  4
             if ( propertiesResource.getHost() != null )
 216  
             {
 217  0
                 path = propertiesResource.getHost() + path;
 218  
             }
 219  4
             return bindProperties( path );
 220  
         }
 221  
 
 222  
         try
 223  
         {
 224  12
             return bindProperties( propertiesResource.toURL() );
 225  
         }
 226  0
         catch ( MalformedURLException e )
 227  
         {
 228  0
             throw new ProvisionException( format( "URI '%s' not supported: %s", propertiesResource, e.getMessage() ) );
 229  
         }
 230  
     }
 231  
 
 232  
     /**
 233  
      *
 234  
      * @param classPathResource
 235  
      * @return
 236  
      */
 237  
     protected XMLPropertiesFormatBindingBuilder bindProperties( final String classPathResource )
 238  
     {
 239  8
         return bindProperties( classPathResource, getClass().getClassLoader() );
 240  
     }
 241  
 
 242  
     /**
 243  
      *
 244  
      * @param classPathResource
 245  
      * @param classLoader
 246  
      * @return
 247  
      */
 248  
     protected XMLPropertiesFormatBindingBuilder bindProperties( final String classPathResource,
 249  
                                                                 final ClassLoader classLoader )
 250  
     {
 251  8
         checkNotNull( classPathResource, "Parameter 'classPathResource' must be not null" );
 252  8
         checkNotNull( classLoader, "Parameter 'classLoader' must be not null" );
 253  
 
 254  8
         String resourceURL = classPathResource;
 255  8
         if ( '/' == classPathResource.charAt( 0 ) )
 256  
         {
 257  4
             resourceURL = classPathResource.substring( 1 );
 258  
         }
 259  
 
 260  8
         URL url = classLoader.getResource( resourceURL );
 261  8
         checkNotNull( url,
 262  
                       "ClassPath resource '%s' not found, make sure it is in the ClassPath or you're using the right ClassLoader",
 263  
                       classPathResource );
 264  
 
 265  8
         return bindProperties( url );
 266  
     }
 267  
 
 268  
     /**
 269  
      *
 270  
      * @param propertiesResource
 271  
      * @return
 272  
      */
 273  
     protected XMLPropertiesFormatBindingBuilder bindProperties( final URL propertiesResource )
 274  
     {
 275  20
         checkNotNull( propertiesResource, "parameter 'propertiesResource' must not be null" );
 276  
 
 277  20
         PropertiesURLReader reader = new PropertiesURLReader( propertiesResource );
 278  20
         readers.add( reader );
 279  20
         return reader;
 280  
     }
 281  
 
 282  
     private static void checkNotNull( Object object, String messageFormat, Object...args )
 283  
     {
 284  1084
         if ( object == null )
 285  
         {
 286  0
             throw new IllegalArgumentException( format( messageFormat, args ) );
 287  
         }
 288  1084
     }
 289  
 
 290  
 }