jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 1018 9f07e65e9653
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
package javax.management.openmbean;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
// java import
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.ObjectInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.io.Serializable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.util.Collection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.util.Collections;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.util.Iterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.util.Set;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
// jmx import
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
//
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * The <tt>TabularDataSupport</tt> class is the <i>open data</i> class which implements the <tt>TabularData</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * and the <tt>Map</tt> interfaces, and which is internally based on a hash map data structure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
/* It would make much more sense to implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
   Map<List<?>,CompositeData> here, but unfortunately we cannot for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
   compatibility reasons.  If we did that, then we would have to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
   define e.g.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
   CompositeData remove(Object)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
   instead of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
   Object remove(Object).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
   That would mean that if any existing code subclassed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
   TabularDataSupport and overrode
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
   Object remove(Object),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
   it would (a) no longer compile and (b) not actually override
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
   CompositeData remove(Object)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
   in binaries compiled before the change.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
public class TabularDataSupport
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    implements TabularData, Map<Object,Object>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
               Cloneable, Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    /* Serial version */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    static final long serialVersionUID = 5720150593236309827L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     * @serial This tabular data instance's contents: a {@link HashMap}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private Map<Object,CompositeData> dataMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * @serial This tabular data instance's tabular type
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private TabularType tabularType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * The array of item names that define the index used for rows (convenience field)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    private transient String[] indexNamesArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    /* *** Constructors *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * Creates an empty <tt>TabularDataSupport</tt> instance whose open-type is <var>tabularType</var>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * and whose underlying <tt>HashMap</tt> has a default initial capacity (101) and default load factor (0.75).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * This constructor simply calls <tt>this(tabularType, 101, 0.75f);</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * @param  tabularType               the <i>tabular type</i> describing this <tt>TabularData</tt> instance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     *                                   cannot be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * @throws IllegalArgumentException  if the tabular type is null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    public TabularDataSupport(TabularType tabularType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        this(tabularType, 101, 0.75f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * Creates an empty <tt>TabularDataSupport</tt> instance whose open-type is <var>tabularType</var>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * and whose underlying <tt>HashMap</tt> has the specified initial capacity and load factor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * @param  tabularType               the <i>tabular type</i> describing this <tt>TabularData</tt> instance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     *                           cannot be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * @param  initialCapacity   the initial capacity of the HashMap.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * @param  loadFactor        the load factor of the HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * @throws IllegalArgumentException  if the initial capacity is less than zero,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     *                                   or the load factor is nonpositive,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     *                                   or the tabular type is null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    public TabularDataSupport(TabularType tabularType, int initialCapacity, float loadFactor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        // Check tabularType is not null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        if (tabularType == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            throw new IllegalArgumentException("Argument tabularType cannot be null.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        // Initialize this.tabularType (and indexNamesArray for convenience)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        this.tabularType = tabularType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        List<String> tmpNames = tabularType.getIndexNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        this.indexNamesArray = tmpNames.toArray(new String[tmpNames.size()]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        // Construct the empty contents HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        this.dataMap =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            new HashMap<Object,CompositeData>(initialCapacity, loadFactor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    /* *** TabularData specific information methods *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * Returns the <i>tabular type</i> describing this <tt>TabularData</tt> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    public TabularType getTabularType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        return tabularType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * Calculates the index that would be used in this <tt>TabularData</tt> instance to refer to the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * composite data <var>value</var> parameter if it were added to this instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * This method checks for the type validity of the specified <var>value</var>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * but does not check if the calculated index is already used to refer to a value in this <tt>TabularData</tt> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * @param  value                      the composite data value whose index in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     *                                    <tt>TabularData</tt> instance is to be calculated;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     *                                    must be of the same composite type as this instance's row type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     *                                    must not be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * @return the index that the specified <var>value</var> would have in this <tt>TabularData</tt> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     * @throws NullPointerException       if <var>value</var> is <tt>null</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     * @throws InvalidOpenTypeException   if <var>value</var> does not conform to this <tt>TabularData</tt> instance's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     *                                    row type definition.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    public Object[] calculateIndex(CompositeData value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        // Check value is valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        checkValueType(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        // Return its calculated index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        return internalCalculateIndex(value).toArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    /* *** Content information query methods *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * Returns <tt>true</tt> if and only if this <tt>TabularData</tt> instance contains a <tt>CompositeData</tt> value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     * (ie a row) whose index is the specified <var>key</var>. If <var>key</var> cannot be cast to a one dimension array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * of Object instances, this method simply returns <tt>false</tt>; otherwise it returns the the result of the call to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     * <tt>this.containsKey((Object[]) key)</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * @param  key  the index value whose presence in this <tt>TabularData</tt> instance is to be tested.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * @return  <tt>true</tt> if this <tt>TabularData</tt> indexes a row value with the specified key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    public boolean containsKey(Object key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        // if key is not an array of Object instances, return false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        Object[] k;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            k = (Object[]) key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        } catch (ClassCastException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        return  this.containsKey(k);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * Returns <tt>true</tt> if and only if this <tt>TabularData</tt> instance contains a <tt>CompositeData</tt> value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * (ie a row) whose index is the specified <var>key</var>. If <var>key</var> is <tt>null</tt> or does not conform to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * this <tt>TabularData</tt> instance's <tt>TabularType</tt> definition, this method simply returns <tt>false</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * @param  key  the index value whose presence in this <tt>TabularData</tt> instance is to be tested.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * @return  <tt>true</tt> if this <tt>TabularData</tt> indexes a row value with the specified key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    public boolean containsKey(Object[] key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        return  ( key == null ? false : dataMap.containsKey(Arrays.asList(key)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * Returns <tt>true</tt> if and only if this <tt>TabularData</tt> instance contains the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * <tt>CompositeData</tt> value. If <var>value</var> is <tt>null</tt> or does not conform to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * this <tt>TabularData</tt> instance's row type definition, this method simply returns <tt>false</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * @param  value  the row value whose presence in this <tt>TabularData</tt> instance is to be tested.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * @return  <tt>true</tt> if this <tt>TabularData</tt> instance contains the specified row value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    public boolean containsValue(CompositeData value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        return dataMap.containsValue(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * Returns <tt>true</tt> if and only if this <tt>TabularData</tt> instance contains the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * @param  value  the row value whose presence in this <tt>TabularData</tt> instance is to be tested.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * @return  <tt>true</tt> if this <tt>TabularData</tt> instance contains the specified row value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    public boolean containsValue(Object value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        return dataMap.containsValue(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     * This method simply calls <tt>get((Object[]) key)</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * @throws NullPointerException  if the <var>key</var> is <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * @throws ClassCastException    if the <var>key</var> is not of the type <tt>Object[]</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * @throws InvalidKeyException   if the <var>key</var> does not conform to this <tt>TabularData</tt> instance's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     *                               <tt>TabularType</tt> definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    public Object get(Object key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        return get((Object[]) key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * Returns the <tt>CompositeData</tt> value whose index is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * <var>key</var>, or <tt>null</tt> if there is no value mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * to <var>key</var>, in this <tt>TabularData</tt> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * @param key the index of the value to get in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     * <tt>TabularData</tt> instance; * must be valid with this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * <tt>TabularData</tt> instance's row type definition; * must not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * @return the value corresponding to <var>key</var>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * @throws NullPointerException  if the <var>key</var> is <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     * @throws InvalidKeyException   if the <var>key</var> does not conform to this <tt>TabularData</tt> instance's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     *                               <tt>TabularType</tt> type definition.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    public CompositeData get(Object[] key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        // Check key is not null and valid with tabularType
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        // (throws NullPointerException, InvalidKeyException)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        checkKeyType(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        // Return the mapping stored in the parent HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        return dataMap.get(Arrays.asList(key));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    /* *** Content modification operations (one element at a time) *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * This method simply calls <tt>put((CompositeData) value)</tt> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * therefore ignores its <var>key</var> parameter which can be <tt>null</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * @param key an ignored parameter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * @param value the {@link CompositeData} to put.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * @return the value which is put
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * @throws NullPointerException  if the <var>value</var> is <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * @throws ClassCastException if the <var>value</var> is not of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * the type <tt>CompositeData</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * @throws InvalidOpenTypeException if the <var>value</var> does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * not conform to this <tt>TabularData</tt> instance's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * <tt>TabularType</tt> definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * @throws KeyAlreadyExistsException if the key for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * <var>value</var> parameter, calculated according to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * <tt>TabularData</tt> instance's <tt>TabularType</tt> definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * already maps to an existing value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    public Object put(Object key, Object value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        internalPut((CompositeData) value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        return value; // should be return internalPut(...); (5090566)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    public void put(CompositeData value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        internalPut(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    private CompositeData internalPut(CompositeData value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        // Check value is not null, value's type is the same as this instance's row type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        // and calculate the value's index according to this instance's tabularType and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        // check it is not already used for a mapping in the parent HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        List<?> index = checkValueAndIndex(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        // store the (key, value) mapping in the dataMap HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        return dataMap.put(index, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * This method simply calls <tt>remove((Object[]) key)</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     * @param key an <tt>Object[]</tt> representing the key to remove.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * @return previous value associated with specified key, or <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     *         if there was no mapping for key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * @throws NullPointerException  if the <var>key</var> is <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * @throws ClassCastException    if the <var>key</var> is not of the type <tt>Object[]</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * @throws InvalidKeyException   if the <var>key</var> does not conform to this <tt>TabularData</tt> instance's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     *                               <tt>TabularType</tt> definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    public Object remove(Object key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        return remove((Object[]) key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * Removes the <tt>CompositeData</tt> value whose index is <var>key</var> from this <tt>TabularData</tt> instance,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * and returns the removed value, or returns <tt>null</tt> if there is no value whose index is <var>key</var>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * @param  key  the index of the value to get in this <tt>TabularData</tt> instance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     *              must be valid with this <tt>TabularData</tt> instance's row type definition;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     *              must not be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     * @return previous value associated with specified key, or <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     *         if there was no mapping for key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * @throws NullPointerException  if the <var>key</var> is <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * @throws InvalidKeyException   if the <var>key</var> does not conform to this <tt>TabularData</tt> instance's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     *                               <tt>TabularType</tt> definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    public CompositeData remove(Object[] key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        // Check key is not null and valid with tabularType
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        // (throws NullPointerException, InvalidKeyException)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        checkKeyType(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        // Removes the (key, value) mapping in the parent HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        return dataMap.remove(Arrays.asList(key));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
    /* ***   Content modification bulk operations   *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     * Add all the values contained in the specified map <var>t</var>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * to this <tt>TabularData</tt> instance.  This method converts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * the collection of values contained in this map into an array of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * <tt>CompositeData</tt> values, if possible, and then call the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * method <tt>putAll(CompositeData[])</tt>. Note that the keys
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * used in the specified map <var>t</var> are ignored. This method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     * allows, for example to add the content of another
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * <tt>TabularData</tt> instance with the same row type (but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     * possibly different index names) into this instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     * @param t the map whose values are to be added as new rows to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     * this <tt>TabularData</tt> instance; if <var>t</var> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     * <tt>null</tt> or empty, this method returns without doing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
     * anything.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
     * @throws NullPointerException if a value in <var>t</var> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
     * <tt>null</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
     * @throws ClassCastException if a value in <var>t</var> is not an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     * instance of <tt>CompositeData</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
     * @throws InvalidOpenTypeException if a value in <var>t</var>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * does not conform to this <tt>TabularData</tt> instance's row
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     * type definition.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     * @throws KeyAlreadyExistsException if the index for a value in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     * <var>t</var>, calculated according to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * <tt>TabularData</tt> instance's <tt>TabularType</tt> definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * already maps to an existing value in this instance, or two
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * values in <var>t</var> have the same index.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    public void putAll(Map<?,?> t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        // if t is null or empty, just return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        if ( (t == null) || (t.size() == 0) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        // Convert the values in t into an array of <tt>CompositeData</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        CompositeData[] values;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            values =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                t.values().toArray(new CompositeData[t.size()]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        } catch (java.lang.ArrayStoreException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            throw new ClassCastException("Map argument t contains values which are not instances of <tt>CompositeData</tt>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        // Add the array of values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        putAll(values);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * Add all the elements in <var>values</var> to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     * <tt>TabularData</tt> instance.  If any element in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * <var>values</var> does not satisfy the constraints defined in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * {@link #put(CompositeData) <tt>put</tt>}, or if any two
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * elements in <var>values</var> have the same index calculated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * according to this <tt>TabularData</tt> instance's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * <tt>TabularType</tt> definition, then an exception describing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * the failure is thrown and no element of <var>values</var> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * added, thus leaving this <tt>TabularData</tt> instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * unchanged.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     * @param values the array of composite data values to be added as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * new rows to this <tt>TabularData</tt> instance; if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     * <var>values</var> is <tt>null</tt> or empty, this method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * returns without doing anything.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * @throws NullPointerException if an element of <var>values</var>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     * is <tt>null</tt>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     * @throws InvalidOpenTypeException if an element of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     * <var>values</var> does not conform to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
     * <tt>TabularData</tt> instance's row type definition (ie its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
     * <tt>TabularType</tt> definition)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
     * @throws KeyAlreadyExistsException if the index for an element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * of <var>values</var>, calculated according to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * <tt>TabularData</tt> instance's <tt>TabularType</tt> definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     * already maps to an existing value in this instance, or two
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * elements of <var>values</var> have the same index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    public void putAll(CompositeData[] values) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        // if values is null or empty, just return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        if ( (values == null) || (values.length == 0) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        // create the list of indexes corresponding to each value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        List<List<?>> indexes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
            new ArrayList<List<?>>(values.length + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        // Check all elements in values and build index list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        List<?> index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        for (int i=0; i<values.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            // check value and calculate index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            index = checkValueAndIndex(values[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
            // check index is different of those previously calculated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            if (indexes.contains(index)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                throw new KeyAlreadyExistsException("Argument elements values["+ i +"] and values["+ indexes.indexOf(index) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                                                    "] have the same indexes, "+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                                                    "calculated according to this TabularData instance's tabularType.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            // add to index list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            indexes.add(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        // store all (index, value) mappings in the dataMap HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        for (int i=0; i<values.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            dataMap.put(indexes.get(i), values[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     * Removes all rows from this <code>TabularDataSupport</code> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    public void clear() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        dataMap.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
    /* ***  Informational methods from java.util.Map  *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     * Returns the number of rows in this <code>TabularDataSupport</code> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
     * @return the number of rows in this <code>TabularDataSupport</code> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
    public int size() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        return dataMap.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * Returns <tt>true</tt> if this <code>TabularDataSupport</code> instance contains no rows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     * @return <tt>true</tt> if this <code>TabularDataSupport</code> instance contains no rows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    public boolean isEmpty() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        return (this.size() == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    /* ***  Collection views from java.util.Map  *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
     * Returns a set view of the keys contained in the underlying map of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * {@code TabularDataSupport} instance used to index the rows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * Each key contained in this {@code Set} is an unmodifiable {@code List<?>}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     * so the returned set view is a {@code Set<List<?>>} but is declared as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * {@code Set<Object>} for compatibility reasons.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     * The set is backed by the underlying map of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * {@code TabularDataSupport} instance, so changes to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     * {@code TabularDataSupport} instance are reflected in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * set, and vice-versa.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * The set supports element removal, which removes the corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * row from this {@code TabularDataSupport} instance, via the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     * {@link Iterator#remove}, {@link Set#remove}, {@link Set#removeAll},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     * {@link Set#retainAll}, and {@link Set#clear} operations. It does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     *  not support the {@link Set#add} or {@link Set#addAll} operations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * @return a set view ({@code Set<List<?>>}) of the keys used to index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * the rows of this {@code TabularDataSupport} instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    public Set<Object> keySet() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        return dataMap.keySet() ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     * Returns a collection view of the rows contained in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     * {@code TabularDataSupport} instance. The returned {@code Collection}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
     * is a {@code Collection<CompositeData>} but is declared as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
     * {@code Collection<Object>} for compatibility reasons.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
     * The returned collection can be used to iterate over the values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
     * The collection is backed by the underlying map, so changes to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     * {@code TabularDataSupport} instance are reflected in the collection,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     * and vice-versa.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
     * The collection supports element removal, which removes the corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
     * index to row mapping from this {@code TabularDataSupport} instance, via
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
     * the {@link Iterator#remove}, {@link Collection#remove},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
     * {@link Collection#removeAll}, {@link Collection#retainAll},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     * and {@link Collection#clear} operations. It does not support
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     * the {@link Collection#add} or {@link Collection#addAll} operations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * @return a collection view ({@code Collection<CompositeData>}) of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * the values contained in this {@code TabularDataSupport} instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    @SuppressWarnings("unchecked")  // historical confusion about the return type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    public Collection<Object> values() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        return (Collection) dataMap.values() ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * Returns a collection view of the index to row mappings
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * contained in this {@code TabularDataSupport} instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * Each element in the returned collection is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     * a {@code Map.Entry<List<?>,CompositeData>} but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     * is declared as a {@code Map.Entry<Object,Object>}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     * for compatibility reasons. Each of the map entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     * keys is an unmodifiable {@code List<?>}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     * The collection is backed by the underlying map of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     * {@code TabularDataSupport} instance, so changes to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * {@code TabularDataSupport} instance are reflected in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     * the collection, and vice-versa.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     * The collection supports element removal, which removes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     * the corresponding mapping from the map, via the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * {@link Iterator#remove}, {@link Collection#remove},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     * {@link Collection#removeAll}, {@link Collection#retainAll},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     * and {@link Collection#clear} operations. It does not support
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     * the {@link Collection#add} or {@link Collection#addAll}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     * operations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * <b>IMPORTANT NOTICE</b>: Do not use the {@code setValue} method of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * {@code Map.Entry} elements contained in the returned collection view.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     * Doing so would corrupt the index to row mappings contained in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     * {@code TabularDataSupport} instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     * @return a collection view ({@code Set<Map.Entry<List<?>,CompositeData>>})
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
     * of the mappings contained in this map.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
     * @see java.util.Map.Entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    @SuppressWarnings("unchecked")  // historical confusion about the return type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    public Set<Map.Entry<Object,Object>> entrySet() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        return (Set) dataMap.entrySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    /* ***  Commodity methods from java.lang.Object  *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * Returns a clone of this <code>TabularDataSupport</code> instance:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * the clone is obtained by calling <tt>super.clone()</tt>, and then cloning the underlying map.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * Only a shallow clone of the underlying map is made, i.e. no cloning of the indexes and row values is made as they are immutable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    /* We cannot use covariance here and return TabularDataSupport
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
       because this would fail with existing code that subclassed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
       TabularDataSupport and overrode Object clone().  It would not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
       override the new clone().  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    public Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            TabularDataSupport c = (TabularDataSupport) super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            c.dataMap = new HashMap<Object,CompositeData>(c.dataMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            return c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        catch (CloneNotSupportedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            throw new InternalError(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * Compares the specified <var>obj</var> parameter with this <code>TabularDataSupport</code> instance for equality.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * Returns <tt>true</tt> if and only if all of the following statements are true:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * <li><var>obj</var> is non null,</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     * <li><var>obj</var> also implements the <code>TabularData</code> interface,</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     * <li>their tabular types are equal</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     * <li>their contents (ie all CompositeData values) are equal.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
     * This ensures that this <tt>equals</tt> method works properly for <var>obj</var> parameters which are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     * different implementations of the <code>TabularData</code> interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     * <br>&nbsp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     * @param  obj  the object to be compared for equality with this <code>TabularDataSupport</code> instance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     * @return  <code>true</code> if the specified object is equal to this <code>TabularDataSupport</code> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
    public boolean equals(Object obj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        // if obj is null, return false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
        if (obj == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        // if obj is not a TabularData, return false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        TabularData other;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            other = (TabularData) obj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        } catch (ClassCastException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        // Now, really test for equality between this TabularData implementation and the other:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        // their tabularType should be equal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        if ( ! this.getTabularType().equals(other.getTabularType()) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        // their contents should be equal:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        // . same size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        // . values in this instance are in the other (we know there are no duplicate elements possible)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        // (row values comparison is enough, because keys are calculated according to tabularType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        if (this.size() != other.size()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        for (Iterator iter = this.values().iterator(); iter.hasNext();  ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            CompositeData value = (CompositeData) iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            if ( ! other.containsValue(value) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        // All tests for equality were successfull
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
     * Returns the hash code value for this <code>TabularDataSupport</code> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
     * The hash code of a <code>TabularDataSupport</code> instance is the sum of the hash codes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
     * of all elements of information used in <code>equals</code> comparisons
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
     * (ie: its <i>tabular type</i> and its content, where the content is defined as all the CompositeData values).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
     * This ensures that <code> t1.equals(t2) </code> implies that <code> t1.hashCode()==t2.hashCode() </code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
     * for any two <code>TabularDataSupport</code> instances <code>t1</code> and <code>t2</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
     * as required by the general contract of the method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
     * {@link Object#hashCode() Object.hashCode()}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
     * However, note that another instance of a class implementing the <code>TabularData</code> interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
     * may be equal to this <code>TabularDataSupport</code> instance as defined by {@link #equals},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
     * but may have a different hash code if it is calculated differently.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
     * @return  the hash code value for this <code>TabularDataSupport</code> instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
   public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        int result = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        result += this.tabularType.hashCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        for (Iterator iter = this.values().iterator(); iter.hasNext();  ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            result += ((CompositeData)iter.next()).hashCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     * Returns a string representation of this <code>TabularDataSupport</code> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
     * The string representation consists of the name of this class (ie <code>javax.management.openmbean.TabularDataSupport</code>),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
     * the string representation of the tabular type of this instance, and the string representation of the contents
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
     * (ie list the key=value mappings as returned by a call to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
     * <tt>dataMap.</tt>{@link java.util.HashMap#toString() toString()}).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     * @return  a string representation of this <code>TabularDataSupport</code> instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        return new StringBuilder()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            .append(this.getClass().getName())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            .append("(tabularType=")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
            .append(tabularType.toString())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            .append(",contents=")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            .append(dataMap.toString())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            .append(")")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            .toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    /* *** TabularDataSupport internal utility methods *** */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
     * Returns the index for value, assuming value is valid for this <tt>TabularData</tt> instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
     * (ie value is not null, and its composite type is equal to row type).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     * The index is a List, and not an array, so that an index.equals(otherIndex) call will actually compare contents,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
     * not just the objects references as is done for an array object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
     * The returned List is unmodifiable so that once a row has been put into the dataMap, its index cannot be modified,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
     * for example by a user that would attempt to modify an index contained in the Set returned by keySet().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    private List<?> internalCalculateIndex(CompositeData value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        return Collections.unmodifiableList(Arrays.asList(value.getAll(this.indexNamesArray)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     * Checks if the specified key is valid for this <tt>TabularData</tt> instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
     * @throws  NullPointerException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
     * @throws  InvalidOpenTypeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
    private void checkKeyType(Object[] key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        // Check key is neither null nor empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        if ( (key == null) || (key.length == 0) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            throw new NullPointerException("Argument key cannot be null or empty.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        /* Now check key is valid with tabularType index and row type definitions: */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
        // key[] should have the size expected for an index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        if (key.length != this.indexNamesArray.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            throw new InvalidKeyException("Argument key's length="+ key.length +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                                          " is different from the number of item values, which is "+ indexNamesArray.length +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                                          ", specified for the indexing rows in this TabularData instance.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        // each element in key[] should be a value for its corresponding open type specified in rowType
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        OpenType<?> keyElementType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        for (int i=0; i<key.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            keyElementType = tabularType.getRowType().getType(this.indexNamesArray[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            if ( (key[i] != null) && (! keyElementType.isValue(key[i])) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                throw new InvalidKeyException("Argument element key["+ i +"] is not a value for the open type expected for "+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                                              "this element of the index, whose name is \""+ indexNamesArray[i] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                                              "\" and whose open type is "+ keyElementType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
     * Checks the specified value's type is valid for this <tt>TabularData</tt> instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
     * (ie value is not null, and its composite type is equal to row type).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     * @throws  NullPointerException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
     * @throws  InvalidOpenTypeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
    private void checkValueType(CompositeData value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        // Check value is not null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        if (value == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
            throw new NullPointerException("Argument value cannot be null.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        // if value's type is not the same as this instance's row type, throw InvalidOpenTypeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        if (!tabularType.getRowType().isValue(value)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            throw new InvalidOpenTypeException("Argument value's composite type ["+ value.getCompositeType() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                                               "] is not assignable to "+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                                               "this TabularData instance's row type ["+ tabularType.getRowType() +"].");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
     * Checks if the specified value can be put (ie added) in this <tt>TabularData</tt> instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
     * (ie value is not null, its composite type is equal to row type, and its index is not already used),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
     * and returns the index calculated for this value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
     * The index is a List, and not an array, so that an index.equals(otherIndex) call will actually compare contents,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
     * not just the objects references as is done for an array object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
     * @throws  NullPointerException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
     * @throws  InvalidOpenTypeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
     * @throws  KeyAlreadyExistsException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    private List<?> checkValueAndIndex(CompositeData value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
        // Check value is valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
        checkValueType(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
        // Calculate value's index according to this instance's tabularType
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
        // and check it is not already used for a mapping in the parent HashMap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
        List<?> index = internalCalculateIndex(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        if (dataMap.containsKey(index)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
            throw new KeyAlreadyExistsException("Argument value's index, calculated according to this TabularData "+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                                                "instance's tabularType, already refers to a value in this table.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        // The check is OK, so return the index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        return index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
     * Deserializes a {@link TabularDataSupport} from an {@link ObjectInputStream}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
    private void readObject(ObjectInputStream in)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
            throws IOException, ClassNotFoundException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
      in.defaultReadObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
      List<String> tmpNames = tabularType.getIndexNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
      indexNamesArray = tmpNames.toArray(new String[tmpNames.size()]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
}