View Javadoc
1   package org.apache.maven.plugin.changes;
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.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  
26  import org.apache.maven.plugin.MojoExecutionException;
27  import org.apache.maven.plugin.logging.Log;
28  import org.apache.maven.plugins.changes.model.Action;
29  import org.apache.maven.plugins.changes.model.Release;
30  
31  /**
32   * A utility class for working with Release objects.
33   *
34   * @author Dennis Lundberg
35   * @version $Id: ReleaseUtils.java 1685894 2015-06-16 19:29:09Z khmarbaise $
36   * @since 2.4
37   */
38  public class ReleaseUtils
39  {
40      private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT";
41  
42      private Log log;
43  
44      public ReleaseUtils( Log log )
45      {
46          this.log = log;
47      }
48  
49      /**
50       * Get the latest release by matching the supplied releases with the version from the pom.
51       *
52       * @param releases list of releases
53       * @param pomVersion Version of the artifact
54       * @return A <code>Release</code> that matches the next release of the current project
55       * @throws org.apache.maven.plugin.MojoExecutionException If a release can't be found
56       */
57      public Release getLatestRelease( List<Release> releases, String pomVersion )
58          throws MojoExecutionException
59      {
60          // Remove "-SNAPSHOT" from the end, if it's there
61          if ( pomVersion != null && pomVersion.endsWith( SNAPSHOT_SUFFIX ) )
62          {
63              pomVersion = pomVersion.substring( 0, pomVersion.length() - SNAPSHOT_SUFFIX.length() );
64          }
65          getLog().debug( "Found " + releases.size() + " releases." );
66  
67          Release release = getRelease( releases, pomVersion );
68  
69          if ( release == null )
70          {
71              throw new MojoExecutionException( "Couldn't find the release '" + pomVersion
72                  + "' among the supplied releases: " + toString( releases ) );
73          }
74  
75          return release;
76      }
77  
78      private Log getLog()
79      {
80          return log;
81      }
82  
83      /**
84       * Get a release with the specified version from the list of releases.
85       *
86       * @param releases A list of releases
87       * @param version The version we want
88       * @return A Release, or null if no release with the specified version can be found
89       */
90      protected Release getRelease( List<Release> releases, String version )
91      {
92          for ( Release release : releases )
93          {
94              if ( getLog().isDebugEnabled() )
95              {
96                  getLog().debug( "The release: " + release.getVersion() + " has " + release.getActions().size()
97                      + " actions." );
98              }
99  
100             if ( release.getVersion() != null && release.getVersion().equals( version ) )
101             {
102                 if ( getLog().isDebugEnabled() )
103                 {
104                     getLog().debug( "Found the correct release: " + release.getVersion() );
105                     logRelease( release );
106                 }
107                 return release;
108             }
109         }
110         return null;
111     }
112 
113     protected void logRelease( Release release )
114     {
115         Action action;
116         for ( Action action1 : release.getActions() )
117         {
118             action = action1;
119             getLog().debug( "o " + action.getType() );
120             getLog().debug( "issue : " + action.getIssue() );
121             getLog().debug( "action : " + action.getAction() );
122             getLog().debug( "dueTo : " + action.getDueTo() );
123         }
124     }
125 
126     /**
127      * Merge releases from one issue tracker with releases from another issue tracker. If a release is found in both
128      * issue trackers, i.e. they have the same version, their issues are merged into one release.
129      *
130      * @param firstReleases Releases from the first issue tracker
131      * @param secondReleases Releases from the second issue tracker
132      * @return A list containing the merged releases
133      */
134     public List<Release> mergeReleases( final List<Release> firstReleases, final List<Release> secondReleases )
135     {
136         if ( firstReleases == null && secondReleases == null )
137         {
138             return Collections.emptyList();
139         }
140         if ( firstReleases == null )
141         {
142             return secondReleases;
143         }
144         if ( secondReleases == null )
145         {
146             return firstReleases;
147         }
148 
149         List<Release> mergedReleases = new ArrayList<Release>();
150 
151         // Loop through the releases from the first issue tracker, merging in
152         // actions from releases with the same version from the second issue
153         // tracker
154         for ( Release firstRelease : firstReleases )
155         {
156             Release secondRelease = getRelease( secondReleases, firstRelease.getVersion() );
157             if ( secondRelease != null )
158             {
159                 if ( secondRelease.getActions() != null )
160                 {
161                     firstRelease.getActions().addAll( secondRelease.getActions() );
162                 }
163             }
164             mergedReleases.add( firstRelease );
165         }
166 
167         // Handle releases that are only in the second issue tracker
168         for ( Release secondRelease : secondReleases )
169         {
170             Release mergedRelease = getRelease( mergedReleases, secondRelease.getVersion() );
171             if ( mergedRelease == null )
172             {
173                 mergedReleases.add( secondRelease );
174             }
175         }
176         return mergedReleases;
177     }
178 
179     /**
180      * Convert an untyped List of Release objects that comes from changes.xml into a typed List of Release objects.
181      *
182      * @param changesReleases An untyped List of Release objects
183      * @return A type List of Release objects
184      * @todo When Modello can generate typed collections this method is no longer needed
185      */
186     public List<Release> convertReleaseList( List<Release> changesReleases )
187     {
188         List<Release> releases = new ArrayList<Release>();
189 
190         // Loop through the List of releases from changes.xml and casting each
191         // release to a Release
192         for ( Object changesRelease : changesReleases )
193         {
194             Release release = (Release) changesRelease;
195             releases.add( release );
196         }
197         return releases;
198     }
199 
200     /**
201      * Merge releases from parent component with releases from child component. If a release is found in both
202      * components, i.e. they have the same version, their issues are merged into one (parent) release with component
203      * marker for component issues.
204      *
205      * @param releases Releases from the parent component
206      * @param componentName child component name (retrieved from project name)
207      * @param componentReleases Releases from the child component
208      * @return A list containing the merged releases
209      */
210     public List<Release> mergeReleases( final List<Release> releases, final String componentName,
211                                         final List<Release> componentReleases )
212     {
213         if ( releases == null && componentReleases == null )
214         {
215             return Collections.emptyList();
216         }
217         if ( componentReleases == null )
218         {
219             return releases;
220         }
221 
222         final List<Release> mergedReleases = new ArrayList<Release>();
223 
224         if ( releases != null )
225         {
226             for ( Object release1 : releases )
227             {
228                 final Release release = (Release) release1;
229                 final Release componentRelease = getRelease( componentReleases, release.getVersion() );
230                 if ( componentRelease != null )
231                 {
232                     release.addComponent( componentName, componentRelease );
233                 }
234                 mergedReleases.add( release );
235             }
236         }
237 
238         for ( Object componentRelease1 : componentReleases )
239         {
240             final Release release = (Release) componentRelease1;
241             final Release mergedRelease = getRelease( mergedReleases, release.getVersion() );
242             if ( mergedRelease == null )
243             {
244                 final Release componentRelease = new Release();
245                 componentRelease.setVersion( release.getVersion() );
246                 componentRelease.setDateRelease( release.getDateRelease() );
247                 componentRelease.addComponent( componentName, release );
248                 mergedReleases.add( componentRelease );
249             }
250         }
251 
252         return mergedReleases;
253     }
254 
255     private static String toString( Release release )
256     {
257         return release.getClass().getSimpleName() + "[version='" + release.getVersion() + "'" + ", date='"
258             + release.getDateRelease() + "'" + ", description='" + release.getDescription() + "'" + ", actionsSize="
259             + release.getActions().size() + "]";
260     }
261 
262     public static String toString( List<Release> releases )
263     {
264         List<String> releaseStrings = new ArrayList<String>( releases.size() );
265         for ( Release release : releases )
266         {
267             releaseStrings.add( toString( release ) );
268         }
269         return releaseStrings.toString();
270     }
271 }