001: /*
002: * Copyright 2005 Paul Hinds
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.tp23.antinstaller.runtime;
017:
018: import java.util.StringTokenizer;
019:
020: /**
021: * Version helper accepts version numbers of the following format.
022: * [major][clause].[minor][clause].[minor][clause].... ad infinitum
023: *
024: * If the Java flag is set to true an attempt is made to parse the string as if it were
025: * returned by System.getProperty("java.version");
026: * Since pre 1.3.1 the system is not parsable the default is to accept the string
027: * if there is a format error.
028: *
029: * For the non java syntax getting the string wrong will result in failed tests
030: * @author teknopaul
031: *
032: */
033: public class VersionHelper {
034:
035: public static final String CLAUSE_ALPHA = "alpha";
036: public static final String CLAUSE_BETA = "beta";
037: public static final String CLAUSE_GAMMA = "gamma";
038: public static final String CLAUSE_JAVA_BETA = "ea";
039:
040: public boolean equalOrHigher(final String test, final String version) {
041: return equalOrHigher(test, version, false);
042: }
043:
044: public boolean majorVersionCompatible(final String test,
045: final String version) {
046: return getMajorVersion(test) == getMajorVersion(version);
047: }
048:
049: /**
050: *
051: * @param test java version string being tested
052: * @param version java version string being used as reference
053: * @param javaSyntax
054: * @return true if the value of <code>test</code> is greater than or equal to the value of <code>version</code>
055: */
056: public boolean equalOrHigher(final String test,
057: final String version, final boolean javaSyntax) {
058: try {
059: StringTokenizer testSt = new StringTokenizer(test, ".");
060: StringTokenizer verSt = new StringTokenizer(version, ".");
061:
062: while (true) {
063: boolean testMore = testSt.hasMoreTokens();
064: boolean verMore = verSt.hasMoreTokens();
065: if (!testMore || !verMore) {
066: break;
067: }
068: String testToken = testSt.nextToken();
069: String verToken = verSt.nextToken();
070: short testVer = getVersion(testToken);
071: short versionVer = getVersion(verToken);
072: if (testVer == versionVer) {
073: if (equalClause(getClause(testToken),
074: getClause(verToken))) {
075: continue;
076: } else {
077: return higherClause(getClause(testToken),
078: getClause(verToken), javaSyntax);
079: }
080: }
081: return testVer > versionVer;
082: }
083: // equal up to one not having minor details
084: if (countDots(test) >= countDots(version)) {
085: return true;
086: }
087: return test.equals(version);
088: } catch (Exception e) {
089: // syntax exceptions
090: if (javaSyntax) {
091: return true; // return true for Java since pre 1.3.1 or other JVMs could get any old rubbish
092: }
093: return false;
094: }
095: }
096:
097: public boolean isValid(final String version) {
098: try {
099: StringTokenizer verSt = new StringTokenizer(version, ".");
100:
101: boolean verMore = false;
102: int i = 0;
103: for (; verMore = verSt.hasMoreTokens(); i++) {
104:
105: String verToken = verSt.nextToken();
106: if ("".equals(verToken)) {
107: return false;
108: }
109: // may throw NumberFormatExceptions
110: getVersion(verToken);
111: String clause = getClause(verToken);
112: if (!"".equals(clause)) {
113: short clauseS = clauseToShort(clause);
114: if (!(clauseS == 1 || clauseS == 2 || clauseS == 3)) {
115: return false;
116: }
117: }
118: }
119: if (!verMore && i == 0) {
120: return false; // nothing there!
121: }
122: return true;
123:
124: } catch (Exception e) {
125: // syntax exceptions
126: return false;
127: }
128: }
129:
130: /**
131: * @return the number part of the clause
132: */
133: private short getVersion(final String section) {
134: StringBuffer sb = new StringBuffer();
135: for (int i = 0; i < section.length(); i++) {
136: char c = section.charAt(i);
137: if (Character.isDigit(c)) {
138: sb.append(c);
139: } else {
140: return Short.parseShort(sb.toString());
141: }
142: }
143: if (sb.length() > 0) {
144: return Short.parseShort(sb.toString());
145: }
146: return 0;
147: }
148:
149: /**
150: * @return the clause eg beta or ""
151: */
152: private String getClause(final String section) {
153: for (int i = 0; i < section.length(); i++) {
154: char c = section.charAt(i);
155: if (Character.isDigit(c)) {
156: continue;
157: } else {
158: return section.substring(i);
159: }
160: }
161: return "";
162: }
163:
164: private boolean higherClause(final String test,
165: final String clause, final boolean javaSyntax) {
166: if (javaSyntax) {
167: return clauseJavaToShort(test) > clauseJavaToShort(clause);
168: } else {
169: return clauseToShort(test) > clauseToShort(clause);
170: }
171:
172: }
173:
174: private boolean equalClause(final String test, final String clause) {
175: return clauseToShort(test) == clauseToShort(clause);
176: }
177:
178: private short clauseToShort(String clause) {
179: if (clause.startsWith("-")) {
180: clause = clause.substring(1); // knock off java style 1-beta dashes
181: }
182: if (CLAUSE_ALPHA.equals(clause)) {
183: return 3;
184: } else if (CLAUSE_BETA.equals(clause)) {
185: return 2;
186: } else if (CLAUSE_GAMMA.equals(clause)) {
187: return 1;
188: }
189: if (clause.startsWith("_")) { // java build version support 1_03-ea-beta (discarding the sub sub clause "-ea-beta" because I'm lazy)
190: int hasDash = clause.indexOf('-');
191: if (hasDash > -1) {
192: return Short.parseShort(clause.substring(1, hasDash));
193: } else {
194: return Short.parseShort(clause.substring(1));
195: }
196: } else
197: return Short.MAX_VALUE; // no clause assumes higher
198: }
199:
200: private short clauseJavaToShort(String clause) {
201: if (clause.startsWith("-")) {
202: clause = clause.substring(1); // knock off java style 1-beta dashes
203: } else if (CLAUSE_JAVA_BETA.equals(clause)) { // -ea early access are assumed to be less good
204: return -2;
205: }
206: if (clause.startsWith("_")) { // java build version support 1_03-ea-beta (discarding the sub sub clause "-ea-beta" because I'm lazy)
207: int hasDash = clause.indexOf('-');
208: if (hasDash > -1) {
209: return Short.parseShort(clause.substring(1, hasDash));
210: } else {
211: return Short.parseShort(clause.substring(1));
212: }
213: } else
214: return 0; // no clause assumes lower in Java speak
215: }
216:
217: private short countDots(final String fullver) {
218: short count = 0;
219: for (int i = 0; i < fullver.length(); i++) {
220: if (fullver.charAt(i) == '.') {
221: count++;
222: }
223: }
224: return count;
225: }
226:
227: private short getMajorVersion(String test) {
228: return getVersion(test);
229: }
230:
231: }
|