View Javadoc
1   package org.apache.maven.shared.release.config;
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 java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  import java.util.Map.Entry;
26  import java.util.Properties;
27  import java.util.Set;
28  
29  import org.apache.maven.shared.release.scm.IdentifiedScm;
30  
31  /**
32   * Class providing utility methods used during the release process
33   *
34   * @author <a href="mailto:jwhitlock@apache.org">Jeremy Whitlock</a>
35   */
36  public class ReleaseUtils
37  {
38      private ReleaseUtils()
39      {
40          // nothing to see here
41      }
42  
43      /**
44       * Merge two descriptors together. All SCM settings are overridden by the merge descriptor, as is the
45       * <code>workingDirectory</code> field. The <code>completedPhase</code> field is used as
46       * a default from the merge descriptor, but not overridden if it exists.
47       *
48       * @param mergeInto  the descriptor to be merged into
49       * @param toBeMerged the descriptor to merge into mergeInto
50       * @return ReleaseDescriptor the merged descriptor
51       */
52      public static ReleaseDescriptor merge( ReleaseDescriptor mergeInto, ReleaseDescriptor toBeMerged )
53      {
54          // Overridden if configured from the caller
55          mergeInto.setScmId( mergeOverride( mergeInto.getScmId(), toBeMerged.getScmId() ) );
56          mergeInto.setScmSourceUrl( mergeOverride( mergeInto.getScmSourceUrl(), toBeMerged.getScmSourceUrl() ) );
57          mergeInto.setScmCommentPrefix(
58              mergeOverride( mergeInto.getScmCommentPrefix(), toBeMerged.getScmCommentPrefix() ) );
59          mergeInto.setScmReleaseLabel( mergeOverride( mergeInto.getScmReleaseLabel(), toBeMerged.getScmReleaseLabel() ) );
60          mergeInto.setScmTagBase( mergeOverride( mergeInto.getScmTagBase(), toBeMerged.getScmTagBase() ) );
61          mergeInto.setScmTagNameFormat(
62              mergeOverride( mergeInto.getScmTagNameFormat(), toBeMerged.getScmTagNameFormat() ) );
63          mergeInto.setScmBranchBase( mergeOverride( mergeInto.getScmBranchBase(), toBeMerged.getScmBranchBase() ) );
64          mergeInto.setScmUsername( mergeOverride( mergeInto.getScmUsername(), toBeMerged.getScmUsername() ) );
65          mergeInto.setScmPassword( mergeOverride( mergeInto.getScmPassword(), toBeMerged.getScmPassword() ) );
66          mergeInto.setScmPrivateKey( mergeOverride( mergeInto.getScmPrivateKey(), toBeMerged.getScmPrivateKey() ) );
67          mergeInto.setScmPrivateKeyPassPhrase(
68              mergeOverride( mergeInto.getScmPrivateKeyPassPhrase(), toBeMerged.getScmPrivateKeyPassPhrase() ) );
69          mergeInto.setScmCommentPrefix(
70              mergeOverride( mergeInto.getScmCommentPrefix(), toBeMerged.getScmCommentPrefix() ) );
71          mergeInto.setAdditionalArguments(
72              mergeOverride( mergeInto.getAdditionalArguments(), toBeMerged.getAdditionalArguments() ) );
73          mergeInto.setPreparationGoals(
74              mergeOverride( mergeInto.getPreparationGoals(), toBeMerged.getPreparationGoals() ) );
75          mergeInto.setCompletionGoals(
76              mergeOverride( mergeInto.getCompletionGoals(), toBeMerged.getCompletionGoals() ) );
77          mergeInto.setPerformGoals( mergeOverride( mergeInto.getPerformGoals(), toBeMerged.getPerformGoals() ) );
78          mergeInto.setPomFileName( mergeOverride( mergeInto.getPomFileName(), toBeMerged.getPomFileName() ) );
79          mergeInto.setCheckModificationExcludes( toBeMerged.getCheckModificationExcludes() );
80          mergeInto.setScmUseEditMode( toBeMerged.isScmUseEditMode() );
81          mergeInto.setAddSchema( toBeMerged.isAddSchema() );
82          mergeInto.setGenerateReleasePoms( toBeMerged.isGenerateReleasePoms() );
83          mergeInto.setInteractive( toBeMerged.isInteractive() );
84          mergeInto.setUpdateDependencies( toBeMerged.isUpdateDependencies() );
85          mergeInto.setCommitByProject( mergeOverride( mergeInto.isCommitByProject(), toBeMerged.isCommitByProject(),
86                                                       false ) );
87          mergeInto.setUseReleaseProfile( toBeMerged.isUseReleaseProfile() );
88          mergeInto.setBranchCreation( toBeMerged.isBranchCreation() );
89          mergeInto.setUpdateBranchVersions( toBeMerged.isUpdateBranchVersions() );
90          mergeInto.setUpdateWorkingCopyVersions( toBeMerged.isUpdateWorkingCopyVersions() );
91          mergeInto.setSuppressCommitBeforeTagOrBranch( toBeMerged.isSuppressCommitBeforeTagOrBranch() );
92          mergeInto.setUpdateVersionsToSnapshot( toBeMerged.isUpdateVersionsToSnapshot() );
93          mergeInto.setAllowTimestampedSnapshots( toBeMerged.isAllowTimestampedSnapshots() );
94          mergeInto.setSnapshotReleasePluginAllowed( toBeMerged.isSnapshotReleasePluginAllowed() );
95          mergeInto.setAutoVersionSubmodules( toBeMerged.isAutoVersionSubmodules() );
96          mergeInto.setDefaultReleaseVersion( mergeOverride( mergeInto.getDefaultReleaseVersion(),
97                                                             toBeMerged.getDefaultReleaseVersion() ) );
98          mergeInto.setDefaultDevelopmentVersion( mergeOverride( mergeInto.getDefaultDevelopmentVersion(),
99                                                                 toBeMerged.getDefaultDevelopmentVersion() ) );
100         mergeInto.setRemoteTagging( toBeMerged.isRemoteTagging() );
101         mergeInto.setLocalCheckout( toBeMerged.isLocalCheckout() );
102         mergeInto.setPushChanges( toBeMerged.isPushChanges() );
103         mergeInto.setWaitBeforeTagging( toBeMerged.getWaitBeforeTagging() );
104 
105         // If the user specifies versions, these should be override the existing versions
106         if ( toBeMerged.getReleaseVersions() != null )
107         {
108             mergeInto.getReleaseVersions().putAll( toBeMerged.getReleaseVersions() );
109         }
110         if ( toBeMerged.getDevelopmentVersions() != null )
111         {
112             mergeInto.getDevelopmentVersions().putAll( toBeMerged.getDevelopmentVersions() );
113         }
114         // These must be overridden, as they are not stored
115         mergeInto.setWorkingDirectory(
116             mergeOverride( mergeInto.getWorkingDirectory(), toBeMerged.getWorkingDirectory() ) );
117         mergeInto.setCheckoutDirectory(
118             mergeOverride( mergeInto.getCheckoutDirectory(), toBeMerged.getCheckoutDirectory() ) );
119 
120         // Not overridden - not configured from caller
121         mergeInto.setCompletedPhase( mergeDefault( mergeInto.getCompletedPhase(), toBeMerged.getCompletedPhase() ) );
122 
123         mergeInto.setProjectVersionPolicyId(
124             mergeDefault( mergeInto.getProjectVersionPolicyId(), toBeMerged.getProjectVersionPolicyId() ) );
125 
126         return mergeInto;
127     }
128 
129     private static String mergeOverride( String thisValue, String mergeValue )
130     {
131         return mergeValue != null ? mergeValue : thisValue;
132     }
133 
134     private static String mergeDefault( String thisValue, String mergeValue )
135     {
136         return thisValue != null ? thisValue : mergeValue;
137     }
138 
139     private static boolean mergeOverride( boolean thisValue, boolean mergeValue, boolean defaultValue )
140     {
141         return mergeValue != defaultValue ? mergeValue : thisValue;
142     }
143 
144     public static ReleaseDescriptor copyPropertiesToReleaseDescriptor( Properties properties )
145     {
146         ReleaseDescriptor releaseDescriptor = new ReleaseDescriptor();
147         releaseDescriptor.setCompletedPhase( properties.getProperty( "completedPhase" ) );
148         releaseDescriptor.setCommitByProject( Boolean.parseBoolean( properties.getProperty( "commitByProject" ) ) );
149         releaseDescriptor.setScmId( properties.getProperty( "scm.id" ) );
150         releaseDescriptor.setScmSourceUrl( properties.getProperty( "scm.url" ) );
151         releaseDescriptor.setScmUsername( properties.getProperty( "scm.username" ) );
152         releaseDescriptor.setScmPassword( properties.getProperty( "scm.password" ) );
153         releaseDescriptor.setScmPrivateKey( properties.getProperty( "scm.privateKey" ) );
154         releaseDescriptor.setScmPrivateKeyPassPhrase( properties.getProperty( "scm.passphrase" ) );
155         releaseDescriptor.setScmTagBase( properties.getProperty( "scm.tagBase" ) );
156         releaseDescriptor.setScmTagNameFormat( properties.getProperty( "scm.tagNameFormat" ) );
157         releaseDescriptor.setScmBranchBase( properties.getProperty( "scm.branchBase" ) );
158         releaseDescriptor.setScmReleaseLabel( properties.getProperty( "scm.tag" ) );
159         releaseDescriptor.setScmCommentPrefix( properties.getProperty( "scm.commentPrefix" ) );
160         releaseDescriptor.setAdditionalArguments( properties.getProperty( "exec.additionalArguments" ) );
161         releaseDescriptor.setPomFileName( properties.getProperty( "exec.pomFileName" ) );
162         releaseDescriptor.setPreparationGoals( properties.getProperty( "preparationGoals" ) );
163         releaseDescriptor.setCompletionGoals( properties.getProperty( "completionGoals" ) );
164         releaseDescriptor.setProjectVersionPolicyId( properties.getProperty( "projectVersionPolicyId" ) );
165         String snapshotReleasePluginAllowedStr = properties.getProperty( "exec.snapshotReleasePluginAllowed" );
166         releaseDescriptor.setSnapshotReleasePluginAllowed( snapshotReleasePluginAllowedStr == null
167                                                                ? false
168                                                                : Boolean.valueOf(
169                                                                    snapshotReleasePluginAllowedStr ).booleanValue() );
170         String remoteTaggingStr = properties.getProperty( "remoteTagging" );
171         releaseDescriptor.setRemoteTagging(
172             remoteTaggingStr == null ? false : Boolean.valueOf( remoteTaggingStr ).booleanValue() );
173         String pushChanges = properties.getProperty( "pushChanges" );
174         releaseDescriptor.setPushChanges( pushChanges == null ? true : Boolean.valueOf( pushChanges ).booleanValue() );
175 
176         loadResolvedDependencies( properties, releaseDescriptor );
177 
178         // boolean properties are not written to the properties file because the value from the caller is always used
179 
180         for ( Iterator<?> i = properties.keySet().iterator(); i.hasNext(); )
181         {
182             String property = (String) i.next();
183             if ( property.startsWith( "project.rel." ) )
184             {
185                 releaseDescriptor.mapReleaseVersion( property.substring( "project.rel.".length() ),
186                                                      properties.getProperty( property ) );
187             }
188             else if ( property.startsWith( "project.dev." ) )
189             {
190                 releaseDescriptor.mapDevelopmentVersion( property.substring( "project.dev.".length() ),
191                                                          properties.getProperty( property ) );
192             }
193             else if ( property.startsWith( "project.scm." ) )
194             {
195                 int index = property.lastIndexOf( '.' );
196                 if ( index > "project.scm.".length() )
197                 {
198                     String key = property.substring( "project.scm.".length(), index );
199 
200                     if ( !releaseDescriptor.getOriginalScmInfo().containsKey( key ) )
201                     {
202                         if ( properties.getProperty( "project.scm." + key + ".empty" ) != null )
203                         {
204                             releaseDescriptor.mapOriginalScmInfo( key, null );
205                         }
206                         else
207                         {
208                             IdentifiedScm scm = new IdentifiedScm();
209                             scm.setConnection( properties.getProperty( "project.scm." + key + ".connection" ) );
210                             scm.setDeveloperConnection(
211                                 properties.getProperty( "project.scm." + key + ".developerConnection" ) );
212                             scm.setUrl( properties.getProperty( "project.scm." + key + ".url" ) );
213                             scm.setTag( properties.getProperty( "project.scm." + key + ".tag" ) );
214                             scm.setId( properties.getProperty( "project.scm." + key + ".id" ) );
215 
216                             releaseDescriptor.mapOriginalScmInfo( key, scm );
217                         }
218                     }
219                 }
220             }
221         }
222         return releaseDescriptor;
223     }
224 
225     private static void loadResolvedDependencies( Properties prop, ReleaseDescriptor descriptor )
226     {
227         Map<String, Map<String, String>> resolvedDependencies = new HashMap<String, Map<String, String>>();
228 
229         Set entries = prop.entrySet();
230         Iterator<Entry<String, String>> iterator = entries.iterator();
231         String propertyName;
232         Entry<String, String> currentEntry;
233 
234         while ( iterator.hasNext() )
235         {
236             currentEntry = iterator.next();
237             propertyName = currentEntry.getKey();
238 
239             if ( propertyName.startsWith( "dependency." ) )
240             {
241                 Map<String, String> versionMap;
242                 String artifactVersionlessKey;
243                 int startIndex = "dependency.".length();
244                 int endIndex;
245                 String versionType;
246 
247                 versionMap = new HashMap<String, String>();
248 
249                 if ( propertyName.indexOf( ".development" ) != -1 )
250                 {
251                     endIndex = propertyName.lastIndexOf( ".development" );
252                     versionType = ReleaseDescriptor.DEVELOPMENT_KEY;
253                 }
254                 else
255                 {
256                     endIndex = propertyName.lastIndexOf( ".release" );
257                     versionType = ReleaseDescriptor.RELEASE_KEY;
258                 }
259 
260                 artifactVersionlessKey = propertyName.substring( startIndex, endIndex );
261 
262                 if ( resolvedDependencies.containsKey( artifactVersionlessKey ) )
263                 {
264                     versionMap = resolvedDependencies.get( artifactVersionlessKey );
265                 }
266                 else
267                 {
268                     versionMap = new HashMap<String, String>();
269                     resolvedDependencies.put( artifactVersionlessKey, versionMap );
270                 }
271 
272                 versionMap.put( versionType, currentEntry.getValue() );
273             }
274         }
275 
276         descriptor.setResolvedSnapshotDependencies( resolvedDependencies );
277     }
278 
279 }