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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javax.print.attribute;
27
28 import java.io.IOException;
29 import java.io.ObjectInputStream;
30 import java.io.ObjectOutputStream;
31 import java.io.Serializable;
32 import java.util.HashMap;
33
34 /**
35 * Class HashAttributeSet provides an <code>AttributeSet</code>
36 * implementation with characteristics of a hash map.
37 *
38 * @author Alan Kaminsky
39 */
40 public class HashAttributeSet implements AttributeSet, Serializable {
41
42 private static final long serialVersionUID = 5311560590283707917L;
43
44 /**
45 * The interface of which all members of this attribute set must be an
46 * instance. It is assumed to be interface {@link Attribute Attribute}
47 * or a subinterface thereof.
48 * @serial
49 */
50 private Class<?> myInterface;
51
52 /*
53 * A HashMap used by the implementation.
54 * The serialised form doesn't include this instance variable.
55 */
87 for (int i = 0; i < count; i++) {
88 attr = (Attribute)s.readObject();
89 add(attr);
90 }
91 }
92
93 /**
94 * Construct a new, empty attribute set.
95 */
96 public HashAttributeSet() {
97 this(Attribute.class);
98 }
99
100 /**
101 * Construct a new attribute set,
102 * initially populated with the given attribute.
103 *
104 * @param attribute Attribute value to add to the set.
105 *
106 * @exception NullPointerException
107 * (unchecked exception) Thrown if <CODE>attribute</CODE> is null.
108 */
109 public HashAttributeSet(Attribute attribute) {
110 this (attribute, Attribute.class);
111 }
112
113 /**
114 * Construct a new attribute set,
115 * initially populated with the values from the
116 * given array. The new attribute set is populated by
117 * adding the elements of <CODE>attributes</CODE> array to the set in
118 * sequence, starting at index 0. Thus, later array elements may replace
119 * earlier array elements if the array contains duplicate attribute
120 * values or attribute categories.
121 *
122 * @param attributes Array of attribute values to add to the set.
123 * If null, an empty attribute set is constructed.
124 *
125 * @exception NullPointerException
126 * (unchecked exception) Thrown if any element of
127 * <CODE>attributes</CODE> is null.
128 */
129 public HashAttributeSet(Attribute[] attributes) {
130 this (attributes, Attribute.class);
131 }
132
133 /**
134 * Construct a new attribute set,
135 * initially populated with the values from the given set.
136 *
137 * @param attributes Set of attributes from which to initialise this set.
138 * If null, an empty attribute set is constructed.
139 *
140 */
141 public HashAttributeSet(AttributeSet attributes) {
142 this (attributes, Attribute.class);
143 }
144
145 /**
146 * Construct a new, empty attribute set, where the members of
147 * the attribute set are restricted to the given interface.
154 */
155 protected HashAttributeSet(Class<?> interfaceName) {
156 if (interfaceName == null) {
157 throw new NullPointerException("null interface");
158 }
159 myInterface = interfaceName;
160 }
161
162 /**
163 * Construct a new attribute set, initially populated with the given
164 * attribute, where the members of the attribute set are restricted to the
165 * given interface.
166 *
167 * @param attribute Attribute value to add to the set.
168 * @param interfaceName The interface of which all members of this
169 * attribute set must be an instance. It is assumed to
170 * be interface {@link Attribute Attribute} or a
171 * subinterface thereof.
172 *
173 * @exception NullPointerException
174 * (unchecked exception) Thrown if <CODE>attribute</CODE> is null.
175 * @exception NullPointerException if interfaceName is null.
176 * @exception ClassCastException
177 * (unchecked exception) Thrown if <CODE>attribute</CODE> is not an
178 * instance of <CODE>interfaceName</CODE>.
179 */
180 protected HashAttributeSet(Attribute attribute, Class<?> interfaceName) {
181 if (interfaceName == null) {
182 throw new NullPointerException("null interface");
183 }
184 myInterface = interfaceName;
185 add (attribute);
186 }
187
188 /**
189 * Construct a new attribute set, where the members of the attribute
190 * set are restricted to the given interface.
191 * The new attribute set is populated
192 * by adding the elements of <CODE>attributes</CODE> array to the set in
193 * sequence, starting at index 0. Thus, later array elements may replace
194 * earlier array elements if the array contains duplicate attribute
195 * values or attribute categories.
196 *
197 * @param attributes Array of attribute values to add to the set. If
198 * null, an empty attribute set is constructed.
199 * @param interfaceName The interface of which all members of this
200 * attribute set must be an instance. It is assumed to
201 * be interface {@link Attribute Attribute} or a
202 * subinterface thereof.
203 *
204 * @exception NullPointerException
205 * (unchecked exception) Thrown if any element of
206 * <CODE>attributes</CODE> is null.
207 * @exception NullPointerException if interfaceName is null.
208 * @exception ClassCastException
209 * (unchecked exception) Thrown if any element of
210 * <CODE>attributes</CODE> is not an instance of
211 * <CODE>interfaceName</CODE>.
212 */
213 protected HashAttributeSet(Attribute[] attributes, Class<?> interfaceName) {
214 if (interfaceName == null) {
215 throw new NullPointerException("null interface");
216 }
217 myInterface = interfaceName;
218 int n = attributes == null ? 0 : attributes.length;
219 for (int i = 0; i < n; ++ i) {
220 add (attributes[i]);
221 }
222 }
223
224 /**
225 * Construct a new attribute set, initially populated with the
226 * values from the given set where the members of the attribute
227 * set are restricted to the given interface.
228 *
229 * @param attributes set of attribute values to initialise the set. If
230 * null, an empty attribute set is constructed.
231 * @param interfaceName The interface of which all members of this
232 * attribute set must be an instance. It is assumed to
233 * be interface {@link Attribute Attribute} or a
234 * subinterface thereof.
235 *
236 * @exception ClassCastException
237 * (unchecked exception) Thrown if any element of
238 * <CODE>attributes</CODE> is not an instance of
239 * <CODE>interfaceName</CODE>.
240 */
241 protected HashAttributeSet(AttributeSet attributes, Class<?> interfaceName) {
242 myInterface = interfaceName;
243 if (attributes != null) {
244 Attribute[] attribArray = attributes.toArray();
245 int n = attribArray == null ? 0 : attribArray.length;
246 for (int i = 0; i < n; ++ i) {
247 add (attribArray[i]);
248 }
249 }
250 }
251
252 /**
253 * Returns the attribute value which this attribute set contains in the
254 * given attribute category. Returns <tt>null</tt> if this attribute set
255 * does not contain any attribute value in the given attribute category.
256 *
257 * @param category Attribute category whose associated attribute value
258 * is to be returned. It must be a
259 * {@link java.lang.Class Class}
260 * that implements interface {@link Attribute
261 * Attribute}.
262 *
263 * @return The attribute value in the given attribute category contained
264 * in this attribute set, or <tt>null</tt> if this attribute set
265 * does not contain any attribute value in the given attribute
266 * category.
267 *
268 * @throws NullPointerException
269 * (unchecked exception) Thrown if the <CODE>category</CODE> is null.
270 * @throws ClassCastException
271 * (unchecked exception) Thrown if the <CODE>category</CODE> is not a
272 * {@link java.lang.Class Class} that implements interface {@link
273 * Attribute Attribute}.
274 */
275 public Attribute get(Class<?> category) {
276 return attrMap.get(AttributeSetUtilities.
277 verifyAttributeCategory(category,
278 Attribute.class));
279 }
280
281 /**
282 * Adds the specified attribute to this attribute set if it is not
283 * already present, first removing any existing in the same
284 * attribute category as the specified attribute value.
285 *
286 * @param attribute Attribute value to be added to this attribute set.
287 *
288 * @return <tt>true</tt> if this attribute set changed as a result of the
289 * call, i.e., the given attribute value was not already a
290 * member of this attribute set.
291 *
292 * @throws NullPointerException
293 * (unchecked exception) Thrown if the <CODE>attribute</CODE> is null.
294 * @throws UnmodifiableSetException
295 * (unchecked exception) Thrown if this attribute set does not support
296 * the <CODE>add()</CODE> operation.
297 */
298 public boolean add(Attribute attribute) {
299 Object oldAttribute =
300 attrMap.put(attribute.getCategory(),
301 AttributeSetUtilities.
302 verifyAttributeValue(attribute, myInterface));
303 return (!attribute.equals(oldAttribute));
304 }
305
306 /**
307 * Removes any attribute for this category from this attribute set if
308 * present. If <CODE>category</CODE> is null, then
309 * <CODE>remove()</CODE> does nothing and returns <tt>false</tt>.
310 *
311 * @param category Attribute category to be removed from this
312 * attribute set.
313 *
314 * @return <tt>true</tt> if this attribute set changed as a result of the
315 * call, i.e., the given attribute category had been a member of
316 * this attribute set.
317 *
318 * @throws UnmodifiableSetException
319 * (unchecked exception) Thrown if this attribute set does not
320 * support the <CODE>remove()</CODE> operation.
321 */
322 public boolean remove(Class<?> category) {
323 return
324 category != null &&
325 AttributeSetUtilities.
326 verifyAttributeCategory(category, Attribute.class) != null &&
327 attrMap.remove(category) != null;
328 }
329
330 /**
331 * Removes the specified attribute from this attribute set if
332 * present. If <CODE>attribute</CODE> is null, then
333 * <CODE>remove()</CODE> does nothing and returns <tt>false</tt>.
334 *
335 * @param attribute Attribute value to be removed from this attribute set.
336 *
337 * @return <tt>true</tt> if this attribute set changed as a result of the
338 * call, i.e., the given attribute value had been a member of
339 * this attribute set.
340 *
341 * @throws UnmodifiableSetException
342 * (unchecked exception) Thrown if this attribute set does not
343 * support the <CODE>remove()</CODE> operation.
344 */
345 public boolean remove(Attribute attribute) {
346 return
347 attribute != null &&
348 attrMap.remove(attribute.getCategory()) != null;
349 }
350
351 /**
352 * Returns <tt>true</tt> if this attribute set contains an
353 * attribute for the specified category.
354 *
355 * @param category whose presence in this attribute set is
356 * to be tested.
357 *
358 * @return <tt>true</tt> if this attribute set contains an attribute
359 * value for the specified category.
360 */
361 public boolean containsKey(Class<?> category) {
362 return
363 category != null &&
364 AttributeSetUtilities.
365 verifyAttributeCategory(category, Attribute.class) != null &&
366 attrMap.get(category) != null;
367 }
368
369 /**
370 * Returns <tt>true</tt> if this attribute set contains the given
371 * attribute.
372 *
373 * @param attribute value whose presence in this attribute set is
374 * to be tested.
375 *
376 * @return <tt>true</tt> if this attribute set contains the given
377 * attribute value.
378 */
379 public boolean containsValue(Attribute attribute) {
380 return
381 attribute != null &&
382 attribute instanceof Attribute &&
383 attribute.equals(attrMap.get(attribute.getCategory()));
384 }
385
386 /**
387 * Adds all of the elements in the specified set to this attribute.
388 * The outcome is the same as if the
389 * {@link #add(Attribute) add(Attribute)}
390 * operation had been applied to this attribute set successively with
391 * each element from the specified set.
392 * The behavior of the <CODE>addAll(AttributeSet)</CODE>
393 * operation is unspecified if the specified set is modified while
394 * the operation is in progress.
395 * <P>
396 * If the <CODE>addAll(AttributeSet)</CODE> operation throws an exception,
397 * the effect on this attribute set's state is implementation dependent;
398 * elements from the specified set before the point of the exception may
399 * or may not have been added to this attribute set.
400 *
401 * @param attributes whose elements are to be added to this attribute
402 * set.
403 *
404 * @return <tt>true</tt> if this attribute set changed as a result of the
405 * call.
406 *
407 * @throws UnmodifiableSetException
408 * (Unchecked exception) Thrown if this attribute set does not
409 * support the <tt>addAll(AttributeSet)</tt> method.
410 * @throws NullPointerException
411 * (Unchecked exception) Thrown if some element in the specified
412 * set is null, or the set is null.
413 *
414 * @see #add(Attribute)
415 */
416 public boolean addAll(AttributeSet attributes) {
417
418 Attribute []attrs = attributes.toArray();
419 boolean result = false;
420 for (int i=0; i<attrs.length; i++) {
421 Attribute newValue =
422 AttributeSetUtilities.verifyAttributeValue(attrs[i],
423 myInterface);
424 Object oldValue = attrMap.put(newValue.getCategory(), newValue);
425 result = (! newValue.equals(oldValue)) || result;
426 }
427 return result;
428 }
429
430 /**
431 * Returns the number of attributes in this attribute set. If this
432 * attribute set contains more than <tt>Integer.MAX_VALUE</tt> elements,
433 * returns <tt>Integer.MAX_VALUE</tt>.
434 *
435 * @return The number of attributes in this attribute set.
436 */
437 public int size() {
438 return attrMap.size();
439 }
440
441 /**
442 *
443 * @return the Attributes contained in this set as an array, zero length
444 * if the AttributeSet is empty.
445 */
446 public Attribute[] toArray() {
447 Attribute []attrs = new Attribute[size()];
448 attrMap.values().toArray(attrs);
449 return attrs;
450 }
451
452
453 /**
454 * Removes all attributes from this attribute set.
455 *
456 * @throws UnmodifiableSetException
457 * (unchecked exception) Thrown if this attribute set does not support
458 * the <CODE>clear()</CODE> operation.
459 */
460 public void clear() {
461 attrMap.clear();
462 }
463
464 /**
465 * Returns true if this attribute set contains no attributes.
466 *
467 * @return true if this attribute set contains no attributes.
468 */
469 public boolean isEmpty() {
470 return attrMap.isEmpty();
471 }
472
473 /**
474 * Compares the specified object with this attribute set for equality.
475 * Returns <tt>true</tt> if the given object is also an attribute set and
476 * the two attribute sets contain the same attribute category-attribute
477 * value mappings. This ensures that the
478 * <tt>equals()</tt> method works properly across different
479 * implementations of the AttributeSet interface.
480 *
481 * @param object to be compared for equality with this attribute set.
482 *
483 * @return <tt>true</tt> if the specified object is equal to this
484 * attribute set.
485 */
486
487 public boolean equals(Object object) {
488 if (object == null || !(object instanceof AttributeSet)) {
489 return false;
490 }
491
492 AttributeSet aset = (AttributeSet)object;
493 if (aset.size() != size()) {
494 return false;
495 }
496
497 Attribute[] attrs = toArray();
498 for (int i=0;i<attrs.length; i++) {
499 if (!aset.containsValue(attrs[i])) {
500 return false;
501 }
502 }
503 return true;
504 }
505
506 /**
507 * Returns the hash code value for this attribute set.
508 * The hash code of an attribute set is defined to be the sum
509 * of the hash codes of each entry in the AttributeSet.
510 * This ensures that <tt>t1.equals(t2)</tt> implies that
511 * <tt>t1.hashCode()==t2.hashCode()</tt> for any two attribute sets
512 * <tt>t1</tt> and <tt>t2</tt>, as required by the general contract of
513 * {@link java.lang.Object#hashCode() Object.hashCode()}.
514 *
515 * @return The hash code value for this attribute set.
516 */
517 public int hashCode() {
518 int hcode = 0;
519 Attribute[] attrs = toArray();
520 for (int i=0;i<attrs.length; i++) {
521 hcode += attrs[i].hashCode();
522 }
523 return hcode;
524 }
525
526 }
|
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javax.print.attribute;
27
28 import java.io.IOException;
29 import java.io.ObjectInputStream;
30 import java.io.ObjectOutputStream;
31 import java.io.Serializable;
32 import java.util.HashMap;
33
34 /**
35 * Class HashAttributeSet provides an {@code AttributeSet}
36 * implementation with characteristics of a hash map.
37 *
38 * @author Alan Kaminsky
39 */
40 public class HashAttributeSet implements AttributeSet, Serializable {
41
42 private static final long serialVersionUID = 5311560590283707917L;
43
44 /**
45 * The interface of which all members of this attribute set must be an
46 * instance. It is assumed to be interface {@link Attribute Attribute}
47 * or a subinterface thereof.
48 * @serial
49 */
50 private Class<?> myInterface;
51
52 /*
53 * A HashMap used by the implementation.
54 * The serialised form doesn't include this instance variable.
55 */
87 for (int i = 0; i < count; i++) {
88 attr = (Attribute)s.readObject();
89 add(attr);
90 }
91 }
92
93 /**
94 * Construct a new, empty attribute set.
95 */
96 public HashAttributeSet() {
97 this(Attribute.class);
98 }
99
100 /**
101 * Construct a new attribute set,
102 * initially populated with the given attribute.
103 *
104 * @param attribute Attribute value to add to the set.
105 *
106 * @exception NullPointerException
107 * (unchecked exception) Thrown if {@code attribute} is null.
108 */
109 public HashAttributeSet(Attribute attribute) {
110 this (attribute, Attribute.class);
111 }
112
113 /**
114 * Construct a new attribute set,
115 * initially populated with the values from the
116 * given array. The new attribute set is populated by
117 * adding the elements of {@code attributes} array to the set in
118 * sequence, starting at index 0. Thus, later array elements may replace
119 * earlier array elements if the array contains duplicate attribute
120 * values or attribute categories.
121 *
122 * @param attributes Array of attribute values to add to the set.
123 * If null, an empty attribute set is constructed.
124 *
125 * @exception NullPointerException
126 * (unchecked exception) Thrown if any element of
127 * {@code attributes} is null.
128 */
129 public HashAttributeSet(Attribute[] attributes) {
130 this (attributes, Attribute.class);
131 }
132
133 /**
134 * Construct a new attribute set,
135 * initially populated with the values from the given set.
136 *
137 * @param attributes Set of attributes from which to initialise this set.
138 * If null, an empty attribute set is constructed.
139 *
140 */
141 public HashAttributeSet(AttributeSet attributes) {
142 this (attributes, Attribute.class);
143 }
144
145 /**
146 * Construct a new, empty attribute set, where the members of
147 * the attribute set are restricted to the given interface.
154 */
155 protected HashAttributeSet(Class<?> interfaceName) {
156 if (interfaceName == null) {
157 throw new NullPointerException("null interface");
158 }
159 myInterface = interfaceName;
160 }
161
162 /**
163 * Construct a new attribute set, initially populated with the given
164 * attribute, where the members of the attribute set are restricted to the
165 * given interface.
166 *
167 * @param attribute Attribute value to add to the set.
168 * @param interfaceName The interface of which all members of this
169 * attribute set must be an instance. It is assumed to
170 * be interface {@link Attribute Attribute} or a
171 * subinterface thereof.
172 *
173 * @exception NullPointerException
174 * (unchecked exception) Thrown if {@code attribute} is null.
175 * @exception NullPointerException if interfaceName is null.
176 * @exception ClassCastException
177 * (unchecked exception) Thrown if {@code attribute} is not an
178 * instance of {@code interfaceName}.
179 */
180 protected HashAttributeSet(Attribute attribute, Class<?> interfaceName) {
181 if (interfaceName == null) {
182 throw new NullPointerException("null interface");
183 }
184 myInterface = interfaceName;
185 add (attribute);
186 }
187
188 /**
189 * Construct a new attribute set, where the members of the attribute
190 * set are restricted to the given interface.
191 * The new attribute set is populated
192 * by adding the elements of {@code attributes} array to the set in
193 * sequence, starting at index 0. Thus, later array elements may replace
194 * earlier array elements if the array contains duplicate attribute
195 * values or attribute categories.
196 *
197 * @param attributes Array of attribute values to add to the set. If
198 * null, an empty attribute set is constructed.
199 * @param interfaceName The interface of which all members of this
200 * attribute set must be an instance. It is assumed to
201 * be interface {@link Attribute Attribute} or a
202 * subinterface thereof.
203 *
204 * @exception NullPointerException
205 * (unchecked exception) Thrown if any element of
206 * {@code attributes} is null.
207 * @exception NullPointerException if interfaceName is null.
208 * @exception ClassCastException
209 * (unchecked exception) Thrown if any element of
210 * {@code attributes} is not an instance of
211 * {@code interfaceName}.
212 */
213 protected HashAttributeSet(Attribute[] attributes, Class<?> interfaceName) {
214 if (interfaceName == null) {
215 throw new NullPointerException("null interface");
216 }
217 myInterface = interfaceName;
218 int n = attributes == null ? 0 : attributes.length;
219 for (int i = 0; i < n; ++ i) {
220 add (attributes[i]);
221 }
222 }
223
224 /**
225 * Construct a new attribute set, initially populated with the
226 * values from the given set where the members of the attribute
227 * set are restricted to the given interface.
228 *
229 * @param attributes set of attribute values to initialise the set. If
230 * null, an empty attribute set is constructed.
231 * @param interfaceName The interface of which all members of this
232 * attribute set must be an instance. It is assumed to
233 * be interface {@link Attribute Attribute} or a
234 * subinterface thereof.
235 *
236 * @exception ClassCastException
237 * (unchecked exception) Thrown if any element of
238 * {@code attributes} is not an instance of
239 * {@code interfaceName}.
240 */
241 protected HashAttributeSet(AttributeSet attributes, Class<?> interfaceName) {
242 myInterface = interfaceName;
243 if (attributes != null) {
244 Attribute[] attribArray = attributes.toArray();
245 int n = attribArray == null ? 0 : attribArray.length;
246 for (int i = 0; i < n; ++ i) {
247 add (attribArray[i]);
248 }
249 }
250 }
251
252 /**
253 * Returns the attribute value which this attribute set contains in the
254 * given attribute category. Returns {@code null} if this attribute set
255 * does not contain any attribute value in the given attribute category.
256 *
257 * @param category Attribute category whose associated attribute value
258 * is to be returned. It must be a
259 * {@link java.lang.Class Class}
260 * that implements interface {@link Attribute
261 * Attribute}.
262 *
263 * @return The attribute value in the given attribute category contained
264 * in this attribute set, or {@code null} if this attribute set
265 * does not contain any attribute value in the given attribute
266 * category.
267 *
268 * @throws NullPointerException
269 * (unchecked exception) Thrown if the {@code category} is null.
270 * @throws ClassCastException
271 * (unchecked exception) Thrown if the {@code category} is not a
272 * {@link java.lang.Class Class} that implements interface {@link
273 * Attribute Attribute}.
274 */
275 public Attribute get(Class<?> category) {
276 return attrMap.get(AttributeSetUtilities.
277 verifyAttributeCategory(category,
278 Attribute.class));
279 }
280
281 /**
282 * Adds the specified attribute to this attribute set if it is not
283 * already present, first removing any existing in the same
284 * attribute category as the specified attribute value.
285 *
286 * @param attribute Attribute value to be added to this attribute set.
287 *
288 * @return {@code true} if this attribute set changed as a result of the
289 * call, i.e., the given attribute value was not already a
290 * member of this attribute set.
291 *
292 * @throws NullPointerException
293 * (unchecked exception) Thrown if the {@code attribute} is null.
294 * @throws UnmodifiableSetException
295 * (unchecked exception) Thrown if this attribute set does not support
296 * the {@code add()} operation.
297 */
298 public boolean add(Attribute attribute) {
299 Object oldAttribute =
300 attrMap.put(attribute.getCategory(),
301 AttributeSetUtilities.
302 verifyAttributeValue(attribute, myInterface));
303 return (!attribute.equals(oldAttribute));
304 }
305
306 /**
307 * Removes any attribute for this category from this attribute set if
308 * present. If {@code category} is null, then
309 * {@code remove()} does nothing and returns {@code false}.
310 *
311 * @param category Attribute category to be removed from this
312 * attribute set.
313 *
314 * @return {@code true} if this attribute set changed as a result of the
315 * call, i.e., the given attribute category had been a member of
316 * this attribute set.
317 *
318 * @throws UnmodifiableSetException
319 * (unchecked exception) Thrown if this attribute set does not
320 * support the {@code remove()} operation.
321 */
322 public boolean remove(Class<?> category) {
323 return
324 category != null &&
325 AttributeSetUtilities.
326 verifyAttributeCategory(category, Attribute.class) != null &&
327 attrMap.remove(category) != null;
328 }
329
330 /**
331 * Removes the specified attribute from this attribute set if
332 * present. If {@code attribute} is null, then
333 * {@code remove()} does nothing and returns {@code false}.
334 *
335 * @param attribute Attribute value to be removed from this attribute set.
336 *
337 * @return {@code true} if this attribute set changed as a result of the
338 * call, i.e., the given attribute value had been a member of
339 * this attribute set.
340 *
341 * @throws UnmodifiableSetException
342 * (unchecked exception) Thrown if this attribute set does not
343 * support the {@code remove()} operation.
344 */
345 public boolean remove(Attribute attribute) {
346 return
347 attribute != null &&
348 attrMap.remove(attribute.getCategory()) != null;
349 }
350
351 /**
352 * Returns {@code true} if this attribute set contains an
353 * attribute for the specified category.
354 *
355 * @param category whose presence in this attribute set is
356 * to be tested.
357 *
358 * @return {@code true} if this attribute set contains an attribute
359 * value for the specified category.
360 */
361 public boolean containsKey(Class<?> category) {
362 return
363 category != null &&
364 AttributeSetUtilities.
365 verifyAttributeCategory(category, Attribute.class) != null &&
366 attrMap.get(category) != null;
367 }
368
369 /**
370 * Returns {@code true} if this attribute set contains the given
371 * attribute.
372 *
373 * @param attribute value whose presence in this attribute set is
374 * to be tested.
375 *
376 * @return {@code true} if this attribute set contains the given
377 * attribute value.
378 */
379 public boolean containsValue(Attribute attribute) {
380 return
381 attribute != null &&
382 attribute instanceof Attribute &&
383 attribute.equals(attrMap.get(attribute.getCategory()));
384 }
385
386 /**
387 * Adds all of the elements in the specified set to this attribute.
388 * The outcome is the same as if the
389 * {@link #add(Attribute) add(Attribute)}
390 * operation had been applied to this attribute set successively with
391 * each element from the specified set.
392 * The behavior of the {@code addAll(AttributeSet)}
393 * operation is unspecified if the specified set is modified while
394 * the operation is in progress.
395 * <P>
396 * If the {@code addAll(AttributeSet)} operation throws an exception,
397 * the effect on this attribute set's state is implementation dependent;
398 * elements from the specified set before the point of the exception may
399 * or may not have been added to this attribute set.
400 *
401 * @param attributes whose elements are to be added to this attribute
402 * set.
403 *
404 * @return {@code true} if this attribute set changed as a result of the
405 * call.
406 *
407 * @throws UnmodifiableSetException
408 * (Unchecked exception) Thrown if this attribute set does not
409 * support the {@code addAll(AttributeSet)} method.
410 * @throws NullPointerException
411 * (Unchecked exception) Thrown if some element in the specified
412 * set is null, or the set is null.
413 *
414 * @see #add(Attribute)
415 */
416 public boolean addAll(AttributeSet attributes) {
417
418 Attribute []attrs = attributes.toArray();
419 boolean result = false;
420 for (int i=0; i<attrs.length; i++) {
421 Attribute newValue =
422 AttributeSetUtilities.verifyAttributeValue(attrs[i],
423 myInterface);
424 Object oldValue = attrMap.put(newValue.getCategory(), newValue);
425 result = (! newValue.equals(oldValue)) || result;
426 }
427 return result;
428 }
429
430 /**
431 * Returns the number of attributes in this attribute set. If this
432 * attribute set contains more than {@code Integer.MAX_VALUE} elements,
433 * returns {@code Integer.MAX_VALUE}.
434 *
435 * @return The number of attributes in this attribute set.
436 */
437 public int size() {
438 return attrMap.size();
439 }
440
441 /**
442 *
443 * @return the Attributes contained in this set as an array, zero length
444 * if the AttributeSet is empty.
445 */
446 public Attribute[] toArray() {
447 Attribute []attrs = new Attribute[size()];
448 attrMap.values().toArray(attrs);
449 return attrs;
450 }
451
452
453 /**
454 * Removes all attributes from this attribute set.
455 *
456 * @throws UnmodifiableSetException
457 * (unchecked exception) Thrown if this attribute set does not support
458 * the {@code clear()} operation.
459 */
460 public void clear() {
461 attrMap.clear();
462 }
463
464 /**
465 * Returns true if this attribute set contains no attributes.
466 *
467 * @return true if this attribute set contains no attributes.
468 */
469 public boolean isEmpty() {
470 return attrMap.isEmpty();
471 }
472
473 /**
474 * Compares the specified object with this attribute set for equality.
475 * Returns {@code true} if the given object is also an attribute set and
476 * the two attribute sets contain the same attribute category-attribute
477 * value mappings. This ensures that the
478 * {@code equals()} method works properly across different
479 * implementations of the AttributeSet interface.
480 *
481 * @param object to be compared for equality with this attribute set.
482 *
483 * @return {@code true} if the specified object is equal to this
484 * attribute set.
485 */
486
487 public boolean equals(Object object) {
488 if (object == null || !(object instanceof AttributeSet)) {
489 return false;
490 }
491
492 AttributeSet aset = (AttributeSet)object;
493 if (aset.size() != size()) {
494 return false;
495 }
496
497 Attribute[] attrs = toArray();
498 for (int i=0;i<attrs.length; i++) {
499 if (!aset.containsValue(attrs[i])) {
500 return false;
501 }
502 }
503 return true;
504 }
505
506 /**
507 * Returns the hash code value for this attribute set.
508 * The hash code of an attribute set is defined to be the sum
509 * of the hash codes of each entry in the AttributeSet.
510 * This ensures that {@code t1.equals(t2)} implies that
511 * {@code t1.hashCode()==t2.hashCode()} for any two attribute sets
512 * {@code t1} and {@code t2}, as required by the general contract of
513 * {@link java.lang.Object#hashCode() Object.hashCode()}.
514 *
515 * @return The hash code value for this attribute set.
516 */
517 public int hashCode() {
518 int hcode = 0;
519 Attribute[] attrs = toArray();
520 for (int i=0;i<attrs.length; i++) {
521 hcode += attrs[i].hashCode();
522 }
523 return hcode;
524 }
525
526 }
|