diff --git a/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java b/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java
index 753a29b..9c33bbb 100644
--- a/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java
+++ b/src/main/java/org/gatein/rhq/plugins/PortalDiscoveryCallback.java
@@ -5,9 +5,6 @@
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryCallback;
-import java.util.HashMap;
-import java.util.Map;
-
/**
* @author Nick Scavelli
*/
@@ -18,6 +15,7 @@ public class PortalDiscoveryCallback implements ResourceDiscoveryCallback
private static final String CONFIG_PRODUCT_NAME = "expectedRuntimeProductName";
private static final String PRODUCT_NAME = "Portal";
+ private static final String VERSION_RENAMED_TO_JBOSS_Portal = "6.1.1.GA";
@Override
public DiscoveryCallbackResults discoveredResources(DiscoveredResourceDetails discoveredResourceDetails) throws Exception
@@ -32,18 +30,7 @@ public DiscoveryCallbackResults discoveredResources(DiscoveredResourceDetails di
String version = discoveredResourceDetails.getResourceVersion();
String name = discoveredResourceDetails.getResourceName();
- // small hack: we check if the version is higher than 6.1.1, as the logic is the same for all known subsequent versions
- // first, we discard everything after the last dot, as it's usually the release-level string (GA, ER1, ER2, CR1...)
- // then, we get only the numeric chars, and the resulting should be a string with length of 3
- String cleanedVersion = version.substring(0, version.lastIndexOf(".")).replaceAll("[^\\d]", "");
- if (null == cleanedVersion || cleanedVersion.length() > 3)
- {
- throw new IllegalArgumentException("Couldn't reliably determine the Portal version for '" + version + "'");
- }
-
- int versionAsInteger = Integer.parseInt(cleanedVersion);
- if (versionAsInteger >= 611)
- {
+ if (VersionComparator.instance().compare(VERSION_RENAMED_TO_JBOSS_Portal, version) <= 0) {
if (trace)
{
String before = discoveredResourceDetails.getPluginConfiguration().getSimpleValue(CONFIG_PRODUCT_NAME);
@@ -52,7 +39,6 @@ public DiscoveryCallbackResults discoveredResources(DiscoveredResourceDetails di
discoveredResourceDetails.getPluginConfiguration().setSimpleValue(CONFIG_PRODUCT_NAME, PRODUCT_NAME);
result = DiscoveryCallbackResults.PROCESSED;
}
-
return result;
}
diff --git a/src/main/java/org/gatein/rhq/plugins/VersionComparator.java b/src/main/java/org/gatein/rhq/plugins/VersionComparator.java
new file mode 100644
index 0000000..1918d6d
--- /dev/null
+++ b/src/main/java/org/gatein/rhq/plugins/VersionComparator.java
@@ -0,0 +1,139 @@
+package org.gatein.rhq.plugins;
+
+import java.util.Comparator;
+
+/**
+ * Comparator for software versions like {@code "6.2"}, {@code "6.2.0"}, {@code "6.2.0.GA"}, etc.
+ *
+ * @author Peter Palaga
+ */
+public class VersionComparator implements Comparator
+{
+ /**
+ * A stream of version string parts.
+ */
+ static class VersionTokenizer
+ {
+ private int position = 0;
+ private final int length;
+ private final String source;
+ private int counter = 0;
+ private final int numericComponentsCount;
+
+ public VersionTokenizer(String source, int numericComponentsCount)
+ {
+ super();
+ this.source = source;
+ this.numericComponentsCount = numericComponentsCount;
+ this.length = source.length();
+ }
+
+ /**
+ * @return next version part delimited either by period or end of input
+ */
+ private String next()
+ {
+ if (position >= length)
+ {
+ return null;
+ }
+ int end = source.indexOf(DELIMITER, position);
+ int start = position;
+ if (end >= 0)
+ {
+ position = end + 1;
+ } else
+ {
+ position = length;
+ end = length;
+ }
+ return source.substring(start, end);
+ }
+
+ /**
+ * @return next {@code int} version part delimited either by period or end of input
+ * @throws NumberFormatException if the current part cannot be parset as {@code int}
+ * @throws IllegalArgumentException if some of the parts is parsed into a negative integer
+ */
+ public int nextInt()
+ {
+ if (counter >= numericComponentsCount)
+ {
+ throw new IllegalStateException(this.getClass().getSimpleName()
+ + ".nextInt() cannot be invoked more than "
+ + numericComponentsCount + " times.");
+ }
+ counter++;
+ String token = next();
+ if (token == null)
+ {
+ return DEFAULT_NUMERIC_COMPONENT;
+ }
+ int result = Integer.valueOf(token);
+ if (result < 0)
+ {
+ throw new IllegalArgumentException("Version string '" + source
+ + "' contains negative component " + result);
+ }
+ return result;
+ }
+
+ /**
+ * @return the rest of the input from the current position to the input end
+ */
+ public String rest()
+ {
+ if (position >= length)
+ {
+ return DEFAULT_QUALIFIER;
+ }
+ int start = position;
+ position = length;
+ return source.substring(start);
+ }
+
+ }
+
+ /**
+ * @return the singleton instance of {@link VersionComparator}
+ */
+ public static VersionComparator instance()
+ {
+ return INSTANCE;
+ }
+
+ /** The singleton. */
+ private static final VersionComparator INSTANCE = new VersionComparator();
+
+ /** The period character - the delimiter of version parts. */
+ public static final int DELIMITER = '.';
+
+ /** Literal {@code "GA"} returned if there is no qualifier in the input. */
+ public static final String DEFAULT_QUALIFIER = "GA";
+
+ /** Literal {@code 0} returned if the input is missing minor or micro version part. */
+ public static final int DEFAULT_NUMERIC_COMPONENT = 0;
+
+ /** {@code 3} - the number of numeric parts in a version string. */
+ public static final int MAJOR_MINOR_MICRO = 3;
+
+ /** For thrown exceptions, see {@link VersionTokenizer#nextInt()}.
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(String version1, String version2)
+ {
+ VersionTokenizer t1 = new VersionTokenizer(version1, MAJOR_MINOR_MICRO);
+ VersionTokenizer t2 = new VersionTokenizer(version2, MAJOR_MINOR_MICRO);
+ for (int i = 0; i < MAJOR_MINOR_MICRO; i++)
+ {
+ int compare = Integer.compare(t1.nextInt(), t2.nextInt());
+ if (compare != 0)
+ {
+ return compare;
+ }
+ }
+ return t1.rest().compareTo(t2.rest());
+ }
+
+}
diff --git a/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java b/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java
index 64ec007..1ecffc2 100644
--- a/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java
+++ b/src/test/java/org/gatein/rhq/plugins/PortalDiscoveryCallbackTest.java
@@ -33,6 +33,20 @@ public void testVersionIs611() throws Exception
Configuration configuration = new Configuration();
ResourceType type = new ResourceType();
+ DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.1.1", "", configuration, null);
+ ResourceDiscoveryCallback.DiscoveryCallbackResults results = new PortalDiscoveryCallback().discoveredResources(details);
+
+ assertEquals(ResourceDiscoveryCallback.DiscoveryCallbackResults.PROCESSED, results);
+ assertEquals("Portal", details.getPluginConfiguration().getSimpleValue("expectedRuntimeProductName"));
+ }
+
+
+ @Test
+ public void testVersionIs611GA() throws Exception
+ {
+ Configuration configuration = new Configuration();
+ ResourceType type = new ResourceType();
+
DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.1.1.GA", "", configuration, null);
ResourceDiscoveryCallback.DiscoveryCallbackResults results = new PortalDiscoveryCallback().discoveredResources(details);
@@ -41,7 +55,7 @@ public void testVersionIs611() throws Exception
}
@Test
- public void testVersionHigherThan611() throws Exception
+ public void test620ER3HigherThan611() throws Exception
{
Configuration configuration = new Configuration();
ResourceType type = new ResourceType();
@@ -53,13 +67,36 @@ public void testVersionHigherThan611() throws Exception
assertEquals("Portal", details.getPluginConfiguration().getSimpleValue("expectedRuntimeProductName"));
}
+ @Test
+ public void test620HigherThan611() throws Exception
+ {
+ Configuration configuration = new Configuration();
+ ResourceType type = new ResourceType();
+
+ DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.2.0", "", configuration, null);
+ ResourceDiscoveryCallback.DiscoveryCallbackResults results = new PortalDiscoveryCallback().discoveredResources(details);
+
+ assertEquals(ResourceDiscoveryCallback.DiscoveryCallbackResults.PROCESSED, results);
+ assertEquals("Portal", details.getPluginConfiguration().getSimpleValue("expectedRuntimeProductName"));
+ }
+
@Test(expected = IllegalArgumentException.class)
- public void testFailOnUnknownVersion() throws Exception
+ public void testFailOnMalformedVersion() throws Exception
+ {
+ Configuration configuration = new Configuration();
+ ResourceType type = new ResourceType();
+
+ DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.-2.0.ER3", "", configuration, null);
+ new PortalDiscoveryCallback().discoveredResources(details);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void testFailOnMalformedVersion2() throws Exception
{
Configuration configuration = new Configuration();
ResourceType type = new ResourceType();
- DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.22.0.ER3", "", configuration, null);
+ DiscoveredResourceDetails details = new DiscoveredResourceDetails(type, "bogus", "JPP Something", "6.1.GA", "", configuration, null);
new PortalDiscoveryCallback().discoveredResources(details);
}
diff --git a/src/test/java/org/gatein/rhq/plugins/VersionComparatorTest.java b/src/test/java/org/gatein/rhq/plugins/VersionComparatorTest.java
new file mode 100644
index 0000000..abdf780
--- /dev/null
+++ b/src/test/java/org/gatein/rhq/plugins/VersionComparatorTest.java
@@ -0,0 +1,60 @@
+package org.gatein.rhq.plugins;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class VersionComparatorTest
+{
+ @Test
+ public void test()
+ {
+ ensureNFE("6.2.GA");
+
+ test("1", "1.0", 0);
+ test("1", "1.0.0", 0);
+ test("1", "1.0.0.GA", 0);
+
+ test("1", "2", -1);
+ test("9", "11", -1);
+ test("1.0.0.DR1", "1.0.0.DR2", -1);
+ test("1.0.0.DR10", "1.0.0.ER2", -1);
+
+ ensureNFE("1.GA");
+ ensureNFE("1.0.GA");
+ ensureNFE("1-GA");
+
+ ensureIAE("-1");
+ ensureIAE("1.-1");
+ ensureIAE("1.1.-1");
+
+ }
+
+ private void ensureNFE(String v)
+ {
+ try
+ {
+ VersionComparator.instance().compare(v, v);
+ Assert.fail("NumberFormatException expected");
+ } catch (NumberFormatException expected)
+ {
+ }
+ }
+
+ private void ensureIAE(String v)
+ {
+ try
+ {
+ VersionComparator.instance().compare(v, v);
+ Assert.fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException expected)
+ {
+ }
+ }
+
+ private static void test(String v1, String v2, int expected)
+ {
+ Assert.assertEquals("'"+ v1 + "' ? '"+ v2 +"'", expected, VersionComparator.instance().compare(v1, v2));
+ Assert.assertEquals("'"+ v2 + "' ? '"+ v1 +"'", -expected, VersionComparator.instance().compare(v2, v1));
+ }
+
+}