Source for javax.management.openmbean.TabularType

   1: /* TabularType.java -- Type descriptor for TabularData instances.
   2:    Copyright (C) 2006, 2007 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package javax.management.openmbean;
  39: 
  40: import java.util.Arrays;
  41: import java.util.Collections;
  42: import java.util.Iterator;
  43: import java.util.List;
  44: 
  45: /**
  46:  * The open type descriptor for instances of the
  47:  * {@link TabularData} class.
  48:  *
  49:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  50:  * @since 1.5
  51:  */
  52: public class TabularType
  53:   extends OpenType<TabularData>
  54: {
  55: 
  56:   /**
  57:    * Compatible with JDK 1.5
  58:    */
  59:   private static final long serialVersionUID = 6554071860220659261L;
  60: 
  61:   /**
  62:    * The composite type used by the rows of the table.
  63:    */
  64:   private CompositeType rowType;
  65: 
  66:   /**
  67:    * The list of index names, which form the columns of the table.
  68:    * They are retained in the order given by the user, and is
  69:    * unmodifiable.
  70:    */
  71:   private List<String> indexNames;
  72: 
  73:   /**
  74:    * The hash code of this instance.
  75:    */
  76:   private transient Integer hashCode;
  77: 
  78:   /**
  79:    * The <code>toString()</code> result of this instance.
  80:    */
  81:   private transient String string;
  82: 
  83:   /**
  84:    * <p>
  85:    * Constructs a new {@link TabularType} instance for the given
  86:    * type name, description, row type and index names.  All parameters
  87:    * (including the individual elements of the array of index names)
  88:    * must be non-null and those that are of type {@link java.lang.String}
  89:    * must be non-empty.  The array of index names must also be non-empty.
  90:    * </p>
  91:    * <p>
  92:    * The result of <code>TabularData.class.getName()</code> is adopted
  93:    * as the class name (see {@link OpenType}).  The ordering of the array
  94:    * elements is relevant in determining the indicies of the values in the
  95:    * table, and thus in the use of the
  96:    * {@link TabularData#get(java.lang.Object[])} and
  97:    * {@link TabularData#remove(java.lang.Object[])} methods of the
  98:    * {@link TabularData} class.
  99:    * </p>
 100:    *
 101:    * @param name the name of this tabular type.
 102:    * @param desc a description of this tabular type.
 103:    * @param rowType the type of the rows of the table.
 104:    * @param indexNames the names used to index the rows within the table.
 105:    * @throws IllegalArgumentException if any validity constraint listed above
 106:    *                                  is broken.
 107:    * @throws OpenDataException if an index name does not match a corresponding
 108:    *                           name in the given row type.
 109:    */
 110:   public TabularType(String name, String desc, CompositeType rowType,
 111:                      String[] indexNames)
 112:     throws OpenDataException
 113:   {
 114:     super(TabularData.class.getName(), name, desc);
 115:     if (rowType == null)
 116:       throw new IllegalArgumentException("A null row type was given.");
 117:     for (int a = 0; a < indexNames.length; ++a)
 118:       {
 119:         if (indexNames[a] == null)
 120:           throw new IllegalArgumentException("Name " + a +
 121:                                              " is null.");
 122:         if (indexNames[a].length() == 0)
 123:           throw new IllegalArgumentException("Name " + a +
 124:                                              " is the empty string.");
 125:         if (!(rowType.containsKey(indexNames[a])))
 126:           throw new OpenDataException("No matching key for " +
 127:                                       indexNames[a] + " was found in " +
 128:                                       "the supplied row type.");
 129:       }
 130:     this.rowType = rowType;
 131:     this.indexNames = Collections.unmodifiableList(Arrays.asList(indexNames));
 132:   }
 133: 
 134:   /**
 135:    * <p>
 136:    * Compares this tabular data type with another object
 137:    * for equality.  The objects are judged to be equal if:
 138:    * </p>
 139:    * <ul>
 140:    * <li><code>obj</code> is not null.</li>
 141:    * <li><code>obj</code> is an instance of
 142:    * {@link TabularType}.</li>
 143:    * <li>The type names are equal.</li>
 144:    * <li>The row types are equal.</li>
 145:    * <li>The index names are equal and in the same order.</li>
 146:    * </ul>
 147:    *
 148:    * @param obj the object to compare with.
 149:    * @return true if the conditions above hold.
 150:    */
 151:   public boolean equals(Object obj)
 152:   {
 153:     if (!(obj instanceof TabularType))
 154:       return false;
 155:     TabularType ttype = (TabularType) obj;
 156:     return  (ttype.getTypeName().equals(getTypeName())
 157:              && (ttype.getRowType().equals(getRowType()))
 158:              && (ttype.getIndexNames().equals(getIndexNames())));
 159:   }
 160: 
 161:   /**
 162:    * Returns an unmodifiable list containing the index names.
 163:    * The ordering of these names is used to determine the indicies
 164:    * of the {@link CompositeData} values, and is retained from that
 165:    * used in the call to this object's constructor.
 166:    *
 167:    * @return an unmodifiable list of the index names used by this
 168:    *         tabular data structure.
 169:    */
 170:   public List<String> getIndexNames()
 171:   {
 172:     return indexNames;
 173:   }
 174: 
 175:   /**
 176:    * Returns the type of the rows used by this tabular data structure.
 177:    *
 178:    * @return the row type.
 179:    */
 180:   public CompositeType getRowType()
 181:   {
 182:     return rowType;
 183:   }
 184: 
 185:   /**
 186:    * <p>
 187:    * Returns the hash code of the tabular data type.
 188:    * This is computed as the sum of the hash codes of the
 189:    * index names together with the hash code of the type
 190:    * name and row type.  These are the same elements
 191:    * of the type that are compared as part of the
 192:    * {@link #equals(java.lang.Object)} method, thus ensuring
 193:    * that the hashcode is compatible with the equality
 194:    * test.
 195:    * </p>
 196:    * <p>
 197:    * As instances of this class are immutable, the hash code
 198:    * is computed just once for each instance and reused
 199:    * throughout its life.
 200:    * </p>
 201:    *
 202:    * @return the hash code of this instance.
 203:    */
 204:   public int hashCode()
 205:   {
 206:     if (hashCode == null)
 207:       {
 208:         int elementTotal = 0;
 209:         for (String s : indexNames)
 210:           elementTotal += s.hashCode();
 211:         hashCode = Integer.valueOf(elementTotal
 212:                                    + getTypeName().hashCode()
 213:                                    + rowType.hashCode());
 214:       }
 215:     return hashCode.intValue();
 216:   }
 217: 
 218:   /**
 219:    * Returns true if the specified object is a member of this
 220:    * tabular type.  The object is judged to be so if it is
 221:    * an instance of {@link TabularData} with an equivalent
 222:    * type, according to the definition of
 223:    * {@link #equals(java.lang.Object)} for {@link TabularType}.
 224:    *
 225:    * @param obj the object to test for membership.
 226:    * @return true if the object is a member of this type.
 227:    */
 228:   public boolean isValue(Object obj)
 229:   {
 230:     if (obj instanceof TabularData)
 231:       {
 232:         TabularData data = (TabularData) obj;
 233:         return equals(data.getTabularType());
 234:       }
 235:     return false;
 236:   }
 237: 
 238:   /**
 239:    * <p>
 240:    * Returns a textual representation of this instance.  This
 241:    * is constructed using the class name
 242:    * (<code>javax.management.openmbean.TabularType</code>)
 243:    * and each element of the instance which is relevant to
 244:    * the definition of {@link equals(java.lang.Object)} and
 245:    * {@link hashCode()} (i.e. the type name, the row type
 246:    * and the index names).
 247:    * </p>
 248:    * <p>
 249:    * As instances of this class are immutable, the return value
 250:    * is computed just once for each instance and reused
 251:    * throughout its life.
 252:    * </p>
 253:    *
 254:    * @return a @link{java.lang.String} instance representing
 255:    *         the instance in textual form.
 256:    */
 257:   public String toString()
 258:   {
 259:     if (string == null)
 260:       string = getClass().getName()
 261:         + "[name=" + getTypeName()
 262:         + ", rowType=" + rowType
 263:         + ", indexNames=" + indexNames
 264:         + "]";
 265:     return string;
 266:   }
 267: 
 268: }