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