1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.kernel.plugin;
16  
17  import com.liferay.portal.kernel.util.GetterUtil;
18  import com.liferay.portal.kernel.util.StringBundler;
19  import com.liferay.portal.kernel.util.StringPool;
20  import com.liferay.portal.kernel.util.Validator;
21  
22  import java.io.Serializable;
23  
24  import java.util.Map;
25  import java.util.StringTokenizer;
26  import java.util.concurrent.ConcurrentHashMap;
27  
28  /**
29   * <a href="Version.java.html"><b><i>View Source</i></b></a>
30   *
31   * @author Jorge Ferrer
32   */
33  public class Version implements Comparable<Version>, Serializable {
34  
35      public static final String UNKNOWN = "unknown";
36  
37      public static Version getInstance(String version) {
38          Version versionObj = _versions.get(version);
39  
40          if (versionObj == null) {
41              versionObj = new Version(version);
42  
43              _versions.put(version, versionObj);
44          }
45  
46          return versionObj;
47      }
48  
49      public static Version incrementBugFix(Version version) {
50          String bugFix = version.getBugFix();
51  
52          int bugFixInt = GetterUtil.getInteger(bugFix);
53  
54          if (bugFixInt > 0) {
55              bugFix = String.valueOf(bugFixInt + 1);
56          }
57  
58          return getInstance(
59              _toString(
60                  version.getMajor(), version.getMinor(), bugFix,
61                  version.getBuildNumber()));
62      }
63  
64      public static Version incrementBuildNumber(Version version) {
65          String buildNumber = version.getBuildNumber();
66  
67          int buildNumberInt = GetterUtil.getInteger(buildNumber);
68  
69          if (buildNumberInt > 0) {
70              buildNumber = String.valueOf(buildNumberInt + 1);
71          }
72  
73          return getInstance(
74              _toString(
75                  version.getMajor(), version.getMinor(), version.getBugFix(),
76                  buildNumber));
77      }
78  
79      public static Version incrementMajor(Version version) {
80          String major = version.getMajor();
81  
82          int majorInt = GetterUtil.getInteger(major);
83  
84          if (majorInt > 0) {
85              major = String.valueOf(majorInt + 1);
86          }
87  
88          return getInstance(
89              _toString(
90                  major, version.getMinor(), version.getBugFix(),
91                  version.getBuildNumber()));
92      }
93  
94      public static Version incrementMinor(Version version) {
95          String minor = version.getMinor();
96  
97          int minorInt = GetterUtil.getInteger(minor);
98  
99          if (minorInt > 0) {
100             minor = String.valueOf(minorInt + 1);
101         }
102 
103         return getInstance(
104             _toString(
105                 version.getMajor(), minor, version.getBugFix(),
106                 version.getBuildNumber()));
107     }
108 
109     public int compareTo(Version version) {
110         if (version == null) {
111             return 1;
112         }
113 
114         // Unknown is always considered a lower version
115 
116         if (version.toString().equals(UNKNOWN)) {
117             return 1;
118         }
119 
120         if (toString().equals(UNKNOWN)) {
121             return -1;
122         }
123 
124         int result = getMajor().compareTo(version.getMajor());
125 
126         if (result != 0) {
127             return result;
128         }
129 
130         result = getMinor().compareTo(version.getMinor());
131 
132         if (result != 0) {
133             return result;
134         }
135 
136         result = getBugFix().compareTo(version.getBugFix());
137 
138         if (result != 0) {
139             return result;
140         }
141 
142         return getBuildNumber().compareTo(version.getBuildNumber());
143     }
144 
145     public boolean equals(Object obj) {
146         if ((obj == null) || (!(obj instanceof Version))) {
147             return false;
148         }
149 
150         Version version = (Version)obj;
151 
152         String versionString1 = toString();
153         String versionString2 = version.toString();
154 
155         if (versionString1.equals(UNKNOWN) || versionString2.equals(UNKNOWN)) {
156             return false;
157         }
158 
159         return versionString1.equals(versionString2);
160     }
161 
162     public String getBugFix() {
163         if (_bugFix == null) {
164             return "0";
165         }
166 
167         return _bugFix;
168     }
169 
170     public String getBuildNumber() {
171         return _buildNumber;
172     }
173 
174     public String getMajor() {
175         if (_major == null) {
176             return "0";
177         }
178 
179         return _major;
180     }
181 
182     public String getMinor() {
183         if (_minor == null) {
184             return "0";
185         }
186 
187         return _minor;
188     }
189 
190     public int hashCode() {
191         return toString().hashCode();
192     }
193 
194     public boolean includes(Version version) {
195         if (equals(version)) {
196             return true;
197         }
198 
199         if (getMajor().equals(StringPool.STAR)) {
200             return true;
201         }
202 
203         if (getMajor().equals(version.getMajor())) {
204             if (getMinor().equals(StringPool.STAR)) {
205                 return true;
206             }
207 
208             if (getMinor().equals(version.getMinor())) {
209                 if (getBugFix().equals(StringPool.STAR)) {
210                     return true;
211                 }
212 
213                 if (getBugFix().equals(version.getBugFix())) {
214                     if (getBuildNumber().equals(StringPool.STAR) ||
215                         getBuildNumber().equals(version.getBuildNumber())) {
216 
217                         return true;
218                     }
219                 }
220                 else if (_contains(getBugFix(), version.getBugFix())) {
221                     return true;
222                 }
223             }
224             else if (_contains(getMinor(), version.getMinor())) {
225                 return true;
226             }
227         }
228         else if (_contains(getMajor(), version.getMajor())) {
229             return true;
230         }
231 
232         return false;
233     }
234 
235     public boolean isLaterVersionThan(String version) {
236         if (compareTo(getInstance(version)) > 0) {
237             return true;
238         }
239         else {
240             return false;
241         }
242     }
243 
244     public boolean isPreviousVersionThan(String version) {
245         if (compareTo(getInstance(version)) < 0) {
246             return true;
247         }
248         else {
249             return false;
250         }
251     }
252 
253     public boolean isSameVersionAs(String version) {
254         if (compareTo(getInstance(version)) == 0) {
255             return true;
256         }
257         else {
258             return false;
259         }
260     }
261 
262     public String toString() {
263         return _toString(_major, _minor, _bugFix, _buildNumber);
264     }
265 
266     protected Version(String version) {
267         StringTokenizer st = new StringTokenizer(version, _SEPARATOR);
268 
269         _major = st.nextToken();
270 
271         if (st.hasMoreTokens()) {
272             _minor = st.nextToken();
273         }
274 
275         if (st.hasMoreTokens()) {
276             _bugFix = st.nextToken();
277         }
278 
279         StringBundler sb = new StringBundler();
280 
281         while (st.hasMoreTokens()) {
282             sb.append(st.nextToken());
283 
284             if (st.hasMoreTokens()) {
285                 sb.append(_SEPARATOR);
286             }
287         }
288 
289         _buildNumber = sb.toString();
290     }
291 
292     private static boolean _contains(
293         String containerString, String numberString) {
294 
295         if (containerString.endsWith(StringPool.PLUS)) {
296             String containerNumberString = containerString.substring(
297                 0, containerString.length() - 1);
298 
299             try {
300                 int containerNumber = Integer.parseInt(containerNumberString);
301                 int number = Integer.parseInt(numberString);
302 
303                 return containerNumber <= number;
304             }
305             catch (NumberFormatException nfe) {
306                 return false;
307             }
308         }
309 
310         return false;
311     }
312 
313     private static String _toString(
314         String major, String minor, String bugFix, String buildNumber) {
315 
316         StringBundler sb = new StringBundler();
317 
318         sb.append(major);
319 
320         if (Validator.isNotNull(minor)) {
321             sb.append(_SEPARATOR);
322             sb.append(minor);
323 
324             if (Validator.isNotNull(bugFix)) {
325                 sb.append(_SEPARATOR);
326                 sb.append(bugFix);
327 
328                 if (Validator.isNotNull(buildNumber)) {
329                     sb.append(_SEPARATOR);
330                     sb.append(buildNumber);
331                 }
332             }
333         }
334 
335         return sb.toString();
336     }
337 
338     private static final String _SEPARATOR = StringPool.PERIOD;
339 
340     private static Map<String, Version> _versions =
341         new ConcurrentHashMap<String, Version>();
342 
343     private String _bugFix;
344     private String _buildNumber;
345     private String _major;
346     private String _minor;
347 
348 }