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