View Javadoc

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