blob: b385c3c0f79c57ede5c66b1e9058f1f3332f7b48 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.management;
27
28import java.util.ArrayList;
29import java.util.Collection;
30import java.util.List;
31
32/**
33 * Represents a list of values for attributes of an MBean. The methods
34 * used for the insertion of {@link javax.management.Attribute
35 * Attribute} objects in the <CODE>AttributeList</CODE> overrides the
36 * corresponding methods in the superclass
37 * <CODE>ArrayList</CODE>. This is needed in order to insure that the
38 * objects contained in the <CODE>AttributeList</CODE> are only
39 * <CODE>Attribute</CODE> objects. This avoids getting an exception
40 * when retrieving elements from the <CODE>AttributeList</CODE>.
41 *
42 * @since 1.5
43 */
44/* We cannot extend ArrayList<Attribute> because our legacy
45 add(Attribute) method would then override add(E) in ArrayList<E>,
46 and our return value is void whereas ArrayList.add(E)'s is boolean.
47 Likewise for set(int,Attribute). Grrr. We cannot use covariance
48 to override the most important methods and have them return
49 Attribute, either, because that would break subclasses that
50 override those methods in turn (using the original return type
51 of Object). Finally, we cannot implement Iterable<Attribute>
52 so you could write
53 for (Attribute a : attributeList)
54 because ArrayList<> implements Iterable<> and the same class cannot
55 implement two versions of a generic interface. Instead we provide
56 the asList() method so you can write
57 for (Attribute a : attributeList.asList())
58*/
59public class AttributeList extends ArrayList<Object> {
60
61 private transient boolean typeSafe;
62 private transient boolean tainted;
63
64 /* Serial version */
65 private static final long serialVersionUID = -4077085769279709076L;
66
67 /**
68 * Constructs an empty <CODE>AttributeList</CODE>.
69 */
70 public AttributeList() {
71 super();
72 }
73
74 /**
75 * Constructs an empty <CODE>AttributeList</CODE> with
76 * the initial capacity specified.
77 *
78 * @param initialCapacity the initial capacity of the
79 * <code>AttributeList</code>, as specified by {@link
80 * ArrayList#ArrayList(int)}.
81 */
82 public AttributeList(int initialCapacity) {
83 super(initialCapacity);
84 }
85
86 /**
87 * Constructs an <CODE>AttributeList</CODE> containing the
88 * elements of the <CODE>AttributeList</CODE> specified, in the
89 * order in which they are returned by the
90 * <CODE>AttributeList</CODE>'s iterator. The
91 * <CODE>AttributeList</CODE> instance has an initial capacity of
92 * 110% of the size of the <CODE>AttributeList</CODE> specified.
93 *
94 * @param list the <code>AttributeList</code> that defines the initial
95 * contents of the new <code>AttributeList</code>.
96 *
97 * @see ArrayList#ArrayList(java.util.Collection)
98 */
99 public AttributeList(AttributeList list) {
100 super(list);
101 }
102
103 /**
104 * Constructs an {@code AttributeList} containing the elements of the
105 * {@code List} specified, in the order in which they are returned by
106 * the {@code List}'s iterator.
107 *
108 * @param list the {@code List} that defines the initial contents of
109 * the new {@code AttributeList}.
110 *
111 * @exception IllegalArgumentException if the {@code list} parameter
112 * is {@code null} or if the {@code list} parameter contains any
113 * non-Attribute objects.
114 *
115 * @see ArrayList#ArrayList(java.util.Collection)
116 *
117 * @since 1.6
118 */
119 public AttributeList(List<Attribute> list) {
120 // Check for null parameter
121 //
122 if (list == null)
123 throw new IllegalArgumentException("Null parameter");
124
125 // Check for non-Attribute objects
126 //
127 checkTypeSafe(list);
128
129 // Build the List<Attribute>
130 //
131 super.addAll(list);
132 }
133
134 /**
135 * Return a view of this list as a {@code List<Attribute>}.
136 * Changes to the returned value are reflected by changes
137 * to the original {@code AttributeList} and vice versa.
138 *
139 * @return a {@code List<Attribute>} whose contents
140 * reflect the contents of this {@code AttributeList}.
141 *
142 * <p>If this method has ever been called on a given
143 * {@code AttributeList} instance, a subsequent attempt to add
144 * an object to that instance which is not an {@code Attribute}
145 * will fail with a {@code IllegalArgumentException}. For compatibility
146 * reasons, an {@code AttributeList} on which this method has never
147 * been called does allow objects other than {@code Attribute}s to
148 * be added.</p>
149 *
150 * @throws IllegalArgumentException if this {@code AttributeList} contains
151 * an element that is not an {@code Attribute}.
152 *
153 * @since 1.6
154 */
155 @SuppressWarnings("unchecked")
156 public List<Attribute> asList() {
157 if (!typeSafe) {
158 if (tainted)
159 checkTypeSafe(this);
160 typeSafe = true;
161 }
162 return (List<Attribute>) (List) this;
163 }
164
165 /**
166 * Adds the {@code Attribute} specified as the last element of the list.
167 *
168 * @param object The attribute to be added.
169 */
170 public void add(Attribute object) {
171 super.add(object);
172 }
173
174 /**
175 * Inserts the attribute specified as an element at the position specified.
176 * Elements with an index greater than or equal to the current position are
177 * shifted up. If the index is out of range (index < 0 || index >
178 * size() a RuntimeOperationsException should be raised, wrapping the
179 * java.lang.IndexOutOfBoundsException thrown.
180 *
181 * @param object The <CODE>Attribute</CODE> object to be inserted.
182 * @param index The position in the list where the new {@code Attribute}
183 * object is to be inserted.
184 */
185 public void add(int index, Attribute object) {
186 try {
187 super.add(index, object);
188 }
189 catch (IndexOutOfBoundsException e) {
190 throw new RuntimeOperationsException(e,
191 "The specified index is out of range");
192 }
193 }
194
195 /**
196 * Sets the element at the position specified to be the attribute specified.
197 * The previous element at that position is discarded. If the index is
198 * out of range (index < 0 || index > size() a RuntimeOperationsException
199 * should be raised, wrapping the java.lang.IndexOutOfBoundsException thrown.
200 *
201 * @param object The value to which the attribute element should be set.
202 * @param index The position specified.
203 */
204 public void set(int index, Attribute object) {
205 try {
206 super.set(index, object);
207 }
208 catch (IndexOutOfBoundsException e) {
209 throw new RuntimeOperationsException(e,
210 "The specified index is out of range");
211 }
212 }
213
214 /**
215 * Appends all the elements in the <CODE>AttributeList</CODE> specified to
216 * the end of the list, in the order in which they are returned by the
217 * Iterator of the <CODE>AttributeList</CODE> specified.
218 *
219 * @param list Elements to be inserted into the list.
220 *
221 * @return true if this list changed as a result of the call.
222 *
223 * @see ArrayList#addAll(java.util.Collection)
224 */
225 public boolean addAll(AttributeList list) {
226 return (super.addAll(list));
227 }
228
229 /**
230 * Inserts all of the elements in the <CODE>AttributeList</CODE> specified
231 * into this list, starting at the specified position, in the order in which
232 * they are returned by the Iterator of the {@code AttributeList} specified.
233 * If the index is out of range (index < 0 || index > size() a
234 * RuntimeOperationsException should be raised, wrapping the
235 * java.lang.IndexOutOfBoundsException thrown.
236 *
237 * @param list Elements to be inserted into the list.
238 * @param index Position at which to insert the first element from the
239 * <CODE>AttributeList</CODE> specified.
240 *
241 * @return true if this list changed as a result of the call.
242 *
243 * @see ArrayList#addAll(int, java.util.Collection)
244 */
245 public boolean addAll(int index, AttributeList list) {
246 try {
247 return super.addAll(index, list);
248 }
249 catch (IndexOutOfBoundsException e) {
250 throw new RuntimeOperationsException(e,
251 "The specified index is out of range");
252 }
253 }
254
255 /*
256 * Override all of the methods from ArrayList<Object> that might add
257 * a non-Attribute to the List, and disallow that if asList has ever
258 * been called on this instance.
259 */
260
261 @Override
262 public boolean add(Object o) {
263 if (!tainted)
264 tainted = isTainted(o);
265 if (typeSafe)
266 checkTypeSafe(o);
267 return super.add(o);
268 }
269
270 @Override
271 public void add(int index, Object element) {
272 if (!tainted)
273 tainted = isTainted(element);
274 if (typeSafe)
275 checkTypeSafe(element);
276 super.add(index, element);
277 }
278
279 @Override
280 public boolean addAll(Collection<?> c) {
281 if (!tainted)
282 tainted = isTainted(c);
283 if (typeSafe)
284 checkTypeSafe(c);
285 return super.addAll(c);
286 }
287
288 @Override
289 public boolean addAll(int index, Collection<?> c) {
290 if (!tainted)
291 tainted = isTainted(c);
292 if (typeSafe)
293 checkTypeSafe(c);
294 return super.addAll(index, c);
295 }
296
297 @Override
298 public Object set(int index, Object element) {
299 if (!tainted)
300 tainted = isTainted(element);
301 if (typeSafe)
302 checkTypeSafe(element);
303 return super.set(index, element);
304 }
305
306 /**
307 * IllegalArgumentException if o is a non-Attribute object.
308 */
309 private static void checkTypeSafe(Object o) {
310 try {
311 o = (Attribute) o;
312 } catch (ClassCastException e) {
313 throw new IllegalArgumentException(e);
314 }
315 }
316
317 /**
318 * IllegalArgumentException if c contains any non-Attribute objects.
319 */
320 private static void checkTypeSafe(Collection<?> c) {
321 try {
322 Attribute a;
323 for (Object o : c)
324 a = (Attribute) o;
325 } catch (ClassCastException e) {
326 throw new IllegalArgumentException(e);
327 }
328 }
329
330 /**
331 * Returns true if o is a non-Attribute object.
332 */
333 private static boolean isTainted(Object o) {
334 try {
335 checkTypeSafe(o);
336 } catch (IllegalArgumentException e) {
337 return true;
338 }
339 return false;
340 }
341
342 /**
343 * Returns true if c contains any non-Attribute objects.
344 */
345 private static boolean isTainted(Collection<?> c) {
346 try {
347 checkTypeSafe(c);
348 } catch (IllegalArgumentException e) {
349 return true;
350 }
351 return false;
352 }
353}