1 /*
2 * Copyright 2000-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
26 package javax.management.relation;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.List;
31
32 /**
33 * A RoleUnresolvedList represents a list of RoleUnresolved objects,
34 * representing roles not retrieved from a relation due to a problem
35 * encountered when trying to access (read or write) the roles.
36 *
37 * @since 1.5
38 */
39 /* We cannot extend ArrayList<RoleUnresolved> because our legacy
40 add(RoleUnresolved) method would then override add(E) in ArrayList<E>,
41 and our return value is void whereas ArrayList.add(E)'s is boolean.
42 Likewise for set(int,RoleUnresolved). Grrr. We cannot use covariance
43 to override the most important methods and have them return
44 RoleUnresolved, either, because that would break subclasses that
45 override those methods in turn (using the original return type
46 of Object). Finally, we cannot implement Iterable<RoleUnresolved>
47 so you could write
48 for (RoleUnresolved r : roleUnresolvedList)
49 because ArrayList<> implements Iterable<> and the same class cannot
50 implement two versions of a generic interface. Instead we provide
51 the asList() method so you can write
52 for (RoleUnresolved r : roleUnresolvedList.asList())
53 */
54 public class RoleUnresolvedList extends ArrayList<Object> {
55
56 private transient boolean typeSafe;
57 private transient boolean tainted;
58
59 /* Serial version */
60 private static final long serialVersionUID = 4054902803091433324L;
61
62 //
63 // Constructors
64 //
65
66 /**
67 * Constructs an empty RoleUnresolvedList.
68 */
69 public RoleUnresolvedList() {
70 super();
71 }
72
73 /**
74 * Constructs an empty RoleUnresolvedList with the initial capacity
75 * specified.
76 *
77 * @param initialCapacity initial capacity
78 */
79 public RoleUnresolvedList(int initialCapacity) {
80 super(initialCapacity);
81 }
82
83 /**
84 * Constructs a {@code RoleUnresolvedList} containing the elements of the
85 * {@code List} specified, in the order in which they are returned by
86 * the {@code List}'s iterator. The {@code RoleUnresolvedList} instance has
87 * an initial capacity of 110% of the size of the {@code List}
88 * specified.
89 *
90 * @param list the {@code List} that defines the initial contents of
91 * the new {@code RoleUnresolvedList}.
92 *
93 * @exception IllegalArgumentException if the {@code list} parameter
94 * is {@code null} or if the {@code list} parameter contains any
95 * non-RoleUnresolved objects.
96 *
97 * @see ArrayList#ArrayList(java.util.Collection)
98 */
99 public RoleUnresolvedList(List<RoleUnresolved> list)
100 throws IllegalArgumentException {
101 // Check for null parameter
102 //
103 if (list == null)
104 throw new IllegalArgumentException("Null parameter");
105
106 // Check for non-RoleUnresolved objects
107 //
108 checkTypeSafe(list);
109
110 // Build the List<RoleUnresolved>
111 //
112 super.addAll(list);
113 }
114
115 /**
116 * Return a view of this list as a {@code List<RoleUnresolved>}.
117 * Changes to the returned value are reflected by changes
118 * to the original {@code RoleUnresolvedList} and vice versa.
119 *
120 * @return a {@code List<RoleUnresolved>} whose contents
121 * reflect the contents of this {@code RoleUnresolvedList}.
122 *
123 * <p>If this method has ever been called on a given
124 * {@code RoleUnresolvedList} instance, a subsequent attempt to add
125 * an object to that instance which is not a {@code RoleUnresolved}
126 * will fail with an {@code IllegalArgumentException}. For compatibility
127 * reasons, a {@code RoleUnresolvedList} on which this method has never
128 * been called does allow objects other than {@code RoleUnresolved}s to
129 * be added.</p>
130 *
131 * @throws IllegalArgumentException if this {@code RoleUnresolvedList}
132 * contains an element that is not a {@code RoleUnresolved}.
133 *
134 * @since 1.6
135 */
136 @SuppressWarnings("unchecked")
137 public List<RoleUnresolved> asList() {
138 if (!typeSafe) {
139 if (tainted)
140 checkTypeSafe(this);
141 typeSafe = true;
142 }
143 return (List<RoleUnresolved>) (List) this;
144 }
145
146 //
147 // Accessors
148 //
149
150 /**
151 * Adds the RoleUnresolved specified as the last element of the list.
152 *
153 * @param role - the unresolved role to be added.
154 *
155 * @exception IllegalArgumentException if the unresolved role is null.
156 */
157 public void add(RoleUnresolved role)
158 throws IllegalArgumentException {
159
160 if (role == null) {
161 String excMsg = "Invalid parameter";
162 throw new IllegalArgumentException(excMsg);
163 }
164 super.add(role);
165 }
166
167 /**
168 * Inserts the unresolved role specified as an element at the position
169 * specified.
170 * Elements with an index greater than or equal to the current position are
171 * shifted up.
172 *
173 * @param index - The position in the list where the new
174 * RoleUnresolved object is to be inserted.
175 * @param role - The RoleUnresolved object to be inserted.
176 *
177 * @exception IllegalArgumentException if the unresolved role is null.
178 * @exception IndexOutOfBoundsException if index is out of range
179 * (<code>index < 0 || index > size()</code>).
180 */
181 public void add(int index,
182 RoleUnresolved role)
183 throws IllegalArgumentException,
184 IndexOutOfBoundsException {
185
186 if (role == null) {
187 String excMsg = "Invalid parameter";
188 throw new IllegalArgumentException(excMsg);
189 }
190
191 super.add(index, role);
192 }
193
194 /**
195 * Sets the element at the position specified to be the unresolved role
196 * specified.
197 * The previous element at that position is discarded.
198 *
199 * @param index - The position specified.
200 * @param role - The value to which the unresolved role element
201 * should be set.
202 *
203 * @exception IllegalArgumentException if the unresolved role is null.
204 * @exception IndexOutOfBoundsException if index is out of range
205 * (<code>index < 0 || index >= size()</code>).
206 */
207 public void set(int index,
208 RoleUnresolved role)
209 throws IllegalArgumentException,
210 IndexOutOfBoundsException {
211
212 if (role == null) {
213 String excMsg = "Invalid parameter";
214 throw new IllegalArgumentException(excMsg);
215 }
216
217 super.set(index, role);
218 }
219
220 /**
221 * Appends all the elements in the RoleUnresolvedList specified to the end
222 * of the list, in the order in which they are returned by the Iterator of
223 * the RoleUnresolvedList specified.
224 *
225 * @param roleList - Elements to be inserted into the list
226 * (can be null).
227 *
228 * @return true if this list changed as a result of the call.
229 *
230 * @exception IndexOutOfBoundsException if accessing with an index
231 * outside of the list.
232 */
233 public boolean addAll(RoleUnresolvedList roleList)
234 throws IndexOutOfBoundsException {
235
236 if (roleList == null) {
237 return true;
238 }
239
240 return (super.addAll(roleList));
241 }
242
243 /**
244 * Inserts all of the elements in the RoleUnresolvedList specified into
245 * this list, starting at the specified position, in the order in which
246 * they are returned by the Iterator of the RoleUnresolvedList specified.
247 *
248 * @param index - Position at which to insert the first element from the
249 * RoleUnresolvedList specified.
250 * @param roleList - Elements to be inserted into the list.
251 *
252 * @return true if this list changed as a result of the call.
253 *
254 * @exception IllegalArgumentException if the role is null.
255 * @exception IndexOutOfBoundsException if index is out of range
256 * (<code>index < 0 || index > size()</code>).
257 */
258 public boolean addAll(int index,
259 RoleUnresolvedList roleList)
260 throws IllegalArgumentException,
261 IndexOutOfBoundsException {
262
263 if (roleList == null) {
264 String excMsg = "Invalid parameter";
265 throw new IllegalArgumentException(excMsg);
266 }
267
268 return (super.addAll(index, roleList));
269 }
270
271 /*
272 * Override all of the methods from ArrayList<Object> that might add
273 * a non-RoleUnresolved to the List, and disallow that if asList has
274 * ever been called on this instance.
275 */
276
277 @Override
278 public boolean add(Object o) {
279 if (!tainted)
280 tainted = isTainted(o);
281 if (typeSafe)
282 checkTypeSafe(o);
283 return super.add(o);
284 }
285
286 @Override
287 public void add(int index, Object element) {
288 if (!tainted)
289 tainted = isTainted(element);
290 if (typeSafe)
291 checkTypeSafe(element);
292 super.add(index, element);
293 }
294
295 @Override
296 public boolean addAll(Collection<?> c) {
297 if (!tainted)
298 tainted = isTainted(c);
299 if (typeSafe)
300 checkTypeSafe(c);
301 return super.addAll(c);
302 }
303
304 @Override
305 public boolean addAll(int index, Collection<?> c) {
306 if (!tainted)
307 tainted = isTainted(c);
308 if (typeSafe)
309 checkTypeSafe(c);
310 return super.addAll(index, c);
311 }
312
313 @Override
314 public Object set(int index, Object element) {
315 if (!tainted)
316 tainted = isTainted(element);
317 if (typeSafe)
318 checkTypeSafe(element);
319 return super.set(index, element);
320 }
321
322 /**
323 * IllegalArgumentException if o is a non-RoleUnresolved object.
324 */
325 private static void checkTypeSafe(Object o) {
326 try {
327 o = (RoleUnresolved) o;
328 } catch (ClassCastException e) {
329 throw new IllegalArgumentException(e);
330 }
331 }
332
333 /**
334 * IllegalArgumentException if c contains any non-RoleUnresolved objects.
335 */
336 private static void checkTypeSafe(Collection<?> c) {
337 try {
338 RoleUnresolved r;
339 for (Object o : c)
340 r = (RoleUnresolved) o;
341 } catch (ClassCastException e) {
342 throw new IllegalArgumentException(e);
343 }
344 }
345
346 /**
347 * Returns true if o is a non-RoleUnresolved object.
348 */
349 private static boolean isTainted(Object o) {
350 try {
351 checkTypeSafe(o);
352 } catch (IllegalArgumentException e) {
353 return true;
354 }
355 return false;
356 }
357
358 /**
359 * Returns true if c contains any non-RoleUnresolved objects.
360 */
361 private static boolean isTainted(Collection<?> c) {
362 try {
363 checkTypeSafe(c);
364 } catch (IllegalArgumentException e) {
365 return true;
366 }
367 return false;
368 }
369 }