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