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