View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.changes;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.maven.plugin.MojoExecutionException;
26  import org.apache.maven.plugins.changes.model.Action;
27  import org.apache.maven.plugins.changes.model.Release;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  /**
32   * A utility class for working with Release objects.
33   *
34   * @author Dennis Lundberg
35   * @version $Id$
36   * @since 2.4
37   */
38  public class ReleaseUtils {
39      private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT";
40  
41      private static final Logger LOG = LoggerFactory.getLogger(ReleaseUtils.class);
42  
43      private ReleaseUtils() {
44          // utility class
45      }
46  
47      /**
48       * Get the latest release by matching the supplied releases with the version from the pom.
49       *
50       * @param releases list of releases
51       * @param pomVersion Version of the artifact
52       * @return A <code>Release</code> that matches the next release of the current project
53       * @throws org.apache.maven.plugin.MojoExecutionException If a release can't be found
54       */
55      public static Release getLatestRelease(List<Release> releases, String pomVersion) throws MojoExecutionException {
56          // Remove "-SNAPSHOT" from the end, if it's there
57          if (pomVersion != null && pomVersion.endsWith(SNAPSHOT_SUFFIX)) {
58              pomVersion = pomVersion.substring(0, pomVersion.length() - SNAPSHOT_SUFFIX.length());
59          }
60          LOG.debug("Found {} releases.", releases.size());
61  
62          Release release = getRelease(releases, pomVersion);
63  
64          if (release == null) {
65              throw new MojoExecutionException("Couldn't find the release '" + pomVersion
66                      + "' among the supplied releases: " + toString(releases));
67          }
68  
69          return release;
70      }
71  
72      /**
73       * Get a release with the specified version from the list of releases.
74       *
75       * @param releases A list of releases
76       * @param version The version we want
77       * @return A Release, or null if no release with the specified version can be found
78       */
79      protected static Release getRelease(List<Release> releases, String version) {
80          for (Release release : releases) {
81              if (LOG.isDebugEnabled()) {
82                  LOG.debug(
83                          "The release: {} has {} actions.",
84                          release.getVersion(),
85                          release.getActions().size());
86              }
87  
88              if (release.getVersion() != null && release.getVersion().equals(version)) {
89                  if (LOG.isDebugEnabled()) {
90                      LOG.debug("Found the correct release: {}", release.getVersion());
91                      logRelease(release);
92                  }
93                  return release;
94              }
95          }
96          return null;
97      }
98  
99      protected static void logRelease(Release release) {
100         Action action;
101         for (Action action1 : release.getActions()) {
102             action = action1;
103             LOG.debug("o {}", action.getType());
104             LOG.debug("issue: {}", action.getIssue());
105             LOG.debug("action: {}", action.getAction());
106             LOG.debug("dueTo: {}", action.getDueTo());
107         }
108     }
109 
110     /**
111      * Merge releases from one issue tracker with releases from another issue tracker. If a release is found in both
112      * issue trackers, i.e. they have the same version, their issues are merged into one release.
113      *
114      * @param firstReleases Releases from the first issue tracker
115      * @param secondReleases Releases from the second issue tracker
116      * @return A list containing the merged releases
117      */
118     public static List<Release> mergeReleases(final List<Release> firstReleases, final List<Release> secondReleases) {
119         if (firstReleases == null && secondReleases == null) {
120             return Collections.emptyList();
121         }
122         if (firstReleases == null) {
123             return secondReleases;
124         }
125         if (secondReleases == null) {
126             return firstReleases;
127         }
128 
129         List<Release> mergedReleases = new ArrayList<>();
130 
131         // Loop through the releases from the first issue tracker, merging in
132         // actions from releases with the same version from the second issue
133         // tracker
134         for (Release firstRelease : firstReleases) {
135             Release secondRelease = getRelease(secondReleases, firstRelease.getVersion());
136             if (secondRelease != null) {
137                 if (secondRelease.getActions() != null) {
138                     firstRelease.getActions().addAll(secondRelease.getActions());
139                 }
140             }
141             mergedReleases.add(firstRelease);
142         }
143 
144         // Handle releases that are only in the second issue tracker
145         for (Release secondRelease : secondReleases) {
146             Release mergedRelease = getRelease(mergedReleases, secondRelease.getVersion());
147             if (mergedRelease == null) {
148                 mergedReleases.add(secondRelease);
149             }
150         }
151         return mergedReleases;
152     }
153 
154     /**
155      * Merge releases from parent component with releases from child component. If a release is found in both
156      * components, i.e. they have the same version, their issues are merged into one (parent) release with component
157      * marker for component issues.
158      *
159      * @param releases Releases from the parent component
160      * @param componentName child component name (retrieved from project name)
161      * @param componentReleases Releases from the child component
162      * @return A list containing the merged releases
163      */
164     public static List<Release> mergeReleases(
165             final List<Release> releases, final String componentName, final List<Release> componentReleases) {
166         if (releases == null && componentReleases == null) {
167             return Collections.emptyList();
168         }
169         if (componentReleases == null) {
170             return releases;
171         }
172 
173         final List<Release> mergedReleases = new ArrayList<>();
174 
175         if (releases != null) {
176             for (Release release : releases) {
177                 final Release componentRelease = getRelease(componentReleases, release.getVersion());
178                 if (componentRelease != null) {
179                     release.addComponent(componentName, componentRelease);
180                 }
181                 mergedReleases.add(release);
182             }
183         }
184 
185         for (Release release : componentReleases) {
186             final Release mergedRelease = getRelease(mergedReleases, release.getVersion());
187             if (mergedRelease == null) {
188                 final Release componentRelease = new Release();
189                 componentRelease.setVersion(release.getVersion());
190                 componentRelease.setDateRelease(release.getDateRelease());
191                 componentRelease.addComponent(componentName, release);
192                 mergedReleases.add(componentRelease);
193             }
194         }
195 
196         return mergedReleases;
197     }
198 
199     private static String toString(Release release) {
200         return release.getClass().getSimpleName() + "[version='" + release.getVersion() + "'" + ", date='"
201                 + release.getDateRelease() + "'" + ", description='" + release.getDescription() + "'" + ", actionsSize="
202                 + release.getActions().size() + "]";
203     }
204 
205     public static String toString(List<Release> releases) {
206         List<String> releaseStrings = new ArrayList<>(releases.size());
207         for (Release release : releases) {
208             releaseStrings.add(toString(release));
209         }
210         return releaseStrings.toString();
211     }
212 }