[FELIX-4820] Optimize version range parsing a bit
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1663615 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/utils/src/main/java/org/apache/felix/utils/version/VersionCleaner.java b/utils/src/main/java/org/apache/felix/utils/version/VersionCleaner.java
index 4b2078b..d9f89d6 100644
--- a/utils/src/main/java/org/apache/felix/utils/version/VersionCleaner.java
+++ b/utils/src/main/java/org/apache/felix/utils/version/VersionCleaner.java
@@ -42,6 +42,11 @@
{
return "0.0.0";
}
+ String clean = fastSyntax(version);
+ if (clean != null)
+ {
+ return clean;
+ }
StringBuffer result = new StringBuffer();
Matcher m = FUZZY_VERSION.matcher(version);
if (m.matches())
@@ -108,4 +113,45 @@
}
}
+ private static String fastSyntax(String version) {
+ int state = 0;
+ for (int i = 0, l = version.length(); i < l; i++) {
+ char ch = version.charAt(i);
+ switch (state) {
+ case 0:
+ case 2:
+ case 4:
+ if (ch < '0' || ch > '9') {
+ return null;
+ }
+ state++;
+ break;
+ case 1:
+ case 3:
+ case 5:
+ if (ch == '.') {
+ state++;
+ } else if (ch < '0' || ch > '9') {
+ return null;
+ }
+ break;
+ case 6:
+ if (ch == '.') {
+ return null;
+ }
+ break;
+ }
+ }
+ switch (state) {
+ case 0:
+ case 1:
+ return version + ".0.0";
+ case 2:
+ case 3:
+ return version + ".0";
+ default:
+ return version;
+ }
+ }
+
}
diff --git a/utils/src/main/java/org/apache/felix/utils/version/VersionRange.java b/utils/src/main/java/org/apache/felix/utils/version/VersionRange.java
index 5379665..c2279ca 100644
--- a/utils/src/main/java/org/apache/felix/utils/version/VersionRange.java
+++ b/utils/src/main/java/org/apache/felix/utils/version/VersionRange.java
@@ -101,8 +101,7 @@
public VersionRange( String val, boolean exact, boolean clean ) throws IllegalArgumentException, NumberFormatException
{
- val = val.replaceAll( "\\s", "" );
- val = val.replaceAll( "\"", "" );
+ val = removeQuotesAndWhitespaces(val);
int fst = val.charAt( 0 );
if ( fst == '[' )
{
@@ -136,17 +135,53 @@
+ ": range must end in ')' or ']'" );
}
- String inner = val.substring( 1, val.length() - 1 );
- String[] floorCeiling = inner.split( "," );
- if ( floorCeiling.length != 2 )
+ int comma = val.indexOf( ',' );
+ if ( comma < 0 )
+ {
+ throw new IllegalArgumentException( "illegal version range syntax " + "no comma" );
+ }
+ if ( val.indexOf( ',', comma + 1 ) > 0 )
{
throw new IllegalArgumentException( "illegal version range syntax " + "too many commas" );
}
- floor = VersionTable.getVersion( floorCeiling[0], clean );
- ceiling = "*".equals( floorCeiling[1] ) ? INFINITE_VERSION : VersionTable.getVersion( floorCeiling[1], clean );
+ String strFloor = val.substring( 1, comma );
+ String strCeil = val.substring( comma + 1, val.length() - 1 );
+ floor = VersionTable.getVersion( strFloor, clean );
+ ceiling = "*".equals( strCeil ) ? INFINITE_VERSION : VersionTable.getVersion( strCeil, clean );
checkRange();
}
+ private String removeQuotesAndWhitespaces(String val) {
+ for (int i = 0, l = val.length(); i < l; i++) {
+ char ch = val.charAt(i);
+ if (isRemoveable(ch)) {
+ StringBuilder sb = new StringBuilder(l);
+ sb.append(val, 0, i);
+ for (i++; i < l; i++) {
+ ch = val.charAt(i);
+ if (!isRemoveable(ch)) {
+ sb.append(ch);
+ }
+ }
+ return sb.toString();
+ }
+ }
+ return val;
+ }
+
+ private static boolean[] removeable;
+ static {
+ removeable = new boolean[256];
+ for (int i = 0; i < 256; i++) {
+ removeable[i] = Character.isWhitespace(i);
+ }
+ removeable['"'] = true;
+ }
+
+ private boolean isRemoveable(char ch) {
+ return ch < 256 ? removeable[ch] : Character.isWhitespace(ch);
+ }
+
public static VersionRange parseVersionRange( String val ) throws IllegalArgumentException, NumberFormatException
{
if ( val == null || val.trim().length() == 0 )