View Javadoc

1   /*
2    * Copyright 2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.issue.util;
17  
18  import org.apache.maven.artifact.versioning.ArtifactVersion;
19  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
20  import org.apache.maven.project.MavenProject;
21  
22  import de.smartics.util.lang.Arguments;
23  import de.smartics.util.lang.BlankArgumentException;
24  
25  /**
26   * Utility class to handle versions.
27   */
28  public final class VersionHelper
29  { // NOPMD
30    // ********************************* Fields *********************************
31  
32    // --- constants ------------------------------------------------------------
33  
34    /**
35     * Signals to increment the major version number, setting minor and micro to
36     * zero.
37     * <p>
38     * The value of this constant is {@value}.
39     * </p>
40     */
41    public static final String MAJOR = "MAJOR";
42  
43    /**
44     * Signals to increment the minor version number, setting micro to zero.
45     * <p>
46     * The value of this constant is {@value}.
47     * </p>
48     */
49    public static final String MINOR = "MINOR";
50  
51    /**
52     * Signals to increment the micro version number.
53     * <p>
54     * The value of this constant is {@value}.
55     * </p>
56     */
57    public static final String MICRO = "MICRO";
58  
59    /**
60     * Signals to use the current version (without SNAPSHOT).
61     * <p>
62     * The value of this constant is {@value}.
63     * </p>
64     */
65    public static final String CURRENT = "CURRENT";
66  
67    /**
68     * Signals to use the current version (inclusive if present SNAPSHOT).
69     * <p>
70     * The value of this constant is {@value}.
71     * </p>
72     */
73    public static final String SNAPSHOT = "SNAPSHOT";
74  
75    // --- members --------------------------------------------------------------
76  
77    /**
78     * The project's version.
79     */
80    private final String projectVersion;
81  
82    // ****************************** Initializer *******************************
83  
84    // ****************************** Constructors ******************************
85  
86    /**
87     * Convenience constructor.
88     *
89     * @param project the Maven project.
90     */
91    public VersionHelper(final MavenProject project)
92    {
93      this(project.getVersion());
94    }
95  
96    /**
97     * Default constructor.
98     *
99     * @param projectVersion the project's version.
100    * @throws BlankArgumentException if {@code projectVersion} is
101    *           <code>null</code>.
102    */
103   public VersionHelper(final String projectVersion)
104     throws BlankArgumentException
105   {
106     Arguments.checkNotBlank("projectVersion", projectVersion);
107     this.projectVersion = projectVersion;
108   }
109 
110   // ****************************** Inner Classes *****************************
111 
112   // ********************************* Methods ********************************
113 
114   // --- init -----------------------------------------------------------------
115 
116   // --- get&set --------------------------------------------------------------
117 
118   // --- business -------------------------------------------------------------
119 
120   /**
121    * Calculates the previous version.
122    *
123    * @param version the version to analyze.
124    * @return the version if it is neither {@link #MAJOR}, {@link #MINOR}, or
125    *         {@link #MICRO}.
126    * @throws IllegalArgumentException if the version cannot be decremented.
127    */
128   public String calculatePreviousVersion(final String version)
129     throws IllegalArgumentException
130   {
131     final String strippedVersion =
132         getVersionStrippedFromSnapshotSuffix(projectVersion);
133     final String previousVersion;
134     if (MAJOR.equals(version))
135     {
136       previousVersion = calcPreviousMajor(strippedVersion);
137     }
138     else if (MINOR.equals(version))
139     {
140       previousVersion = calcPreviousMinor(strippedVersion);
141     }
142     else if (MICRO.equals(version))
143     {
144       previousVersion = calcPreviousMicro(strippedVersion);
145     }
146     else
147     {
148       previousVersion = version;
149     }
150 
151     return previousVersion;
152   }
153 
154   private String calcPreviousMajor(final String strippedVersion)
155   {
156     final String nextVersion;
157     final ArtifactVersion artifactVersion =
158         createArtifactVersion(strippedVersion);
159     if (artifactVersion == null)
160     {
161       throw new IllegalArgumentException("Cannot major decrement '"
162                                          + projectVersion + '.');
163     }
164 
165     final int currentVersion = artifactVersion.getMajorVersion();
166     if (currentVersion == 0)
167     {
168       throw new IllegalArgumentException("Cannot major decrement '"
169                                          + projectVersion + '.');
170     }
171 
172     final int minorVersion = artifactVersion.getMinorVersion();
173     final int microVersion = artifactVersion.getIncrementalVersion();
174     if (minorVersion == 0 && microVersion == 0)
175     {
176       final int previous = currentVersion - 1;
177       nextVersion = previous + ".0.0"; // NOPMD
178     }
179     else
180     {
181       nextVersion = currentVersion + ".0.0";
182     }
183     return nextVersion;
184   }
185 
186   private String calcPreviousMinor(final String strippedVersion)
187     throws IllegalArgumentException
188   {
189     final String previousVersion;
190     final ArtifactVersion artifactVersion =
191         createArtifactVersion(strippedVersion);
192     if (artifactVersion == null)
193     {
194       throw new IllegalArgumentException("Cannot minor decrement '"
195                                          + projectVersion + '.');
196     }
197 
198     final int currentVersion = artifactVersion.getMinorVersion();
199     if (currentVersion == 0)
200     {
201       final int currentIncrement = artifactVersion.getIncrementalVersion();
202 
203       if (currentIncrement == 0)
204       {
205         throw new IllegalArgumentException("Cannot minor decrement '"
206                                            + projectVersion + '.');
207       }
208 
209       final int previous = currentIncrement - 1;
210       previousVersion = artifactVersion.getMajorVersion() + ".0." + previous;
211     }
212     else
213     {
214       final int previous = currentVersion - 1;
215       previousVersion =
216           String.valueOf(artifactVersion.getMajorVersion()) + '.' + previous
217               + ".0";
218     }
219     return previousVersion;
220   }
221 
222   private String calcPreviousMicro(final String strippedVersion)
223     throws IllegalArgumentException
224   {
225     final String previousVersion;
226     final ArtifactVersion artifactVersion =
227         createArtifactVersion(strippedVersion);
228     if (artifactVersion == null)
229     {
230       throw new IllegalArgumentException("Cannot micro decrement '"
231                                          + projectVersion + '.');
232     }
233 
234     final int currentVersion = artifactVersion.getIncrementalVersion();
235     if (currentVersion == 0)
236     {
237       throw new IllegalArgumentException("Cannot micro decrement '"
238                                          + projectVersion + '.');
239     }
240 
241     final int previous = currentVersion - 1;
242     previousVersion =
243         String.valueOf(artifactVersion.getMajorVersion()) + '.'
244             + artifactVersion.getMinorVersion() + '.' + previous;
245     return previousVersion;
246   }
247 
248   /**
249    * Calculates the next version.
250    *
251    * @param version the version to analyze.
252    * @return the version if it is neither {@link #SNAPSHOT}, {@link #CURRENT},
253    *         {@link #MAJOR}, {@link #MINOR}, or {@link #MICRO}.
254    */
255   public String calculateNextVersion(final String version)
256   {
257     final String nextVersion;
258     if (MAJOR.equals(version))
259     {
260       nextVersion = calcNextMajor();
261     }
262     else if (MINOR.equals(version))
263     {
264       nextVersion = calcNextMinor();
265     }
266     else if (MICRO.equals(version))
267     {
268       nextVersion = calcNextMicro();
269     }
270     else if (CURRENT.equals(version))
271     {
272       nextVersion = getVersionStrippedFromSnapshotSuffix(projectVersion);
273     }
274     else if (SNAPSHOT.equals(version))
275     {
276       nextVersion = projectVersion;
277     }
278     else
279     {
280       nextVersion = version;
281     }
282 
283     return nextVersion;
284   }
285 
286   /**
287    * Returns the given version without the <code>-SNAPSHOT</code> suffix.
288    *
289    * @param version the version to strip.
290    * @return the stripped version or (if no suffix was present) the
291    *         {@code version}.
292    */
293   public static String getVersionStrippedFromSnapshotSuffix(final String version)
294   {
295     if (version.endsWith("-SNAPSHOT"))
296     {
297       return version.substring(0, version.length() - 9);
298     }
299     return version;
300   }
301 
302   private String calcNextMajor()
303   {
304     final String nextVersion;
305     final ArtifactVersion artifactVersion = createArtifactVersion();
306     if (artifactVersion == null)
307     {
308       return null;
309     }
310     final int next = artifactVersion.getMajorVersion() + 1;
311     nextVersion = next + ".0.0";
312     return nextVersion;
313   }
314 
315   private String calcNextMinor()
316   {
317     final String nextVersion;
318     final ArtifactVersion artifactVersion = createArtifactVersion();
319     if (artifactVersion == null)
320     {
321       return null;
322     }
323     final int next = artifactVersion.getMinorVersion() + 1;
324     nextVersion =
325         String.valueOf(artifactVersion.getMajorVersion()) + '.' + next + ".0";
326     return nextVersion;
327   }
328 
329   private String calcNextMicro()
330   {
331     final String nextVersion;
332     final ArtifactVersion artifactVersion = createArtifactVersion();
333     if (artifactVersion == null)
334     {
335       return null;
336     }
337     final int next = artifactVersion.getIncrementalVersion() + 1;
338     nextVersion =
339         String.valueOf(artifactVersion.getMajorVersion()) + '.'
340             + artifactVersion.getMinorVersion() + '.' + next;
341     return nextVersion;
342   }
343 
344   private ArtifactVersion createArtifactVersion()
345   {
346     return createArtifactVersion(projectVersion);
347   }
348 
349   private ArtifactVersion createArtifactVersion(final String version)
350   {
351     final ArtifactVersion artifactVersion = new DefaultArtifactVersion(version);
352     if (notRecognized(artifactVersion))
353     {
354       return null;
355     }
356     return artifactVersion;
357   }
358 
359   private static boolean notRecognized(final ArtifactVersion artifactVersion)
360   {
361     return (artifactVersion.getMajorVersion() == 0
362             && artifactVersion.getMinorVersion() == 0 && artifactVersion
363         .getIncrementalVersion() == 0);
364   }
365 
366   // --- object basics --------------------------------------------------------
367 
368 }