usr/src/java/rad/org/opensolaris/os/rad/ADRName.java
changeset 604 20d9acfeb7fb
parent 573 f0add9469f92
child 685 767674b0a2fb
--- a/usr/src/java/rad/org/opensolaris/os/rad/ADRName.java	Mon Nov 22 10:50:58 2010 -0500
+++ b/usr/src/java/rad/org/opensolaris/os/rad/ADRName.java	Tue Nov 23 15:54:20 2010 -0800
@@ -25,7 +25,9 @@
 
 package org.opensolaris.os.rad;
 
+import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.logging.Level;
@@ -37,6 +39,9 @@
     private String domain_;
     private TreeMap<String, String> kvs_ = new TreeMap<String, String>();
 
+    /* Wire-ordered keys to play jconsole's silly collation game */
+    private List<String> keys_ = new ArrayList<String>();
+
     public ADRName(ObjectName on) {
 	domain_ = on.getDomain();
 	Hashtable<String, String> keys = on.getKeyPropertyList();
@@ -83,6 +88,7 @@
 		if (pos == start || inkey)
 		    throw new IllegalArgumentException("Empty value: " + str);
 		kvs_.put(key, new String(scratch, 0, dst));
+		keys_.add(key);
 		dst = 0;
 		inkey = true;
 		start = pos + 1;
@@ -118,13 +124,30 @@
 	if (pos == start || inkey)
 	    throw new IllegalArgumentException("Empty value: " + str);
 	kvs_.put(key, new String(scratch, 0, dst));
+	keys_.add(key);
     }
 
     public ObjectName toObjectName() throws MalformedObjectNameException {
-	Hashtable<String, String> keys = new Hashtable<String, String>();
-	for (Map.Entry<String, String> e : kvs_.entrySet())
-	    keys.put(e.getKey(), ObjectName.quote(e.getValue()));
-	return new ObjectName(domain_, keys);
+	/*
+	 * In theory, ObjectName keys are unordered.  In practice, their
+	 * order is used as a hint to improve the appearance of jconsole.
+	 * Discordant as this is, the end result is actually pretty nice.
+	 *
+	 * Unfortunately, the only ObjectName constructor that chooses
+	 * practice over theory is the one that takes the string form, so
+	 * below we cons up a String so that ObjectName(String) can then
+	 * immediately undo our work and parse it.
+	 */
+	StringBuffer sb = new StringBuffer(domain_).append(':');
+	boolean first = true;
+	for (String key : keys_) {
+	    if (first)
+		first = false;
+	    else
+		sb.append(',');
+	    sb.append(key).append('=').append(ObjectName.quote(kvs_.get(key)));
+	}
+	return (new ObjectName(sb.toString()));
     }
 
     @Override