# HG changeset patch # User dfuchs # Date 1217352119 -7200 # Node ID 55c9c5a88bde21010f7cb899d02442afcd526789 # Parent 40d3416d937ae292502f3adf0e2d8beff8918022 6402254: Revisit ModelMBean DescriptorSupport implementation of equals and hashCode. Reviewed-by: emcmanus diff -r 40d3416d937a -r 55c9c5a88bde jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Mon Jul 28 12:37:52 2008 -0700 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Tue Jul 29 19:21:59 2008 +0200 @@ -26,6 +26,7 @@ package com.sun.jmx.mbeanserver; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -113,4 +114,32 @@ public static T cast(Object x) { return (T) x; } + + /** + * Computes a descriptor hashcode from its names and values. + * @param names the sorted array of descriptor names. + * @param values the array of descriptor values. + * @return a hash code value, as described in {@link #hashCode(Descriptor)} + */ + public static int hashCode(String[] names, Object[] values) { + int hash = 0; + for (int i = 0; i < names.length; i++) { + Object v = values[i]; + int h; + if (v == null) { + h = 0; + } else if (v instanceof Object[]) { + h = Arrays.deepHashCode((Object[]) v); + } else if (v.getClass().isArray()) { + h = Arrays.deepHashCode(new Object[]{v}) - 31; + // hashcode of a list containing just v is + // v.hashCode() + 31, see List.hashCode() + } else { + h = v.hashCode(); + } + hash += names[i].toLowerCase().hashCode() ^ h; + } + return hash; + } + } diff -r 40d3416d937a -r 55c9c5a88bde jdk/src/share/classes/javax/management/ImmutableDescriptor.java --- a/jdk/src/share/classes/javax/management/ImmutableDescriptor.java Mon Jul 28 12:37:52 2008 -0700 +++ b/jdk/src/share/classes/javax/management/ImmutableDescriptor.java Tue Jul 29 19:21:59 2008 +0200 @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package javax.management; +import com.sun.jmx.mbeanserver.Util; import java.io.InvalidObjectException; import java.lang.reflect.Array; import java.util.Arrays; @@ -362,6 +363,7 @@ */ // Note: this Javadoc is copied from javax.management.Descriptor // due to 6369229. + @Override public boolean equals(Object o) { if (o == this) return true; @@ -410,29 +412,15 @@ */ // Note: this Javadoc is copied from javax.management.Descriptor // due to 6369229. + @Override public int hashCode() { if (hashCode == -1) { - int hash = 0; - for (int i = 0; i < names.length; i++) { - Object v = values[i]; - int h; - if (v == null) - h = 0; - else if (v instanceof Object[]) - h = Arrays.deepHashCode((Object[]) v); - else if (v.getClass().isArray()) { - h = Arrays.deepHashCode(new Object[] {v}) - 31; - // hashcode of a list containing just v is - // v.hashCode() + 31, see List.hashCode() - } else - h = v.hashCode(); - hash += names[i].toLowerCase().hashCode() ^ h; - } - hashCode = hash; + hashCode = Util.hashCode(names, values); } return hashCode; } + @Override public String toString() { StringBuilder sb = new StringBuilder("{"); for (int i = 0; i < names.length; i++) { @@ -479,6 +467,7 @@ * If the descriptor construction fails for any reason, this exception will * be thrown. */ + @Override public Descriptor clone() { return this; } diff -r 40d3416d937a -r 55c9c5a88bde jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java --- a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Mon Jul 28 12:37:52 2008 -0700 +++ b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Tue Jul 29 19:21:59 2008 +0200 @@ -33,6 +33,7 @@ import static com.sun.jmx.defaults.JmxProperties.MODELMBEAN_LOGGER; import static com.sun.jmx.mbeanserver.Util.cast; import com.sun.jmx.mbeanserver.GetPropertyAction; +import com.sun.jmx.mbeanserver.Util; import java.io.IOException; import java.io.ObjectInputStream; @@ -774,6 +775,7 @@ * fails for any reason, this exception will be thrown. */ + @Override public synchronized Object clone() throws RuntimeOperationsException { if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) { MODELMBEAN_LOGGER.logp(Level.FINEST, @@ -814,13 +816,16 @@ * otherwise. * */ - // XXXX TODO: This is not very efficient! // Note: this Javadoc is copied from javax.management.Descriptor // due to 6369229. + @Override public synchronized boolean equals(Object o) { if (o == this) return true; - + if (! (o instanceof Descriptor)) + return false; + if (o instanceof ImmutableDescriptor) + return o.equals(this); return new ImmutableDescriptor(descriptorMap).equals(o); } @@ -844,11 +849,16 @@ * @return A hash code value for this object. * */ - // XXXX TODO: This is not very efficient! // Note: this Javadoc is copied from javax.management.Descriptor // due to 6369229. + @Override public synchronized int hashCode() { - return new ImmutableDescriptor(descriptorMap).hashCode(); + final int size = descriptorMap.size(); + // descriptorMap is sorted with a comparator that ignores cases. + // + return Util.hashCode( + descriptorMap.keySet().toArray(new String[size]), + descriptorMap.values().toArray(new Object[size])); } /** @@ -1278,6 +1288,7 @@ * field Names or field Values. If the descriptor string fails * for any reason, this exception will be thrown. */ + @Override public synchronized String toString() { if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) { MODELMBEAN_LOGGER.logp(Level.FINEST,