Coverage Report - org.apache.maven.archiva.configuration.DefaultArchivaConfiguration
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultArchivaConfiguration
0%
0/247
0%
0/164
0
 
 1  
 package org.apache.maven.archiva.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 org.apache.commons.collections.CollectionUtils;
 23  
 import org.apache.commons.collections.MapUtils;
 24  
 import org.apache.commons.io.FileUtils;
 25  
 import org.apache.commons.lang.StringUtils;
 26  
 import org.apache.maven.archiva.configuration.functors.ProxyConnectorConfigurationOrderComparator;
 27  
 import org.apache.maven.archiva.configuration.io.registry.ConfigurationRegistryReader;
 28  
 import org.apache.maven.archiva.configuration.io.registry.ConfigurationRegistryWriter;
 29  
 import org.apache.maven.archiva.policies.AbstractUpdatePolicy;
 30  
 import org.apache.maven.archiva.policies.CachedFailuresPolicy;
 31  
 import org.apache.maven.archiva.policies.ChecksumPolicy;
 32  
 import org.apache.maven.archiva.policies.Policy;
 33  
 import org.apache.maven.archiva.policies.PostDownloadPolicy;
 34  
 import org.apache.maven.archiva.policies.PreDownloadPolicy;
 35  
 import org.codehaus.plexus.evaluator.DefaultExpressionEvaluator;
 36  
 import org.codehaus.plexus.evaluator.EvaluatorException;
 37  
 import org.codehaus.plexus.evaluator.ExpressionEvaluator;
 38  
 import org.codehaus.plexus.evaluator.sources.SystemPropertyExpressionSource;
 39  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 40  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
 41  
 import org.codehaus.plexus.registry.Registry;
 42  
 import org.codehaus.plexus.registry.RegistryException;
 43  
 import org.codehaus.plexus.registry.RegistryListener;
 44  
 import org.slf4j.Logger;
 45  
 import org.slf4j.LoggerFactory;
 46  
 
 47  
 import java.io.File;
 48  
 import java.io.IOException;
 49  
 import java.util.ArrayList;
 50  
 import java.util.Collection;
 51  
 import java.util.Collections;
 52  
 import java.util.HashMap;
 53  
 import java.util.HashSet;
 54  
 import java.util.Iterator;
 55  
 import java.util.List;
 56  
 import java.util.Map;
 57  
 import java.util.Map.Entry;
 58  
 import java.util.Set;
 59  
 
 60  
 /**
 61  
  * <p>
 62  
  * Implementation of configuration holder that retrieves it from the registry.
 63  
  * </p>
 64  
  * <p>
 65  
  * The registry layers and merges the 2 configuration files: user, and application server.
 66  
  * </p>
 67  
  * <p>
 68  
  * Instead of relying on the model defaults, if the registry is empty a default configuration file is loaded and
 69  
  * applied from a resource. The defaults are not loaded into the registry as the lists (eg repositories) could no longer
 70  
  * be removed if that was the case.
 71  
  * </p>
 72  
  * <p>
 73  
  * When saving the configuration, it is saved to the location it was read from. If it was read from the defaults, it
 74  
  * will be saved to the user location.
 75  
  * However, if the configuration contains information from both sources, an exception is raised as this is currently
 76  
  * unsupported. The reason for this is that it is not possible to identify where to re-save elements, and can result
 77  
  * in list configurations (eg repositories) becoming inconsistent.
 78  
  * </p>
 79  
  * <p>
 80  
  * If the configuration is outdated, it will be upgraded when it is loaded. This is done by checking the version flag
 81  
  * before reading it from the registry.
 82  
  * </p>
 83  
  *
 84  
  * @plexus.component role="org.apache.maven.archiva.configuration.ArchivaConfiguration"
 85  
  */
 86  0
 public class DefaultArchivaConfiguration
 87  
     implements ArchivaConfiguration, RegistryListener, Initializable
 88  
 {
 89  0
     private Logger log = LoggerFactory.getLogger( DefaultArchivaConfiguration.class );
 90  
 
 91  
     /**
 92  
      * Plexus registry to read the configuration from.
 93  
      *
 94  
      * @plexus.requirement role-hint="commons-configuration"
 95  
      */
 96  
     private Registry registry;
 97  
 
 98  
     /**
 99  
      * The configuration that has been converted.
 100  
      */
 101  
     private Configuration configuration;
 102  
 
 103  
     /**
 104  
      * @plexus.requirement role="org.apache.maven.archiva.policies.PreDownloadPolicy"
 105  
      * @todo these don't strictly belong in here
 106  
      */
 107  
     private Map<String, PreDownloadPolicy> prePolicies;
 108  
 
 109  
     /**
 110  
      * @plexus.requirement role="org.apache.maven.archiva.policies.PostDownloadPolicy"
 111  
      * @todo these don't strictly belong in here
 112  
      */
 113  
     private Map<String, PostDownloadPolicy> postPolicies;
 114  
 
 115  
     /**
 116  
      * @plexus.configuration default-value="${user.home}/.m2/archiva.xml"
 117  
      */
 118  
     private String userConfigFilename;
 119  
 
 120  
     /**
 121  
      * @plexus.configuration default-value="${appserver.base}/conf/archiva.xml"
 122  
      */
 123  
     private String altConfigFilename;
 124  
 
 125  
     /**
 126  
      * Configuration Listeners we've registered.
 127  
      */
 128  0
     private Set<ConfigurationListener> listeners = new HashSet<ConfigurationListener>();
 129  
 
 130  
     /**
 131  
      * Registry Listeners we've registered.
 132  
      */
 133  0
     private Set<RegistryListener> registryListeners = new HashSet<RegistryListener>();
 134  
 
 135  
     /**
 136  
      * Boolean to help determine if the configuration exists as a result of pulling in
 137  
      * the default-archiva.xml
 138  
      */
 139  0
     private boolean isConfigurationDefaulted = false;
 140  
 
 141  
     private static final String KEY = "org.apache.maven.archiva";
 142  
 
 143  
     public Configuration getConfiguration()
 144  
     {
 145  0
         return loadConfiguration();
 146  
     }
 147  
 
 148  
     private synchronized Configuration loadConfiguration()
 149  
     {
 150  0
         if ( configuration == null )
 151  
         {
 152  0
             configuration = load();
 153  0
             configuration = unescapeExpressions( configuration );
 154  0
             if( isConfigurationDefaulted )
 155  
             {
 156  0
                 configuration = checkRepositoryLocations( configuration );
 157  
             }
 158  
         }
 159  
 
 160  0
         return configuration;
 161  
     }
 162  
 
 163  
     @SuppressWarnings("unchecked")
 164  
     private Configuration load()
 165  
     {   
 166  
         // TODO: should this be the same as section? make sure unnamed sections still work (eg, sys properties)
 167  0
         Registry subset = registry.getSubset( KEY );
 168  0
         if ( subset.getString( "version" ) == null )
 169  
         {
 170  
             // a little autodetection of v1, even if version is omitted (this was previously allowed)
 171  0
             if ( subset.getSubset( "repositoryScanning" ).isEmpty() )
 172  
             {
 173  
                 // only for empty, or v < 1
 174  0
                 subset = readDefaultConfiguration();
 175  
             }
 176  
         }
 177  
         
 178  0
         Configuration config = new ConfigurationRegistryReader().read( subset );        
 179  
 
 180  0
         if ( !config.getRepositories().isEmpty() )
 181  
         {
 182  0
             for ( Iterator<V1RepositoryConfiguration> i = config.getRepositories().iterator(); i.hasNext(); )
 183  
             {
 184  0
                 V1RepositoryConfiguration r = i.next();
 185  0
                 r.setScanned( r.isIndexed() );
 186  
                 
 187  0
                 if ( r.getUrl().startsWith( "file://" ) )
 188  
                 {
 189  0
                     r.setLocation( r.getUrl().substring( 7 ) );
 190  0
                     config.addManagedRepository( r );
 191  
                 }
 192  0
                 else if ( r.getUrl().startsWith( "file:" ) )
 193  
                 {
 194  0
                     r.setLocation( r.getUrl().substring( 5 ) );
 195  0
                     config.addManagedRepository( r );
 196  
                 }
 197  
                 else
 198  
                 {
 199  0
                     RemoteRepositoryConfiguration repo = new RemoteRepositoryConfiguration();
 200  0
                     repo.setId( r.getId() );
 201  0
                     repo.setLayout( r.getLayout() );
 202  0
                     repo.setName( r.getName() );
 203  0
                     repo.setUrl( r.getUrl() );
 204  0
                     config.addRemoteRepository( repo );
 205  
                 }
 206  0
             }
 207  
 
 208  
             // Prevent duplicate repositories from showing up.
 209  0
             config.getRepositories().clear();
 210  
 
 211  0
             registry.removeSubset( KEY + ".repositories" );
 212  
         }
 213  
 
 214  0
         if ( !CollectionUtils.isEmpty( config.getRemoteRepositories() ) )
 215  
         {
 216  0
             List<RemoteRepositoryConfiguration> remoteRepos = config.getRemoteRepositories();
 217  0
             for ( RemoteRepositoryConfiguration repo : remoteRepos )
 218  
             {
 219  
                 // [MRM-582] Remote Repositories with empty <username> and <password> fields shouldn't be created in configuration.
 220  0
                 if ( StringUtils.isBlank( repo.getUsername() ) )
 221  
                 {
 222  0
                     repo.setUsername( null );
 223  
                 }
 224  
 
 225  0
                 if ( StringUtils.isBlank( repo.getPassword() ) )
 226  
                 {
 227  0
                     repo.setPassword( null );
 228  
                 }
 229  
             }
 230  
         }
 231  
 
 232  0
         if ( !config.getProxyConnectors().isEmpty() )
 233  
         {
 234  
             // Fix Proxy Connector Settings.
 235  
 
 236  0
             List<ProxyConnectorConfiguration> proxyConnectorList = new ArrayList<ProxyConnectorConfiguration>();
 237  
             // Create a copy of the list to read from (to prevent concurrent modification exceptions)
 238  0
             proxyConnectorList.addAll( config.getProxyConnectors() );
 239  
             // Remove the old connector list.
 240  0
             config.getProxyConnectors().clear();
 241  
 
 242  0
             for ( ProxyConnectorConfiguration connector : proxyConnectorList )
 243  
             {
 244  
                 // Fix policies
 245  0
                 boolean connectorValid = true;
 246  
 
 247  0
                 Map<String, String> policies = new HashMap<String, String>();
 248  
                 // Make copy of policies
 249  0
                 policies.putAll( connector.getPolicies() );
 250  
                 // Clear out policies
 251  0
                 connector.getPolicies().clear();
 252  
 
 253  
                 // Work thru policies. cleaning them up.
 254  0
                 for ( Entry<String, String> entry : policies.entrySet() )
 255  
                 {
 256  0
                     String policyId = entry.getKey();
 257  0
                     String setting = entry.getValue();
 258  
 
 259  
                     // Upgrade old policy settings.
 260  0
                     if ( "releases".equals( policyId ) || "snapshots".equals( policyId ) )
 261  
                     {
 262  0
                         if ( "ignored".equals( setting ) )
 263  
                         {
 264  0
                             setting = AbstractUpdatePolicy.ALWAYS;
 265  
                         }
 266  0
                         else if ( "disabled".equals( setting ) )
 267  
                         {
 268  0
                             setting = AbstractUpdatePolicy.NEVER;
 269  
                         }
 270  
                     }
 271  0
                     else if ( "cache-failures".equals( policyId ) )
 272  
                     {
 273  0
                         if ( "ignored".equals( setting ) )
 274  
                         {
 275  0
                             setting = CachedFailuresPolicy.NO;
 276  
                         }
 277  0
                         else if ( "cached".equals( setting ) )
 278  
                         {
 279  0
                             setting = CachedFailuresPolicy.YES;
 280  
                         }
 281  
                     }
 282  0
                     else if ( "checksum".equals( policyId ) )
 283  
                     {
 284  0
                         if ( "ignored".equals( setting ) )
 285  
                         {
 286  0
                             setting = ChecksumPolicy.IGNORE;
 287  
                         }
 288  
                     }
 289  
 
 290  
                     // Validate existance of policy key.
 291  0
                     if ( policyExists( policyId ) )
 292  
                     {
 293  0
                         Policy policy = findPolicy( policyId );
 294  
                         // Does option exist?
 295  0
                         if ( !policy.getOptions().contains( setting ) )
 296  
                         {
 297  0
                             setting = policy.getDefaultOption();
 298  
                         }
 299  0
                         connector.addPolicy( policyId, setting );
 300  0
                     }
 301  
                     else
 302  
                     {
 303  
                         // Policy key doesn't exist. Don't add it to golden version.
 304  0
                         log.warn( "Policy [" + policyId + "] does not exist." );
 305  
                     }
 306  0
                 }
 307  
 
 308  0
                 if ( connectorValid )
 309  
                 {
 310  0
                     config.addProxyConnector( connector );
 311  
                 }
 312  0
             }
 313  
 
 314  
             // Normalize the order fields in the proxy connectors.
 315  0
             Map<String, java.util.List<ProxyConnectorConfiguration>> proxyConnectorMap = config
 316  
                 .getProxyConnectorAsMap();
 317  
 
 318  0
             for ( String key : proxyConnectorMap.keySet() )
 319  
             {
 320  0
                 List<ProxyConnectorConfiguration> connectors = proxyConnectorMap.get( key );
 321  
                 // Sort connectors by order field.
 322  0
                 Collections.sort( connectors, ProxyConnectorConfigurationOrderComparator.getInstance() );
 323  
 
 324  
                 // Normalize the order field values.
 325  0
                 int order = 1;
 326  0
                 for ( ProxyConnectorConfiguration connector : connectors )
 327  
                 {
 328  0
                     connector.setOrder( order++ );
 329  
                 }
 330  0
             }
 331  
         }
 332  
 
 333  0
         return config;
 334  
     }
 335  
 
 336  
     private Policy findPolicy( String policyId )
 337  
     {
 338  0
         if ( MapUtils.isEmpty( prePolicies ) )
 339  
         {
 340  0
             log.error( "No PreDownloadPolicies found!" );
 341  0
             return null;
 342  
         }
 343  
 
 344  0
         if ( MapUtils.isEmpty( postPolicies ) )
 345  
         {
 346  0
             log.error( "No PostDownloadPolicies found!" );
 347  0
             return null;
 348  
         }
 349  
 
 350  
         Policy policy;
 351  
 
 352  0
         policy = prePolicies.get( policyId );
 353  0
         if ( policy != null )
 354  
         {
 355  0
             return policy;
 356  
         }
 357  
 
 358  0
         policy = postPolicies.get( policyId );
 359  0
         if ( policy != null )
 360  
         {
 361  0
             return policy;
 362  
         }
 363  
 
 364  0
         return null;
 365  
     }
 366  
 
 367  
     private boolean policyExists( String policyId )
 368  
     {
 369  0
         if ( MapUtils.isEmpty( prePolicies ) )
 370  
         {
 371  0
             log.error( "No PreDownloadPolicies found!" );
 372  0
             return false;
 373  
         }
 374  
 
 375  0
         if ( MapUtils.isEmpty( postPolicies ) )
 376  
         {
 377  0
             log.error( "No PostDownloadPolicies found!" );
 378  0
             return false;
 379  
         }
 380  
 
 381  0
         return ( prePolicies.containsKey( policyId ) || postPolicies.containsKey( policyId ) );
 382  
     }
 383  
 
 384  
     private Registry readDefaultConfiguration()
 385  
     {
 386  
         // if it contains some old configuration, remove it (Archiva 0.9)
 387  0
         registry.removeSubset( KEY );
 388  
 
 389  
         try
 390  
         {
 391  0
             registry.addConfigurationFromResource( "org/apache/maven/archiva/configuration/default-archiva.xml", KEY );
 392  0
             this.isConfigurationDefaulted = true;
 393  
         }
 394  0
         catch ( RegistryException e )
 395  
         {
 396  0
             throw new ConfigurationRuntimeException(
 397  
                                                      "Fatal error: Unable to find the built-in default configuration and load it into the registry",
 398  
                                                      e );
 399  0
         }
 400  0
         return registry.getSubset( KEY );
 401  
     }
 402  
 
 403  
     @SuppressWarnings("unchecked")
 404  
     public synchronized void save( Configuration configuration )
 405  
         throws RegistryException, IndeterminateConfigurationException
 406  
     {
 407  0
         Registry section = registry.getSection( KEY + ".user" );
 408  0
         Registry baseSection = registry.getSection( KEY + ".base" );
 409  0
         if ( section == null )
 410  
         {
 411  0
             section = baseSection;
 412  0
             if ( section == null )
 413  
             {
 414  0
                 section = createDefaultConfigurationFile();
 415  
             }
 416  
         }
 417  0
         else if ( baseSection != null )
 418  
         {
 419  0
             Collection<String> keys = baseSection.getKeys();
 420  0
             boolean foundList = false;
 421  0
             for ( Iterator<String> i = keys.iterator(); i.hasNext() && !foundList; )
 422  
             {
 423  0
                 String key = i.next();
 424  
 
 425  
                 // a little aggressive with the repositoryScanning and databaseScanning - should be no need to split
 426  
                 // that configuration
 427  0
                 if ( key.startsWith( "repositories" ) || key.startsWith( "proxyConnectors" )
 428  
                     || key.startsWith( "networkProxies" ) || key.startsWith( "repositoryScanning" )
 429  
                     || key.startsWith( "databaseScanning" ) || key.startsWith( "remoteRepositories" )
 430  
                     || key.startsWith( "managedRepositories" ) || key.startsWith( "repositoryGroups" ) )
 431  
                 {
 432  0
                     foundList = true;
 433  
                 }
 434  0
             }
 435  
 
 436  0
             if ( foundList )
 437  
             {
 438  0
                 this.configuration = null;
 439  
 
 440  0
                 throw new IndeterminateConfigurationException(
 441  
                                                                "Configuration can not be saved when it is loaded from two sources" );
 442  
             }
 443  
         }
 444  
 
 445  
         // escape all cron expressions to handle ','
 446  0
         escapeCronExpressions( configuration );
 447  
 
 448  
         // [MRM-661] Due to a bug in the modello registry writer, we need to take these out by hand. They'll be put back by the writer.
 449  0
         if ( configuration.getManagedRepositories().isEmpty() )
 450  
         {
 451  0
             section.removeSubset( "managedRepositories" );
 452  
         }
 453  0
         if ( configuration.getRemoteRepositories().isEmpty() )
 454  
         {
 455  0
             section.removeSubset( "remoteRepositories" );
 456  
         }
 457  0
         if ( configuration.getProxyConnectors().isEmpty() )
 458  
         {
 459  0
             section.removeSubset( "proxyConnectors" );
 460  
         }
 461  0
         if ( configuration.getNetworkProxies().isEmpty() )
 462  
         {
 463  0
             section.removeSubset( "networkProxies" );
 464  
         }
 465  0
         if ( configuration.getLegacyArtifactPaths().isEmpty() )
 466  
         {
 467  0
             section.removeSubset( "legacyArtifactPaths" );
 468  
         }
 469  0
         if ( configuration.getRepositoryGroups().isEmpty() )                
 470  
         {
 471  0
             section.removeSubset( "repositoryGroups" );
 472  
         }
 473  0
         if ( configuration.getRepositoryScanning() != null )
 474  
         {
 475  0
             if ( configuration.getRepositoryScanning().getKnownContentConsumers().isEmpty() )
 476  
             {
 477  0
                 section.removeSubset( "repositoryScanning.knownContentConsumers" );
 478  
             }
 479  0
             if ( configuration.getRepositoryScanning().getInvalidContentConsumers().isEmpty() )
 480  
             {
 481  0
                 section.removeSubset( "repositoryScanning.invalidContentConsumers" );
 482  
             }
 483  
         }
 484  0
         if ( configuration.getDatabaseScanning() != null )
 485  
         {
 486  0
             if ( configuration.getDatabaseScanning().getCleanupConsumers().isEmpty() )
 487  
             {
 488  0
                 section.removeSubset( "databaseScanning.cleanupConsumers" );
 489  
             }
 490  0
             if ( configuration.getDatabaseScanning().getUnprocessedConsumers().isEmpty() )
 491  
             {
 492  0
                 section.removeSubset( "databaseScanning.unprocessedConsumers" );
 493  
             }
 494  
         }
 495  
 
 496  0
         new ConfigurationRegistryWriter().write( configuration, section );
 497  0
         section.save();
 498  
 
 499  0
         this.configuration = unescapeExpressions( configuration );
 500  
 
 501  0
         triggerEvent( ConfigurationEvent.SAVED );
 502  0
     }
 503  
 
 504  
     private void escapeCronExpressions( Configuration configuration )
 505  
     {
 506  0
         for ( ManagedRepositoryConfiguration c : (List<ManagedRepositoryConfiguration>) configuration.getManagedRepositories() )
 507  
         {
 508  0
             c.setRefreshCronExpression( escapeCronExpression( c.getRefreshCronExpression() ) );
 509  
         }
 510  
 
 511  0
         DatabaseScanningConfiguration scanning = configuration.getDatabaseScanning();
 512  0
         if ( scanning != null )
 513  
         {
 514  0
             scanning.setCronExpression( escapeCronExpression( scanning.getCronExpression() ) );
 515  
         }
 516  0
     }
 517  
 
 518  
     private Registry createDefaultConfigurationFile()
 519  
         throws RegistryException
 520  
     {
 521  
         // TODO: may not be needed under commons-configuration 1.4 - check
 522  
         // UPDATE: Upgrading to commons-configuration 1.4 breaks half the unit tests. 2007-10-11 (joakime)
 523  
 
 524  0
         String contents = "<configuration />";
 525  0
         if ( !writeFile( "user configuration", userConfigFilename, contents ) )
 526  
         {
 527  0
             if ( !writeFile( "alternative configuration", altConfigFilename, contents ) )
 528  
             {
 529  0
                 throw new RegistryException( "Unable to create configuration file in either user ["
 530  
                     + userConfigFilename + "] or alternative [" + altConfigFilename
 531  
                     + "] locations on disk, usually happens when not allowed to write to those locations." );
 532  
             }
 533  
         }
 534  
 
 535  
         try
 536  
         {
 537  0
             ( (Initializable) registry ).initialize();
 538  
 
 539  0
             for ( RegistryListener regListener : registryListeners )
 540  
             {
 541  0
                 addRegistryChangeListener( regListener );
 542  
             }
 543  
         }
 544  0
         catch ( InitializationException e )
 545  
         {
 546  0
             throw new RegistryException( "Unable to reinitialize configuration: " + e.getMessage(), e );
 547  0
         }
 548  
 
 549  0
         triggerEvent( ConfigurationEvent.SAVED );
 550  
 
 551  0
         return registry.getSection( KEY + ".user" );
 552  
     }
 553  
 
 554  
     /**
 555  
      * Attempts to write the contents to a file, if an IOException occurs, return false.
 556  
      * 
 557  
      * The file will be created if the directory to the file exists, otherwise this will return false.
 558  
      * 
 559  
      * @param filetype the filetype (freeform text) to use in logging messages when failure to write.
 560  
      * @param path the path to write to.
 561  
      * @param contents the contents to write.
 562  
      * @return true if write successful.
 563  
      */
 564  
     private boolean writeFile( String filetype, String path, String contents )
 565  
     {
 566  0
         File file = new File( path );
 567  
 
 568  
         try
 569  
         {
 570  
             // Check parent directory (if it is declared)
 571  0
             if ( file.getParentFile() != null )
 572  
             {
 573  
                 // Check that directory exists
 574  0
                 if ( ( file.getParentFile().exists() == false ) || ( file.getParentFile().isDirectory() == false ) )
 575  
                 {
 576  
                     // Directory to file must exist for file to be created
 577  0
                     return false;
 578  
                 }
 579  
             }
 580  
 
 581  0
             FileUtils.writeStringToFile( file, contents, "UTF-8" );
 582  0
             return true;
 583  
         }
 584  0
         catch ( IOException e )
 585  
         {
 586  0
             log.error( "Unable to create " + filetype + " file: " + e.getMessage(), e );
 587  0
             return false;
 588  
         }
 589  
     }
 590  
 
 591  
     private void triggerEvent( int type )
 592  
     {
 593  0
         ConfigurationEvent evt = new ConfigurationEvent( type );
 594  0
         for ( ConfigurationListener listener : listeners )
 595  
         {
 596  0
             listener.configurationEvent( evt );
 597  
         }
 598  0
     }
 599  
 
 600  
     public void addListener( ConfigurationListener listener )
 601  
     {
 602  0
         if ( listener == null )
 603  
         {
 604  0
             return;
 605  
         }
 606  
 
 607  0
         listeners.add( listener );
 608  0
     }
 609  
 
 610  
     public void removeListener( ConfigurationListener listener )
 611  
     {
 612  0
         if ( listener == null )
 613  
         {
 614  0
             return;
 615  
         }
 616  
 
 617  0
         listeners.remove( listener );
 618  0
     }
 619  
 
 620  
     public void addChangeListener( RegistryListener listener )
 621  
     {
 622  0
         addRegistryChangeListener( listener );
 623  
 
 624  
         // keep track for later
 625  0
         registryListeners.add( listener );
 626  0
     }
 627  
 
 628  
     private void addRegistryChangeListener( RegistryListener listener )
 629  
     {
 630  0
         Registry section = registry.getSection( KEY + ".user" );
 631  0
         if ( section != null )
 632  
         {
 633  0
             section.addChangeListener( listener );
 634  
         }
 635  0
         section = registry.getSection( KEY + ".base" );
 636  0
         if ( section != null )
 637  
         {
 638  0
             section.addChangeListener( listener );
 639  
         }
 640  0
     }
 641  
 
 642  
     public void initialize()
 643  
         throws InitializationException
 644  
     {
 645  
         // Resolve expressions in the userConfigFilename and altConfigFilename
 646  
         try
 647  
         {
 648  0
             ExpressionEvaluator expressionEvaluator = new DefaultExpressionEvaluator();
 649  0
             expressionEvaluator.addExpressionSource( new SystemPropertyExpressionSource() );
 650  0
             userConfigFilename = expressionEvaluator.expand( userConfigFilename );
 651  0
             altConfigFilename = expressionEvaluator.expand( altConfigFilename );
 652  0
             loadConfiguration();
 653  
         }
 654  0
         catch ( EvaluatorException e )
 655  
         {
 656  0
             throw new InitializationException( "Unable to evaluate expressions found in "
 657  
                 + "userConfigFilename or altConfigFilename." );
 658  0
         }
 659  0
         registry.addChangeListener( this );
 660  0
     }
 661  
 
 662  
     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
 663  
     {
 664  
         // nothing to do here
 665  0
     }
 666  
 
 667  
     public synchronized void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
 668  
     {
 669  0
         configuration = null;
 670  0
     }
 671  
 
 672  
     private String removeExpressions( String directory )
 673  
     {
 674  0
         String value = StringUtils.replace( directory, "${appserver.base}", registry.getString( "appserver.base",
 675  
                                                                                                 "${appserver.base}" ) );
 676  0
         value = StringUtils.replace( value, "${appserver.home}", registry.getString( "appserver.home",
 677  
                                                                                      "${appserver.home}" ) );
 678  0
         return value;
 679  
     }
 680  
 
 681  
     private String unescapeCronExpression( String cronExpression )
 682  
     {
 683  0
         return StringUtils.replace( cronExpression, "\\,", "," );
 684  
     }
 685  
 
 686  
     private String escapeCronExpression( String cronExpression )
 687  
     {
 688  0
         return StringUtils.replace( cronExpression, ",", "\\," );
 689  
     }
 690  
 
 691  
     private Configuration unescapeExpressions( Configuration config )
 692  
     {
 693  
         // TODO: for commons-configuration 1.3 only
 694  0
         for ( Iterator<ManagedRepositoryConfiguration> i = config.getManagedRepositories().iterator(); i.hasNext(); )
 695  
         {
 696  0
             ManagedRepositoryConfiguration c = i.next();
 697  0
             c.setLocation( removeExpressions( c.getLocation() ) );
 698  0
             c.setRefreshCronExpression( unescapeCronExpression( c.getRefreshCronExpression() ) );
 699  0
         }
 700  
 
 701  0
         DatabaseScanningConfiguration databaseScanning = config.getDatabaseScanning();
 702  0
         if ( databaseScanning != null )
 703  
         {
 704  0
             String cron = databaseScanning.getCronExpression();
 705  0
             databaseScanning.setCronExpression( unescapeCronExpression( cron ) );
 706  
         }
 707  
 
 708  0
         return config;
 709  
     }
 710  
     
 711  
     private Configuration checkRepositoryLocations( Configuration config )
 712  
     {
 713  
         // additional check for [MRM-789], ensure that the location of the default repositories 
 714  
         // are not installed in the server installation        
 715  0
         for( ManagedRepositoryConfiguration repo : (List<ManagedRepositoryConfiguration>) config.getManagedRepositories() )
 716  
         {
 717  0
             String repoPath = repo.getLocation();
 718  0
             File repoLocation = new File( repoPath );            
 719  
             
 720  0
             if( repoLocation.exists() && repoLocation.isDirectory() && !repoPath.endsWith( "data/repositories/" + repo.getId() ) )
 721  
             {
 722  0
                 repo.setLocation( repoPath + "/data/repositories/" + repo.getId() );
 723  
             }
 724  0
         }
 725  
         
 726  0
         return config;
 727  
     }
 728  
 
 729  
     public String getUserConfigFilename()
 730  
     {
 731  0
         return userConfigFilename;
 732  
     }
 733  
 
 734  
     public String getAltConfigFilename()
 735  
     {
 736  0
         return altConfigFilename;
 737  
     }
 738  
 
 739  
     public boolean isDefaulted()
 740  
     {
 741  0
         return this.isConfigurationDefaulted;
 742  
     }
 743  
 }