001    /**
002     * Copyright (c) 2000-2012 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            @Override
144            public boolean equals(Object obj) {
145                    if ((obj == null) || (!(obj instanceof Version))) {
146                            return false;
147                    }
148    
149                    Version version = (Version)obj;
150    
151                    String versionString1 = toString();
152                    String versionString2 = version.toString();
153    
154                    if (versionString1.equals(UNKNOWN) || versionString2.equals(UNKNOWN)) {
155                            return false;
156                    }
157    
158                    return versionString1.equals(versionString2);
159            }
160    
161            public String getBugFix() {
162                    if (_bugFix == null) {
163                            return "0";
164                    }
165    
166                    return _bugFix;
167            }
168    
169            public String getBuildNumber() {
170                    return _buildNumber;
171            }
172    
173            public String getMajor() {
174                    if (_major == null) {
175                            return "0";
176                    }
177    
178                    return _major;
179            }
180    
181            public String getMinor() {
182                    if (_minor == null) {
183                            return "0";
184                    }
185    
186                    return _minor;
187            }
188    
189            @Override
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            @Override
263            public String toString() {
264                    return _toString(_major, _minor, _bugFix, _buildNumber);
265            }
266    
267            protected Version(String version) {
268                    StringTokenizer st = new StringTokenizer(version, _SEPARATOR);
269    
270                    _major = st.nextToken();
271    
272                    if (st.hasMoreTokens()) {
273                            _minor = st.nextToken();
274                    }
275    
276                    if (st.hasMoreTokens()) {
277                            _bugFix = st.nextToken();
278                    }
279    
280                    StringBundler sb = new StringBundler();
281    
282                    while (st.hasMoreTokens()) {
283                            sb.append(st.nextToken());
284    
285                            if (st.hasMoreTokens()) {
286                                    sb.append(_SEPARATOR);
287                            }
288                    }
289    
290                    _buildNumber = sb.toString();
291            }
292    
293            private static boolean _contains(
294                    String containerString, String numberString) {
295    
296                    if (containerString.endsWith(StringPool.PLUS)) {
297                            String containerNumberString = containerString.substring(
298                                    0, containerString.length() - 1);
299    
300                            try {
301                                    int containerNumber = Integer.parseInt(containerNumberString);
302                                    int number = Integer.parseInt(numberString);
303    
304                                    return containerNumber <= number;
305                            }
306                            catch (NumberFormatException nfe) {
307                                    return false;
308                            }
309                    }
310    
311                    return false;
312            }
313    
314            private static String _toString(
315                    String major, String minor, String bugFix, String buildNumber) {
316    
317                    StringBundler sb = new StringBundler();
318    
319                    sb.append(major);
320    
321                    if (Validator.isNotNull(minor)) {
322                            sb.append(_SEPARATOR);
323                            sb.append(minor);
324    
325                            if (Validator.isNotNull(bugFix)) {
326                                    sb.append(_SEPARATOR);
327                                    sb.append(bugFix);
328    
329                                    if (Validator.isNotNull(buildNumber)) {
330                                            sb.append(_SEPARATOR);
331                                            sb.append(buildNumber);
332                                    }
333                            }
334                    }
335    
336                    return sb.toString();
337            }
338    
339            private static final String _SEPARATOR = StringPool.PERIOD;
340    
341            private static Map<String, Version> _versions =
342                    new ConcurrentHashMap<String, Version>();
343    
344            private String _bugFix;
345            private String _buildNumber;
346            private String _major;
347            private String _minor;
348    
349    }