1   /**
2    * Copyright (c) 2000-2007 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.util;
24  
25  import com.liferay.portal.kernel.util.StringMaker;
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  
32  /**
33   * <a href="Version.java.html"><b><i>View Source</i></b></a>
34   *
35   * @author Jorge Ferrer
36   *
37   */
38  public class Version implements Comparable {
39  
40      public static final String UNKNOWN = "unknown";
41  
42      public static Version getInstance(String version) {
43          Version versionObj = (Version)_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 String getMajor() {
55          if (_major == null) {
56              return "0";
57          }
58  
59          return _major;
60      }
61  
62      public String getMinor() {
63          if (_minor == null) {
64              return "0";
65          }
66  
67          return _minor;
68      }
69  
70      public String getBugFix() {
71          if (_bugFix == null) {
72              return "0";
73          }
74  
75          return _bugFix;
76      }
77  
78      public String getBuildNumber() {
79          return _buildNumber;
80      }
81  
82      public boolean isLaterVersionThan(String version) {
83          if (compareTo(getInstance(version)) > 0) {
84              return true;
85          }
86          else {
87              return false;
88          }
89      }
90  
91      public boolean isPreviousVersionThan(String version) {
92          if (compareTo(getInstance(version)) < 0) {
93              return true;
94          }
95          else {
96              return false;
97          }
98      }
99  
100     public boolean isSameVersionAs(String version) {
101         if (compareTo(getInstance(version)) == 0) {
102             return true;
103         }
104         else {
105             return false;
106         }
107     }
108 
109     public boolean includes(Version version) {
110         if (equals(version)) {
111             return true;
112         }
113 
114         if (getMajor().equals(StringPool.STAR)) {
115             return true;
116         }
117 
118         if (getMajor().equals(version.getMajor())) {
119             if (getMinor().equals(StringPool.STAR)) {
120                 return true;
121             }
122 
123             if (getMinor().equals(version.getMinor())) {
124                 if (getBugFix().equals(StringPool.STAR)) {
125                     return true;
126                 }
127 
128                 if (getBugFix().equals(version.getBugFix())) {
129                     if (getBuildNumber().equals(StringPool.STAR) ||
130                         getBuildNumber().equals(version.getBuildNumber())) {
131 
132                         return true;
133                     }
134                 }
135                 else if (_contains(getBugFix(), version.getBugFix())) {
136                     return true;
137                 }
138             }
139             else if (_contains(getMinor(), version.getMinor())) {
140                 return true;
141             }
142         }
143         else if (_contains(getMajor(), version.getMajor())) {
144             return true;
145         }
146 
147         return false;
148     }
149 
150     public int compareTo(Object obj) {
151         if ((obj == null) || (!(obj instanceof Version))) {
152             return 1;
153         }
154 
155         Version version = (Version)obj;
156 
157         // Unknown is always considered a lower version
158 
159         if (version.toString().equals(UNKNOWN)) {
160             return 1;
161         }
162 
163         if (toString().equals(UNKNOWN)) {
164             return -1;
165         }
166 
167         int result = getMajor().compareTo(version.getMajor());
168 
169         if (result != 0) {
170             return result;
171         }
172 
173         result = getMinor().compareTo(version.getMinor());
174 
175         if (result != 0) {
176             return result;
177         }
178 
179         result = getBugFix().compareTo(version.getBugFix());
180 
181         if (result != 0) {
182             return result;
183         }
184 
185         return getBuildNumber().compareTo(version.getBuildNumber());
186     }
187 
188     public boolean equals(Object obj) {
189         if ((obj == null) || (!(obj instanceof Version))) {
190             return false;
191         }
192 
193         Version version = (Version)obj;
194 
195         String versionString1 = toString();
196         String versionString2 = version.toString();
197 
198         if (versionString1.equals(UNKNOWN) || versionString2.equals(UNKNOWN)) {
199             return false;
200         }
201 
202         return versionString1.equals(versionString2);
203     }
204 
205     public int hashCode() {
206         return toString().hashCode();
207     }
208 
209     public String toString() {
210         StringMaker sm = new StringMaker();
211 
212         sm.append(_major);
213 
214         if (Validator.isNotNull(_minor)) {
215             sm.append(_SEPARATOR);
216             sm.append(_minor);
217 
218             if (Validator.isNotNull(_bugFix)) {
219                 sm.append(_SEPARATOR);
220                 sm.append(_bugFix);
221 
222                 if (Validator.isNotNull(_buildNumber)) {
223                     sm.append(_SEPARATOR);
224                     sm.append(_buildNumber);
225                 }
226             }
227         }
228 
229         return sm.toString();
230     }
231 
232     protected Version(String version) {
233         StringTokenizer st = new StringTokenizer(version, _SEPARATOR);
234 
235         _major = st.nextToken();
236 
237         if (st.hasMoreTokens()) {
238             _minor = st.nextToken();
239         }
240 
241         if (st.hasMoreTokens()) {
242             _bugFix = st.nextToken();
243         }
244 
245         StringMaker buildNumber = new StringMaker();
246 
247         while (st.hasMoreTokens()) {
248             buildNumber.append(st.nextToken());
249 
250             if (st.hasMoreTokens()) {
251                 buildNumber.append(_SEPARATOR);
252             }
253         }
254 
255         _buildNumber = buildNumber.toString();
256     }
257 
258     private boolean _contains(String containerStr, String numberStr) {
259         if (containerStr.endsWith(StringPool.PLUS)) {
260             String containerNumberStr =
261                     containerStr.substring(0, containerStr.length() - 1);
262 
263             try {
264                 int containerNumber = Integer.parseInt(containerNumberStr);
265                 int number = Integer.parseInt(numberStr);
266 
267                 return containerNumber <= number;
268             } catch (NumberFormatException nfe) {
269                 return false;
270             }
271         }
272         return false;
273     }
274 
275     private static final String _SEPARATOR = StringPool.PERIOD;
276 
277     private static Map _versions = CollectionFactory.getSyncHashMap();
278 
279     private String _major;
280     private String _minor;
281     private String _bugFix;
282     private String _buildNumber;
283 
284 }