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