-package org.simantics.document.server.client;\r
-\r
-import java.util.Comparator;\r
-\r
-/**\r
- * This is an updated version with enhancements made by Daniel Migowski,\r
- * Andre Bogus, and David Koelle\r
- *\r
- * To convert to use Templates (Java 1.5+):\r
- * - Change "implements Comparator" to "implements Comparator<String>"\r
- * - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)"\r
- * - Remove the type checking and casting in compare().\r
- *\r
- * To use this class:\r
- * Use the static "sort" method from the java.util.Collections class:\r
- * Collections.sort(your list, new AlphanumComparator());\r
- */\r
-public class AlphanumericComparator implements Comparator<String>\r
-{\r
- private final boolean isDigit(char ch)\r
- {\r
- return ch >= 48 && ch <= 57;\r
- }\r
-\r
- /** Length of string is passed in for improved efficiency (only need to calculate it once) **/\r
- private final String getChunk(String s, int slength, int marker)\r
- {\r
- StringBuilder chunk = new StringBuilder();\r
- char c = s.charAt(marker);\r
- chunk.append(c);\r
- marker++;\r
- if (isDigit(c))\r
- {\r
- while (marker < slength)\r
- {\r
- c = s.charAt(marker);\r
- if (!isDigit(c))\r
- break;\r
- chunk.append(c);\r
- marker++;\r
- }\r
- } else\r
- {\r
- while (marker < slength)\r
- {\r
- c = s.charAt(marker);\r
- if (isDigit(c))\r
- break;\r
- chunk.append(c);\r
- marker++;\r
- }\r
- }\r
- return chunk.toString();\r
- }\r
-\r
- public int compare(String o1, String o2)\r
- {\r
- if (!(o1 instanceof String) || !(o2 instanceof String))\r
- {\r
- return 0;\r
- }\r
- String s1 = (String)o1;\r
- String s2 = (String)o2;\r
-\r
- int thisMarker = 0;\r
- int thatMarker = 0;\r
- int s1Length = s1.length();\r
- int s2Length = s2.length();\r
-\r
- while (thisMarker < s1Length && thatMarker < s2Length)\r
- {\r
- String thisChunk = getChunk(s1, s1Length, thisMarker);\r
- thisMarker += thisChunk.length();\r
-\r
- String thatChunk = getChunk(s2, s2Length, thatMarker);\r
- thatMarker += thatChunk.length();\r
-\r
- // If both chunks contain numeric characters, sort them numerically\r
- int result = 0;\r
- if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))\r
- {\r
- // Simple chunk comparison by length.\r
- int thisChunkLength = thisChunk.length();\r
- result = thisChunkLength - thatChunk.length();\r
- // If equal, the first different number counts\r
- if (result == 0)\r
- {\r
- for (int i = 0; i < thisChunkLength; i++)\r
- {\r
- result = thisChunk.charAt(i) - thatChunk.charAt(i);\r
- if (result != 0)\r
- {\r
- return result;\r
- }\r
- }\r
- }\r
- } else\r
- {\r
- result = thisChunk.compareTo(thatChunk);\r
- }\r
-\r
- if (result != 0)\r
- return result;\r
- }\r
-\r
- return s1Length - s2Length;\r
- }\r
-\r
-}\r
-\r
+package org.simantics.document.server.client;
+
+import java.util.Comparator;
+
+/**
+ * This is an updated version with enhancements made by Daniel Migowski,
+ * Andre Bogus, and David Koelle
+ *
+ * To convert to use Templates (Java 1.5+):
+ * - Change "implements Comparator" to "implements Comparator<String>"
+ * - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)"
+ * - Remove the type checking and casting in compare().
+ *
+ * To use this class:
+ * Use the static "sort" method from the java.util.Collections class:
+ * Collections.sort(your list, new AlphanumComparator());
+ */
+public class AlphanumericComparator implements Comparator<String>
+{
+ private final boolean isDigit(char ch)
+ {
+ return ch >= 48 && ch <= 57;
+ }
+
+ /** Length of string is passed in for improved efficiency (only need to calculate it once) **/
+ private final String getChunk(String s, int slength, int marker)
+ {
+ StringBuilder chunk = new StringBuilder();
+ char c = s.charAt(marker);
+ chunk.append(c);
+ marker++;
+ if (isDigit(c))
+ {
+ while (marker < slength)
+ {
+ c = s.charAt(marker);
+ if (!isDigit(c))
+ break;
+ chunk.append(c);
+ marker++;
+ }
+ } else
+ {
+ while (marker < slength)
+ {
+ c = s.charAt(marker);
+ if (isDigit(c))
+ break;
+ chunk.append(c);
+ marker++;
+ }
+ }
+ return chunk.toString();
+ }
+
+ public int compare(String o1, String o2)
+ {
+ if (!(o1 instanceof String) || !(o2 instanceof String))
+ {
+ return 0;
+ }
+ String s1 = (String)o1;
+ String s2 = (String)o2;
+
+ int thisMarker = 0;
+ int thatMarker = 0;
+ int s1Length = s1.length();
+ int s2Length = s2.length();
+
+ while (thisMarker < s1Length && thatMarker < s2Length)
+ {
+ String thisChunk = getChunk(s1, s1Length, thisMarker);
+ thisMarker += thisChunk.length();
+
+ String thatChunk = getChunk(s2, s2Length, thatMarker);
+ thatMarker += thatChunk.length();
+
+ // If both chunks contain numeric characters, sort them numerically
+ int result = 0;
+ if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
+ {
+ // Simple chunk comparison by length.
+ int thisChunkLength = thisChunk.length();
+ result = thisChunkLength - thatChunk.length();
+ // If equal, the first different number counts
+ if (result == 0)
+ {
+ for (int i = 0; i < thisChunkLength; i++)
+ {
+ result = thisChunk.charAt(i) - thatChunk.charAt(i);
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+ }
+ } else
+ {
+ result = thisChunk.compareTo(thatChunk);
+ }
+
+ if (result != 0)
+ return result;
+ }
+
+ return s1Length - s2Length;
+ }
+
+}
+