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