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