001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.plugin;
016    
017    import com.liferay.portal.kernel.util.GetterUtil;
018    import com.liferay.portal.kernel.util.StringBundler;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.Validator;
021    
022    import java.io.Serializable;
023    
024    import java.util.Map;
025    import java.util.StringTokenizer;
026    import java.util.concurrent.ConcurrentHashMap;
027    
028    /**
029     * @author Jorge Ferrer
030     */
031    public class Version implements Comparable<Version>, Serializable {
032    
033            public static final String UNKNOWN = "unknown";
034    
035            public static Version getInstance(String version) {
036                    Version versionObj = _versions.get(version);
037    
038                    if (versionObj == null) {
039                            versionObj = new Version(version);
040    
041                            _versions.put(version, versionObj);
042                    }
043    
044                    return versionObj;
045            }
046    
047            public static Version incrementBugFix(Version version) {
048                    String bugFix = version.getBugFix();
049    
050                    int bugFixInt = GetterUtil.getInteger(bugFix);
051    
052                    if (bugFixInt > 0) {
053                            bugFix = String.valueOf(bugFixInt + 1);
054                    }
055    
056                    return getInstance(
057                            _toString(
058                                    version.getMajor(), version.getMinor(), bugFix,
059                                    version.getBuildNumber()));
060            }
061    
062            public static Version incrementBuildNumber(Version version) {
063                    String buildNumber = version.getBuildNumber();
064    
065                    int buildNumberInt = GetterUtil.getInteger(buildNumber);
066    
067                    if (buildNumberInt > 0) {
068                            buildNumber = String.valueOf(buildNumberInt + 1);
069                    }
070    
071                    return getInstance(
072                            _toString(
073                                    version.getMajor(), version.getMinor(), version.getBugFix(),
074                                    buildNumber));
075            }
076    
077            public static Version incrementMajor(Version version) {
078                    String major = version.getMajor();
079    
080                    int majorInt = GetterUtil.getInteger(major);
081    
082                    if (majorInt > 0) {
083                            major = String.valueOf(majorInt + 1);
084                    }
085    
086                    return getInstance(
087                            _toString(
088                                    major, version.getMinor(), version.getBugFix(),
089                                    version.getBuildNumber()));
090            }
091    
092            public static Version incrementMinor(Version version) {
093                    String minor = version.getMinor();
094    
095                    int minorInt = GetterUtil.getInteger(minor);
096    
097                    if (minorInt > 0) {
098                            minor = String.valueOf(minorInt + 1);
099                    }
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    }