1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.kernel.plugin;
24  
25  import com.liferay.portal.kernel.util.GetterUtil;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.kernel.util.Validator;
28  
29  import java.util.Map;
30  import java.util.StringTokenizer;
31  import java.util.concurrent.ConcurrentHashMap;
32  
33  /**
34   * <a href="Version.java.html"><b><i>View Source</i></b></a>
35   *
36   * @author Jorge Ferrer
37   */
38  public class Version implements Comparable<Version> {
39  
40      public static final String UNKNOWN = "unknown";
41  
42      public static Version getInstance(String version) {
43          Version versionObj = _versions.get(version);
44  
45          if (versionObj == null) {
46              versionObj = new Version(version);
47  
48              _versions.put(version, versionObj);
49          }
50  
51          return versionObj;
52      }
53  
54      public static Version incrementBugFix(Version version) {
55          String bugFix = version.getBugFix();
56  
57          int bugFixInt = GetterUtil.getInteger(bugFix);
58  
59          if (bugFixInt > 0) {
60              bugFix = String.valueOf(bugFixInt + 1);
61          }
62  
63          return getInstance(
64              _toString(
65                  version.getMajor(), version.getMinor(), bugFix,
66                  version.getBuildNumber()));
67      }
68  
69      public static Version incrementBuildNumber(Version version) {
70          String buildNumber = version.getBuildNumber();
71  
72          int buildNumberInt = GetterUtil.getInteger(buildNumber);
73  
74          if (buildNumberInt > 0) {
75              buildNumber = String.valueOf(buildNumberInt + 1);
76          }
77  
78          return getInstance(
79              _toString(
80                  version.getMajor(), version.getMinor(), version.getBugFix(),
81                  buildNumber));
82      }
83  
84      public static Version incrementMajor(Version version) {
85          String major = version.getMajor();
86  
87          int majorInt = GetterUtil.getInteger(major);
88  
89          if (majorInt > 0) {
90              major = String.valueOf(majorInt + 1);
91          }
92  
93          return getInstance(
94              _toString(
95                  major, version.getMinor(), version.getBugFix(),
96                  version.getBuildNumber()));
97      }
98  
99      public static Version incrementMinor(Version version) {
100         String minor = version.getMinor();
101 
102         int minorInt = GetterUtil.getInteger(minor);
103 
104         if (minorInt > 0) {
105             minor = String.valueOf(minorInt + 1);
106         }
107 
108         return getInstance(
109             _toString(
110                 version.getMajor(), minor, version.getBugFix(),
111                 version.getBuildNumber()));
112     }
113 
114     public int compareTo(Version version) {
115         if (version == null) {
116             return 1;
117         }
118 
119         // Unknown is always considered a lower version
120 
121         if (version.toString().equals(UNKNOWN)) {
122             return 1;
123         }
124 
125         if (toString().equals(UNKNOWN)) {
126             return -1;
127         }
128 
129         int result = getMajor().compareTo(version.getMajor());
130 
131         if (result != 0) {
132             return result;
133         }
134 
135         result = getMinor().compareTo(version.getMinor());
136 
137         if (result != 0) {
138             return result;
139         }
140 
141         result = getBugFix().compareTo(version.getBugFix());
142 
143         if (result != 0) {
144             return result;
145         }
146 
147         return getBuildNumber().compareTo(version.getBuildNumber());
148     }
149 
150     public boolean equals(Object obj) {
151         if ((obj == null) || (!(obj instanceof Version))) {
152             return false;
153         }
154 
155         Version version = (Version)obj;
156 
157         String versionString1 = toString();
158         String versionString2 = version.toString();
159 
160         if (versionString1.equals(UNKNOWN) || versionString2.equals(UNKNOWN)) {
161             return false;
162         }
163 
164         return versionString1.equals(versionString2);
165     }
166 
167     public String getBugFix() {
168         if (_bugFix == null) {
169             return "0";
170         }
171 
172         return _bugFix;
173     }
174 
175     public String getBuildNumber() {
176         return _buildNumber;
177     }
178 
179     public String getMajor() {
180         if (_major == null) {
181             return "0";
182         }
183 
184         return _major;
185     }
186 
187     public String getMinor() {
188         if (_minor == null) {
189             return "0";
190         }
191 
192         return _minor;
193     }
194 
195     public int hashCode() {
196         return toString().hashCode();
197     }
198 
199     public boolean includes(Version version) {
200         if (equals(version)) {
201             return true;
202         }
203 
204         if (getMajor().equals(StringPool.STAR)) {
205             return true;
206         }
207 
208         if (getMajor().equals(version.getMajor())) {
209             if (getMinor().equals(StringPool.STAR)) {
210                 return true;
211             }
212 
213             if (getMinor().equals(version.getMinor())) {
214                 if (getBugFix().equals(StringPool.STAR)) {
215                     return true;
216                 }
217 
218                 if (getBugFix().equals(version.getBugFix())) {
219                     if (getBuildNumber().equals(StringPool.STAR) ||
220                         getBuildNumber().equals(version.getBuildNumber())) {
221 
222                         return true;
223                     }
224                 }
225                 else if (_contains(getBugFix(), version.getBugFix())) {
226                     return true;
227                 }
228             }
229             else if (_contains(getMinor(), version.getMinor())) {
230                 return true;
231             }
232         }
233         else if (_contains(getMajor(), version.getMajor())) {
234             return true;
235         }
236 
237         return false;
238     }
239 
240     public boolean isLaterVersionThan(String version) {
241         if (compareTo(getInstance(version)) > 0) {
242             return true;
243         }
244         else {
245             return false;
246         }
247     }
248 
249     public boolean isPreviousVersionThan(String version) {
250         if (compareTo(getInstance(version)) < 0) {
251             return true;
252         }
253         else {
254             return false;
255         }
256     }
257 
258     public boolean isSameVersionAs(String version) {
259         if (compareTo(getInstance(version)) == 0) {
260             return true;
261         }
262         else {
263             return false;
264         }
265     }
266 
267     public String toString() {
268         return _toString(_major, _minor, _bugFix, _buildNumber);
269     }
270 
271     protected Version(String version) {
272         StringTokenizer st = new StringTokenizer(version, _SEPARATOR);
273 
274         _major = st.nextToken();
275 
276         if (st.hasMoreTokens()) {
277             _minor = st.nextToken();
278         }
279 
280         if (st.hasMoreTokens()) {
281             _bugFix = st.nextToken();
282         }
283 
284         StringBuilder sb = new StringBuilder();
285 
286         while (st.hasMoreTokens()) {
287             sb.append(st.nextToken());
288 
289             if (st.hasMoreTokens()) {
290                 sb.append(_SEPARATOR);
291             }
292         }
293 
294         _buildNumber = sb.toString();
295     }
296 
297     private static boolean _contains(
298         String containerString, String numberString) {
299 
300         if (containerString.endsWith(StringPool.PLUS)) {
301             String containerNumberString = containerString.substring(
302                 0, containerString.length() - 1);
303 
304             try {
305                 int containerNumber = Integer.parseInt(containerNumberString);
306                 int number = Integer.parseInt(numberString);
307 
308                 return containerNumber <= number;
309             }
310             catch (NumberFormatException nfe) {
311                 return false;
312             }
313         }
314 
315         return false;
316     }
317 
318     private static String _toString(
319         String major, String minor, String bugFix, String buildNumber) {
320 
321         StringBuilder sb = new StringBuilder();
322 
323         sb.append(major);
324 
325         if (Validator.isNotNull(minor)) {
326             sb.append(_SEPARATOR);
327             sb.append(minor);
328 
329             if (Validator.isNotNull(bugFix)) {
330                 sb.append(_SEPARATOR);
331                 sb.append(bugFix);
332 
333                 if (Validator.isNotNull(buildNumber)) {
334                     sb.append(_SEPARATOR);
335                     sb.append(buildNumber);
336                 }
337             }
338         }
339 
340         return sb.toString();
341     }
342 
343     private static final String _SEPARATOR = StringPool.PERIOD;
344 
345     private static Map<String, Version> _versions =
346         new ConcurrentHashMap<String, Version>();
347 
348     private String _bugFix;
349     private String _buildNumber;
350     private String _major;
351     private String _minor;
352 
353 }