1 package org.apache.maven.shared.release.config;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.util.Iterator;
30 import java.util.Map;
31 import java.util.Map.Entry;
32 import java.util.Properties;
33 import java.util.Set;
34
35 import org.apache.maven.model.Scm;
36 import org.apache.maven.shared.release.scm.IdentifiedScm;
37 import org.codehaus.plexus.logging.AbstractLogEnabled;
38 import org.codehaus.plexus.util.IOUtil;
39 import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
40 import org.sonatype.plexus.components.cipher.PlexusCipherException;
41 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
42 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
43 import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
44 import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
45
46
47
48
49
50
51
52 public class PropertiesReleaseDescriptorStore
53 extends AbstractLogEnabled
54 implements ReleaseDescriptorStore
55 {
56
57
58
59
60
61
62
63
64 private DefaultSecDispatcher secDispatcher;
65
66 public ReleaseDescriptor read( ReleaseDescriptor mergeDescriptor )
67 throws ReleaseDescriptorStoreException
68 {
69 return read( mergeDescriptor, getDefaultReleasePropertiesFile( mergeDescriptor ) );
70 }
71
72 public ReleaseDescriptor read( File file )
73 throws ReleaseDescriptorStoreException
74 {
75 return read( null, file );
76 }
77
78 public ReleaseDescriptor read( ReleaseDescriptor mergeDescriptor, File file )
79 throws ReleaseDescriptorStoreException
80 {
81 Properties properties = new Properties();
82
83 InputStream inStream = null;
84 try
85 {
86 inStream = new FileInputStream( file );
87
88 properties.load( inStream );
89 }
90 catch ( FileNotFoundException e )
91 {
92 getLogger().debug( file.getName() + " not found - using empty properties" );
93 }
94 catch ( IOException e )
95 {
96 throw new ReleaseDescriptorStoreException(
97 "Error reading properties file '" + file.getName() + "': " + e.getMessage(), e );
98 }
99 finally
100 {
101 IOUtil.close( inStream );
102 }
103
104 ReleaseDescriptor releaseDescriptor = ReleaseUtils.copyPropertiesToReleaseDescriptor( properties );
105
106 if ( mergeDescriptor != null )
107 {
108 releaseDescriptor = ReleaseUtils.merge( releaseDescriptor, mergeDescriptor );
109 }
110
111 return releaseDescriptor;
112 }
113
114 public void write( ReleaseDescriptor config )
115 throws ReleaseDescriptorStoreException
116 {
117 write( config, getDefaultReleasePropertiesFile( config ) );
118 }
119
120 public void delete( ReleaseDescriptor config )
121 {
122 File file = getDefaultReleasePropertiesFile( config );
123 if ( file.exists() )
124 {
125 file.delete();
126 }
127 }
128
129 public void write( ReleaseDescriptor config, File file )
130 throws ReleaseDescriptorStoreException
131 {
132 Properties properties = new Properties();
133 properties.setProperty( "completedPhase", config.getCompletedPhase() );
134 if ( config.isCommitByProject() )
135 {
136 properties.setProperty( "commitByProject", "true" );
137 }
138 properties.setProperty( "scm.url", config.getScmSourceUrl() );
139 if ( config.getScmId() != null )
140 {
141 properties.setProperty( "scm.id", config.getScmId() );
142 }
143 if ( config.getScmUsername() != null )
144 {
145 properties.setProperty( "scm.username", config.getScmUsername() );
146 }
147 if ( config.getScmPassword() != null )
148 {
149 String password = config.getScmPassword();
150 try
151 {
152 password = encryptAndDecorate( password );
153 }
154 catch ( IllegalStateException e )
155 {
156 getLogger().debug( e.getMessage() );
157 }
158 catch ( SecDispatcherException e )
159 {
160 getLogger().debug( e.getMessage() );
161 }
162 catch ( PlexusCipherException e )
163 {
164 getLogger().debug( e.getMessage() );
165 }
166 properties.setProperty( "scm.password", password );
167 }
168 if ( config.getScmPrivateKey() != null )
169 {
170 properties.setProperty( "scm.privateKey", config.getScmPrivateKey() );
171 }
172 if ( config.getScmPrivateKeyPassPhrase() != null )
173 {
174 String passPhrase = config.getScmPrivateKeyPassPhrase();
175 try
176 {
177 passPhrase = encryptAndDecorate( passPhrase );
178 }
179 catch ( IllegalStateException e )
180 {
181 getLogger().debug( e.getMessage() );
182 }
183 catch ( SecDispatcherException e )
184 {
185 getLogger().debug( e.getMessage() );
186 }
187 catch ( PlexusCipherException e )
188 {
189 getLogger().debug( e.getMessage() );
190 }
191 properties.setProperty( "scm.passphrase", passPhrase );
192 }
193 if ( config.getScmTagBase() != null )
194 {
195 properties.setProperty( "scm.tagBase", config.getScmTagBase() );
196 }
197 if ( config.getScmBranchBase() != null )
198 {
199 properties.setProperty( "scm.branchBase", config.getScmBranchBase() );
200 }
201 if ( config.getScmReleaseLabel() != null )
202 {
203 properties.setProperty( "scm.tag", config.getScmReleaseLabel() );
204 }
205 if ( config.getScmTagNameFormat() != null )
206 {
207 properties.setProperty( "scm.tagNameFormat", config.getScmTagNameFormat() );
208 }
209 if ( config.getScmCommentPrefix() != null )
210 {
211 properties.setProperty( "scm.commentPrefix", config.getScmCommentPrefix() );
212 }
213 if ( config.getAdditionalArguments() != null )
214 {
215 properties.setProperty( "exec.additionalArguments", config.getAdditionalArguments() );
216 }
217 if ( config.getPomFileName() != null )
218 {
219 properties.setProperty( "exec.pomFileName", config.getPomFileName() );
220 }
221 if ( config.getPreparationGoals() != null )
222 {
223 properties.setProperty( "preparationGoals", config.getPreparationGoals() );
224 }
225 if ( config.getCompletionGoals() != null )
226 {
227 properties.setProperty( "completionGoals", config.getCompletionGoals() );
228 }
229 if ( config.getProjectVersionPolicyId() != null )
230 {
231 properties.setProperty( "projectVersionPolicyId", config.getProjectVersionPolicyId() );
232 }
233
234 properties.setProperty( "exec.snapshotReleasePluginAllowed",
235 Boolean.toString( config.isSnapshotReleasePluginAllowed() ) );
236
237 properties.setProperty( "remoteTagging", Boolean.toString( config.isRemoteTagging() ) );
238
239 properties.setProperty( "pushChanges", Boolean.toString( config.isPushChanges() ) );
240
241
242
243
244 for ( Iterator<?> i = config.getReleaseVersions().entrySet().iterator(); i.hasNext(); )
245 {
246 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
247 properties.setProperty( "project.rel." + entry.getKey(), (String) entry.getValue() );
248 }
249
250 for ( Iterator<?> i = config.getDevelopmentVersions().entrySet().iterator(); i.hasNext(); )
251 {
252 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
253 properties.setProperty( "project.dev." + entry.getKey(), (String) entry.getValue() );
254 }
255
256 for ( Iterator<?> i = config.getOriginalScmInfo().entrySet().iterator(); i.hasNext(); )
257 {
258 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
259 Scm scm = (Scm) entry.getValue();
260 String prefix = "project.scm." + entry.getKey();
261 if ( scm != null )
262 {
263 if ( scm.getConnection() != null )
264 {
265 properties.setProperty( prefix + ".connection", scm.getConnection() );
266 }
267 if ( scm.getDeveloperConnection() != null )
268 {
269 properties.setProperty( prefix + ".developerConnection", scm.getDeveloperConnection() );
270 }
271 if ( scm.getUrl() != null )
272 {
273 properties.setProperty( prefix + ".url", scm.getUrl() );
274 }
275 if ( scm.getTag() != null )
276 {
277 properties.setProperty( prefix + ".tag", scm.getTag() );
278 }
279 if ( scm instanceof IdentifiedScm )
280 {
281 IdentifiedScm identifiedScm = (IdentifiedScm) scm;
282 if ( identifiedScm.getId() != null )
283 {
284 properties.setProperty( prefix + ".id", identifiedScm.getId() );
285 }
286 }
287 }
288 else
289 {
290 properties.setProperty( prefix + ".empty", "true" );
291 }
292 }
293
294 if ( ( config.getResolvedSnapshotDependencies() != null )
295 && ( config.getResolvedSnapshotDependencies().size() > 0 ) )
296 {
297 processResolvedDependencies( properties, config.getResolvedSnapshotDependencies() );
298 }
299
300 OutputStream outStream = null;
301
302 try
303 {
304 outStream = new FileOutputStream( file );
305
306 properties.store( outStream, "release configuration" );
307 }
308 catch ( IOException e )
309 {
310 throw new ReleaseDescriptorStoreException(
311 "Error writing properties file '" + file.getName() + "': " + e.getMessage(), e );
312 }
313 finally
314 {
315 IOUtil.close( outStream );
316 }
317
318 }
319
320 private void processResolvedDependencies( Properties prop, Map<?, ?> resolvedDependencies )
321 {
322 Set<?> entries = resolvedDependencies.entrySet();
323 Iterator<?> iterator = entries.iterator();
324 Entry<?, ?> currentEntry;
325
326 while ( iterator.hasNext() )
327 {
328 currentEntry = (Entry<?, ?>) iterator.next();
329
330 Map<?, ?> versionMap = (Map<?, ?>) currentEntry.getValue();
331
332 prop.setProperty( "dependency." + currentEntry.getKey() + ".release",
333 (String) versionMap.get( ReleaseDescriptor.RELEASE_KEY ) );
334 prop.setProperty( "dependency." + currentEntry.getKey() + ".development",
335 (String) versionMap.get( ReleaseDescriptor.DEVELOPMENT_KEY ) );
336 }
337 }
338
339 private static File getDefaultReleasePropertiesFile( ReleaseDescriptor mergeDescriptor )
340 {
341 return new File( mergeDescriptor.getWorkingDirectory(), "release.properties" );
342 }
343
344
345 private String encryptAndDecorate( String passwd )
346 throws IllegalStateException, SecDispatcherException, PlexusCipherException
347 {
348 String configurationFile = secDispatcher.getConfigurationFile();
349
350 if ( configurationFile.startsWith( "~" ) )
351 {
352 configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
353 }
354
355 String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
356
357 String master = null;
358
359 SettingsSecurity sec = SecUtil.read( file, true );
360 if ( sec != null )
361 {
362 master = sec.getMaster();
363 }
364
365 if ( master == null )
366 {
367 throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
368 }
369
370 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
371 String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
372 return cipher.encryptAndDecorate( passwd, masterPasswd );
373 }
374
375 }