]> source.dussan.org Git - archiva.git/blob
540a8653919a280644830403e93adff784b77629
[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.io.FileUtils;
23 import org.apache.maven.archiva.configuration.io.registry.ConfigurationRegistryReader;
24 import org.apache.maven.archiva.configuration.io.registry.ConfigurationRegistryWriter;
25 import org.codehaus.plexus.logging.AbstractLogEnabled;
26 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
27 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
28 import org.codehaus.plexus.registry.Registry;
29 import org.codehaus.plexus.registry.RegistryException;
30 import org.codehaus.plexus.registry.RegistryListener;
31 import org.codehaus.plexus.util.StringUtils;
32
33 import java.io.File;
34 import java.io.IOException;
35 import java.util.Iterator;
36
37 /**
38  * Implementation of configuration holder that retrieves it from the registry.
39  * <p/>
40  * The registry layers and merges the 2 configuration files: user, and application server.
41  * <p/>
42  * Instead of relying on the model defaults, if the registry is empty a default configuration file is loaded and
43  * applied from a resource. The defaults are not loaded into the registry as the lists (eg repositories) could no longer
44  * be removed if that was the case.
45  * <p/>
46  * When saving the configuration, it is saved to the location it was read from. If it was read from the defaults, it
47  * will be saved to the user location.
48  * However, if the configuration contains information from both sources, an exception is raised as this is currently
49  * unsupported. The reason for this is that it is not possible to identify where to re-save elements, and can result
50  * in list configurations (eg repositories) becoming inconsistent.
51  * <p/>
52  * If the configuration is outdated, it will be upgraded when it is loaded. This is done by checking the version flag
53  * before reading it from the registry.
54  *
55  * @plexus.component role="org.apache.maven.archiva.configuration.ArchivaConfiguration"
56  */
57 public class DefaultArchivaConfiguration
58     extends AbstractLogEnabled
59     implements ArchivaConfiguration, RegistryListener, Initializable
60 {
61     /**
62      * Plexus registry to read the configuration from.
63      *
64      * @plexus.requirement role-hint="commons-configuration"
65      */
66     private Registry registry;
67
68     /**
69      * The configuration that has been converted.
70      */
71     private Configuration configuration;
72
73     private static final String KEY = "org.apache.maven.archiva";
74
75     /**
76      * @plexus.configuration default-value="${user.home}/.m2/archiva.xml"
77      */
78     private String userConfigFilename;
79
80     public String getFilteredUserConfigFilename()
81     {
82         return StringUtils.replace( userConfigFilename, "${user.home}", System.getProperty( "user.home" + "" ) );
83     }
84
85     public synchronized Configuration getConfiguration()
86     {
87         if ( configuration == null )
88         {
89             configuration = load();
90         }
91         return configuration;
92     }
93
94     private Configuration load()
95     {
96         // TODO: should this be the same as section? make sure unnamed sections still work (eg, sys properties)
97         Registry subset = registry.getSubset( KEY );
98         if ( subset.getString( "version" ) == null )
99         {
100             // a little autodetection of v1, even if version is omitted (this was previously allowed)
101             if ( subset.getSubset( "repositoryScanning" ).isEmpty() )
102             {
103                 // only for empty, or v < 1
104                 subset = readDefaultConfiguration();
105             }
106         }
107
108         Configuration config = new ConfigurationRegistryReader().read( subset );
109
110         // TODO: for commons-configuration 1.3 only
111         for ( Iterator i = config.getRepositories().iterator(); i.hasNext(); )
112         {
113             RepositoryConfiguration c = (RepositoryConfiguration) i.next();
114             c.setUrl( removeExpressions( c.getUrl() ) );
115         }
116         return config;
117     }
118
119     private Registry readDefaultConfiguration()
120     {
121         // if it contains some old configuration, remove it (Archiva 0.9)
122         registry.removeSubset( KEY );
123
124         try
125         {
126             registry.addConfigurationFromResource( "org/apache/maven/archiva/configuration/default-archiva.xml", KEY );
127         }
128         catch ( RegistryException e )
129         {
130             throw new ConfigurationRuntimeException(
131                 "Fatal error: Unable to find the built-in default configuration and load it into the registry", e );
132         }
133         return registry.getSubset( KEY );
134     }
135
136     public void save( Configuration configuration )
137         throws RegistryException, IndeterminateConfigurationException
138     {
139         Registry section = registry.getSection( KEY + ".user" );
140         if ( section == null )
141         {
142             section = registry.getSection( KEY + ".base" );
143             if ( section == null )
144             {
145                 section = createDefaultConfigurationFile();
146             }
147         }
148         else if ( registry.getSection( KEY + ".base" ) != null )
149         {
150             this.configuration = null;
151
152             throw new IndeterminateConfigurationException(
153                 "Configuration can not be saved when it is loaded from two sources" );
154         }
155
156         new ConfigurationRegistryWriter().write( configuration, section );
157         section.save();
158
159         this.configuration = configuration;
160     }
161
162     private Registry createDefaultConfigurationFile()
163         throws RegistryException
164     {
165         // TODO: may not be needed under commons-configuration 1.4 - check
166         File file = new File( getFilteredUserConfigFilename() );
167         try
168         {
169             FileUtils.writeStringToFile( file, "<configuration/>", "UTF-8" );
170         }
171         catch ( IOException e )
172         {
173             throw new RegistryException( "Unable to create configuration file: " + e.getMessage(), e );
174         }
175
176         try
177         {
178             ( (Initializable) registry ).initialize();
179         }
180         catch ( InitializationException e )
181         {
182             throw new RegistryException( "Unable to reinitialize configuration: " + e.getMessage(), e );
183         }
184
185         return registry.getSection( KEY + ".user" );
186     }
187
188     public void addChangeListener( RegistryListener listener )
189     {
190         Registry section = registry.getSection( KEY + ".user" );
191         if ( section != null )
192         {
193             section.addChangeListener( listener );
194         }
195         section = registry.getSection( KEY + ".base" );
196         if ( section != null )
197         {
198             section.addChangeListener( listener );
199         }
200     }
201
202     public void initialize()
203         throws InitializationException
204     {
205         registry.addChangeListener( this );
206     }
207
208     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
209     {
210         // nothing to do here
211     }
212
213     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
214     {
215         configuration = null;
216     }
217
218     private String removeExpressions( String directory )
219     {
220         String value = StringUtils.replace( directory, "${appserver.base}",
221                                             registry.getString( "appserver.base", "${appserver.base}" ) );
222         value = StringUtils.replace( value, "${appserver.home}",
223                                      registry.getString( "appserver.home", "${appserver.home}" ) );
224         return value;
225     }
226
227 }