/* Utils.java Purpose: Description: History: Wed Jul 11 14:47:08 2007, Created by tomyeh Copyright (C) 2007 Potix Corporation. All Rights Reserved. {{IS_RIGHT This program is distributed under LGPL Version 2.1 in the hope that it will be useful, but WITHOUT ANY WARRANTY. }}IS_RIGHT */ package org.zkoss.util; import java.util.List; import java.util.LinkedList; /** * Generic utilities. * * @author tomyeh * @since 3.0.0 */ public class Utils { /** Returns a portion of the specified version in an integer, * or 0 if no such portion exists. * * <p>For example, getSubversion(0) returns the so-called major version * (2 in "2.4.0"), and getSubversion(1) returns the so-called * minor version (4 in "2.4.0"). * * <p>Note: alpha is consider as -500, beta -300, and rc -100. * Moreover, beta3 is -497 (= -500 + 3) and rc5 -95 (-100 + 5) * * @param version the version. The version is assumed to * a series of integer separated by a non-alphanumeric separator. * @param portion which portion of the version; starting from 0. * If you want to retrieve the major version, specify 0. * @since 3.0.0 */ public static final int getSubversion(String version, int portion) { if (portion < 0) throw new IllegalArgumentException("Negative not allowed: "+portion); final int len = version.length(); int j = 0; while (--portion >= 0) { j = nextVerSeparator(version, j) + 1; if (j >= len) return 0; //no such portion } return convertSubversion( version.substring(j, nextVerSeparator(version, j))); } /** Parses the specified version into an array of integer. * For example, parseVersion("3.5.2") will return [3, 5, 2]. * @since 3.5.2 */ public static final int[] parseVersion(String version) { final List<Integer> vers = new LinkedList<Integer>(); for (int j = 0, len = version.length(); j < len;) { int k = nextVerSeparator(version, j); vers.add(new Integer(convertSubversion(version.substring(j, k)))); j = k + 1; } final int[] ivs = new int[vers.size()]; int j = 0; for (Integer ver: vers) ivs[j++] = ver.intValue(); return ivs; } /** Compares two version. * @return 0 if equals, 1 if the first one is larger, -1 if smaller. * @since 3.5.2 */ public static final int compareVersion(int[] v1, int[] v2) { for (int j = 0;; ++j) { if (j == v1.length) { for (; j < v2.length; ++j) { if (v2[j] > 0) return -1; if (v2[j] < 0) return 1; } return 0; } if (j == v2.length) { for (; j < v1.length; ++j) { if (v1[j] > 0) return 1; if (v1[j] < 0) return -1; } return 0; } if (v1[j] > v2[j]) return 1; if (v1[j] < v2[j]) return -1; } } private static final int convertSubversion(String subver) { try { return Integer.parseInt(subver); } catch (Throwable ex) { //eat } subver = subver.toLowerCase(java.util.Locale.ENGLISH); final int base, j; if (subver.startsWith("rc")) { base = -100; j = 2; } else if (subver.startsWith("beta")) { base = -300; j = 4; } else if (subver.startsWith("alpha")) { base = -500; j = 5; } else { return 0; //unknown } if (j < subver.length()) { try { return base + Integer.parseInt(subver.substring(j)); } catch (Throwable ex) { //eat } } return base; } private static final int nextVerSeparator(String version, int from) { for (final int len = version.length(); from < len; ++from) { final char cc = version.charAt(from); if ((cc < '0' || cc > '9') && (cc < 'a' || cc > 'z') && (cc < 'A' || cc > 'Z')) break; } return from; } }