1 /* 2 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 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.Serializable; 29 30 /** 31 * Class {@code AttributeSetUtilities} provides static methods for manipulating 32 * {@code AttributeSets}. 33 * <ul> 34 * <li>Methods for creating unmodifiable and synchronized views of attribute 35 * sets. 36 * <li>operations useful for building implementations of interface 37 * {@link AttributeSet AttributeSet} 38 * </ul> 39 * An <b>unmodifiable view</b> <i>U</i> of an {@code AttributeSet} <i>S</i> 40 * provides a client with "read-only" access to <i>S</i>. Query operations on 41 * <i>U</i> "read through" to <i>S</i>; thus, changes in <i>S</i> are reflected 42 * in <i>U</i>. However, any attempt to modify <i>U</i>, results in an 43 * {@code UnmodifiableSetException}. The unmodifiable view object <i>U</i> will 44 * be serializable if the attribute set object <i>S</i> is serializable. 45 * <p> 46 * A <b>synchronized view</b> <i>V</i> of an attribute set <i>S</i> provides a 47 * client with synchronized (multiple thread safe) access to <i>S</i>. Each 48 * operation of <i>V</i> is synchronized using <i>V</i> itself as the lock 49 * object and then merely invokes the corresponding operation of <i>S</i>. In 50 * order to guarantee mutually exclusive access, it is critical that all access 51 * to <i>S</i> is accomplished through <i>V</i>. The synchronized view object 52 * <i>V</i> will be serializable if the attribute set object <i>S</i> is 53 * serializable. 54 * <p> 55 * As mentioned in the package description of {@code javax.print}, a 56 * {@code null} reference parameter to methods is incorrect unless explicitly 57 * documented on the method as having a meaningful interpretation. Usage to the 58 * contrary is incorrect coding and may result in a run time exception either 59 * immediately or at some later time. {@code IllegalArgumentException} and 60 * {@code NullPointerException} are examples of typical and acceptable run time 61 * exceptions for such cases. 62 * 63 * @author Alan Kaminsky 64 */ 65 public final class AttributeSetUtilities { 66 67 /** 68 * Suppress default constructor, ensuring non-instantiability. 69 */ 70 private AttributeSetUtilities() { 71 } 72 73 /** 74 * Unmodifiable view of {@code AttributeSet}. 75 * 76 * @serial include 77 */ 78 private static class UnmodifiableAttributeSet 79 implements AttributeSet, Serializable { 80 81 /** 82 * Use serialVersionUID from JDK 1.4 for interoperability. 83 */ 84 private static final long serialVersionUID = -6131802583863447813L; 85 86 /** 87 * The attribute set. 88 */ 89 @SuppressWarnings("serial") // Not statically typed as Serializable 90 private AttributeSet attrset; 91 92 /** 93 * Constructs unmodifiable view of the underlying attribute set. 94 * 95 * @param attributeSet the attribute set 96 */ 97 public UnmodifiableAttributeSet(AttributeSet attributeSet) { 98 99 attrset = attributeSet; 100 } 101 102 public Attribute get(Class<?> key) { 103 return attrset.get(key); 104 } 105 106 public boolean add(Attribute attribute) { 107 throw new UnmodifiableSetException(); 108 } 109 110 public synchronized boolean remove(Class<?> category) { 111 throw new UnmodifiableSetException(); 112 } 113 114 public boolean remove(Attribute attribute) { 115 throw new UnmodifiableSetException(); 116 } 117 118 public boolean containsKey(Class<?> category) { 119 return attrset.containsKey(category); 120 } 121 122 public boolean containsValue(Attribute attribute) { 123 return attrset.containsValue(attribute); 124 } 125 126 public boolean addAll(AttributeSet attributes) { 127 throw new UnmodifiableSetException(); 128 } 129 130 public int size() { 131 return attrset.size(); 132 } 133 134 public Attribute[] toArray() { 135 return attrset.toArray(); 136 } 137 138 public void clear() { 139 throw new UnmodifiableSetException(); 140 } 141 142 public boolean isEmpty() { 143 return attrset.isEmpty(); 144 } 145 146 public boolean equals(Object o) { 147 return attrset.equals (o); 148 } 149 150 public int hashCode() { 151 return attrset.hashCode(); 152 } 153 } 154 155 /** 156 * Unmodifiable view of {@code DocAttributeSet}. 157 * 158 * @serial include 159 */ 160 private static class UnmodifiableDocAttributeSet 161 extends UnmodifiableAttributeSet 162 implements DocAttributeSet, Serializable { 163 164 /** 165 * Use serialVersionUID from JDK 1.4 for interoperability. 166 */ 167 private static final long serialVersionUID = -6349408326066898956L; 168 169 /** 170 * Constructs a new unmodifiable doc attribute set. 171 * 172 * @param attributeSet the doc attribute set 173 */ 174 public UnmodifiableDocAttributeSet(DocAttributeSet attributeSet) { 175 176 super (attributeSet); 177 } 178 } 179 180 /** 181 * Unmodifiable view of {@code PrintRequestAttributeSet}. 182 * 183 * @serial include 184 */ 185 private static class UnmodifiablePrintRequestAttributeSet 186 extends UnmodifiableAttributeSet 187 implements PrintRequestAttributeSet, Serializable 188 { 189 190 /** 191 * Use serialVersionUID from JDK 1.4 for interoperability. 192 */ 193 private static final long serialVersionUID = 7799373532614825073L; 194 195 /** 196 * Constructs a new unmodifiable print request attribute set. 197 * 198 * @param attributeSet the print request attribute set 199 */ 200 public UnmodifiablePrintRequestAttributeSet 201 (PrintRequestAttributeSet attributeSet) { 202 203 super (attributeSet); 204 } 205 } 206 207 /** 208 * Unmodifiable view of {@code PrintJobAttributeSet}. 209 * 210 * @serial include 211 */ 212 private static class UnmodifiablePrintJobAttributeSet 213 extends UnmodifiableAttributeSet 214 implements PrintJobAttributeSet, Serializable 215 { 216 /** 217 * Use serialVersionUID from JDK 1.4 for interoperability. 218 */ 219 private static final long serialVersionUID = -8002245296274522112L; 220 221 /** 222 * Constructs a new unmodifiable print job attribute set. 223 * 224 * @param attributeSet the print job attribute set 225 */ 226 public UnmodifiablePrintJobAttributeSet 227 (PrintJobAttributeSet attributeSet) { 228 229 super (attributeSet); 230 } 231 } 232 233 /** 234 * Unmodifiable view of {@code PrintServiceAttributeSet}. 235 * 236 * @serial include 237 */ 238 private static class UnmodifiablePrintServiceAttributeSet 239 extends UnmodifiableAttributeSet 240 implements PrintServiceAttributeSet, Serializable 241 { 242 /** 243 * Use serialVersionUID from JDK 1.4 for interoperability. 244 */ 245 private static final long serialVersionUID = -7112165137107826819L; 246 247 /** 248 * Constructs a new unmodifiable print service attribute set. 249 * 250 * @param attributeSet the print service attribute set 251 */ 252 public UnmodifiablePrintServiceAttributeSet 253 (PrintServiceAttributeSet attributeSet) { 254 255 super (attributeSet); 256 } 257 } 258 259 /** 260 * Creates an unmodifiable view of the given attribute set. 261 * 262 * @param attributeSet underlying attribute set 263 * @return unmodifiable view of {@code attributeSet} 264 * @throws NullPointerException if {@code attributeSet} is {@code null} 265 */ 266 public static AttributeSet unmodifiableView(AttributeSet attributeSet) { 267 if (attributeSet == null) { 268 throw new NullPointerException(); 269 } 270 271 return new UnmodifiableAttributeSet(attributeSet); 272 } 273 274 /** 275 * Creates an unmodifiable view of the given doc attribute set. 276 * 277 * @param attributeSet underlying doc attribute set 278 * @return unmodifiable view of {@code attributeSet} 279 * @throws NullPointerException if {@code attributeSet} is {@code null} 280 */ 281 public static DocAttributeSet unmodifiableView 282 (DocAttributeSet attributeSet) { 283 if (attributeSet == null) { 284 throw new NullPointerException(); 285 } 286 return new UnmodifiableDocAttributeSet(attributeSet); 287 } 288 289 /** 290 * Creates an unmodifiable view of the given print request attribute set. 291 * 292 * @param attributeSet underlying print request attribute set 293 * @return unmodifiable view of {@code attributeSet} 294 * @throws NullPointerException if {@code attributeSet} is {@code null} 295 */ 296 public static PrintRequestAttributeSet 297 unmodifiableView(PrintRequestAttributeSet attributeSet) { 298 if (attributeSet == null) { 299 throw new NullPointerException(); 300 } 301 return new UnmodifiablePrintRequestAttributeSet(attributeSet); 302 } 303 304 /** 305 * Creates an unmodifiable view of the given print job attribute set. 306 * 307 * @param attributeSet underlying print job attribute set 308 * @return unmodifiable view of {@code attributeSet} 309 * @throws NullPointerException if {@code attributeSet} is {@code null} 310 */ 311 public static PrintJobAttributeSet 312 unmodifiableView(PrintJobAttributeSet attributeSet) { 313 if (attributeSet == null) { 314 throw new NullPointerException(); 315 } 316 return new UnmodifiablePrintJobAttributeSet(attributeSet); 317 } 318 319 /** 320 * Creates an unmodifiable view of the given print service attribute set. 321 * 322 * @param attributeSet underlying print service attribute set 323 * @return unmodifiable view of {@code attributeSet} 324 * @throws NullPointerException if {@code attributeSet} is {@code null} 325 */ 326 public static PrintServiceAttributeSet 327 unmodifiableView(PrintServiceAttributeSet attributeSet) { 328 if (attributeSet == null) { 329 throw new NullPointerException(); 330 } 331 return new UnmodifiablePrintServiceAttributeSet (attributeSet); 332 } 333 334 /** 335 * Synchronized view of {@code AttributeSet}. 336 * 337 * @serial include 338 */ 339 private static class SynchronizedAttributeSet 340 implements AttributeSet, Serializable { 341 342 /** 343 * Use serialVersionUID from JDK 1.4 for interoperability. 344 */ 345 private static final long serialVersionUID = 8365731020128564925L; 346 347 /** 348 * The attribute set. 349 */ 350 @SuppressWarnings("serial") // Not statically typed as Serializable 351 private AttributeSet attrset; 352 353 /** 354 * Constructs a new synchronized attribute set. 355 * 356 * @param attributeSet the attribute set 357 */ 358 public SynchronizedAttributeSet(AttributeSet attributeSet) { 359 attrset = attributeSet; 360 } 361 362 public synchronized Attribute get(Class<?> category) { 363 return attrset.get(category); 364 } 365 366 public synchronized boolean add(Attribute attribute) { 367 return attrset.add(attribute); 368 } 369 370 public synchronized boolean remove(Class<?> category) { 371 return attrset.remove(category); 372 } 373 374 public synchronized boolean remove(Attribute attribute) { 375 return attrset.remove(attribute); 376 } 377 378 public synchronized boolean containsKey(Class<?> category) { 379 return attrset.containsKey(category); 380 } 381 382 public synchronized boolean containsValue(Attribute attribute) { 383 return attrset.containsValue(attribute); 384 } 385 386 public synchronized boolean addAll(AttributeSet attributes) { 387 return attrset.addAll(attributes); 388 } 389 390 public synchronized int size() { 391 return attrset.size(); 392 } 393 394 public synchronized Attribute[] toArray() { 395 return attrset.toArray(); 396 } 397 398 public synchronized void clear() { 399 attrset.clear(); 400 } 401 402 public synchronized boolean isEmpty() { 403 return attrset.isEmpty(); 404 } 405 406 public synchronized boolean equals(Object o) { 407 return attrset.equals (o); 408 } 409 410 public synchronized int hashCode() { 411 return attrset.hashCode(); 412 } 413 } 414 415 /** 416 * Synchronized view of {@code DocAttributeSet}. 417 * 418 * @serial include 419 */ 420 private static class SynchronizedDocAttributeSet 421 extends SynchronizedAttributeSet 422 implements DocAttributeSet, Serializable { 423 424 /** 425 * Use serialVersionUID from JDK 1.4 for interoperability. 426 */ 427 private static final long serialVersionUID = 6455869095246629354L; 428 429 /** 430 * Constructs a new synchronized doc attribute set. 431 * 432 * @param attributeSet the doc attribute set 433 */ 434 public SynchronizedDocAttributeSet(DocAttributeSet attributeSet) { 435 super(attributeSet); 436 } 437 } 438 439 /** 440 * Synchronized view of {@code PrintRequestAttributeSet}. 441 * 442 * @serial include 443 */ 444 private static class SynchronizedPrintRequestAttributeSet 445 extends SynchronizedAttributeSet 446 implements PrintRequestAttributeSet, Serializable { 447 448 /** 449 * Use serialVersionUID from JDK 1.4 for interoperability. 450 */ 451 private static final long serialVersionUID = 5671237023971169027L; 452 453 /** 454 * Constructs a new synchronized print request attribute set. 455 * 456 * @param attributeSet the print request attribute set 457 */ 458 public SynchronizedPrintRequestAttributeSet 459 (PrintRequestAttributeSet attributeSet) { 460 super(attributeSet); 461 } 462 } 463 464 /** 465 * Synchronized view of {@code PrintJobAttributeSet}. 466 * 467 * @serial include 468 */ 469 private static class SynchronizedPrintJobAttributeSet 470 extends SynchronizedAttributeSet 471 implements PrintJobAttributeSet, Serializable { 472 473 /** 474 * Use serialVersionUID from JDK 1.4 for interoperability. 475 */ 476 private static final long serialVersionUID = 2117188707856965749L; 477 478 /** 479 * Constructs a new synchronized print job attribute set. 480 * 481 * @param attributeSet the print job attribute set 482 */ 483 public SynchronizedPrintJobAttributeSet 484 (PrintJobAttributeSet attributeSet) { 485 super(attributeSet); 486 } 487 } 488 489 /** 490 * Synchronized view of {@code PrintServiceAttributeSet}. 491 * 492 * @serial include 493 */ 494 private static class SynchronizedPrintServiceAttributeSet 495 extends SynchronizedAttributeSet 496 implements PrintServiceAttributeSet, Serializable { 497 498 /** 499 * Use serialVersionUID from JDK 1.4 for interoperability. 500 */ 501 private static final long serialVersionUID = -2830705374001675073L; 502 503 /** 504 * Constructs a new synchronized print service attribute set. 505 * 506 * @param attributeSet the print service attribute set 507 */ 508 public SynchronizedPrintServiceAttributeSet 509 (PrintServiceAttributeSet attributeSet) { 510 super(attributeSet); 511 } 512 } 513 514 /** 515 * Creates a synchronized view of the given attribute set. 516 * 517 * @param attributeSet underlying attribute set 518 * @return synchronized view of {@code attributeSet} 519 * @throws NullPointerException if {@code attributeSet} is {@code null} 520 */ 521 public static AttributeSet synchronizedView 522 (AttributeSet attributeSet) { 523 if (attributeSet == null) { 524 throw new NullPointerException(); 525 } 526 return new SynchronizedAttributeSet(attributeSet); 527 } 528 529 /** 530 * Creates a synchronized view of the given doc attribute set. 531 * 532 * @param attributeSet underlying doc attribute set 533 * @return synchronized view of {@code attributeSet} 534 * @throws NullPointerException if {@code attributeSet} is {@code null} 535 */ 536 public static DocAttributeSet 537 synchronizedView(DocAttributeSet attributeSet) { 538 if (attributeSet == null) { 539 throw new NullPointerException(); 540 } 541 return new SynchronizedDocAttributeSet(attributeSet); 542 } 543 544 /** 545 * Creates a synchronized view of the given print request attribute set. 546 * 547 * @param attributeSet underlying print request attribute set 548 * @return synchronized view of {@code attributeSet} 549 * @throws NullPointerException if {@code attributeSet} is {@code null} 550 */ 551 public static PrintRequestAttributeSet 552 synchronizedView(PrintRequestAttributeSet attributeSet) { 553 if (attributeSet == null) { 554 throw new NullPointerException(); 555 } 556 return new SynchronizedPrintRequestAttributeSet(attributeSet); 557 } 558 559 /** 560 * Creates a synchronized view of the given print job attribute set. 561 * 562 * @param attributeSet underlying print job attribute set 563 * @return synchronized view of {@code attributeSet} 564 * @throws NullPointerException if {@code attributeSet} is {@code null} 565 */ 566 public static PrintJobAttributeSet 567 synchronizedView(PrintJobAttributeSet attributeSet) { 568 if (attributeSet == null) { 569 throw new NullPointerException(); 570 } 571 return new SynchronizedPrintJobAttributeSet(attributeSet); 572 } 573 574 /** 575 * Creates a synchronized view of the given print service attribute set. 576 * 577 * @param attributeSet underlying print service attribute set 578 * @return synchronized view of {@code attributeSet} 579 * @throws NullPointerException if {@code attributeSet} is {@code null} 580 */ 581 public static PrintServiceAttributeSet 582 synchronizedView(PrintServiceAttributeSet attributeSet) { 583 if (attributeSet == null) { 584 throw new NullPointerException(); 585 } 586 return new SynchronizedPrintServiceAttributeSet(attributeSet); 587 } 588 589 /** 590 * Verify that the given object is a {@link Class Class} that implements the 591 * given interface, which is assumed to be interface 592 * {@link Attribute Attribute} or a subinterface thereof. 593 * 594 * @param object {@code Object} to test 595 * @param interfaceName interface the object must implement 596 * @return if {@code object} is a {@link Class Class} that implements 597 * {@code interfaceName}, {@code object} is returned downcast to 598 * type {@link Class Class}; otherwise an exception is thrown 599 * @throws NullPointerException if {@code object} is {@code null} 600 * @throws ClassCastException if {@code object} is not a 601 * {@link Class Class} that implements {@code interfaceName} 602 */ 603 public static Class<?> 604 verifyAttributeCategory(Object object, Class<?> interfaceName) { 605 606 Class<?> result = (Class<?>) object; 607 if (interfaceName.isAssignableFrom (result)) { 608 return result; 609 } 610 else { 611 throw new ClassCastException(); 612 } 613 } 614 615 /** 616 * Verify that the given object is an instance of the given interface, which 617 * is assumed to be interface {@link Attribute Attribute} or a subinterface 618 * thereof. 619 * 620 * @param object {@code Object} to test 621 * @param interfaceName interface of which the object must be an instance 622 * @return if {@code object} is an instance of {@code interfaceName}, 623 * {@code object} is returned downcast to type 624 * {@link Attribute Attribute}; otherwise an exception is thrown 625 * @throws NullPointerException if {@code object} is {@code null} 626 * @throws ClassCastException if {@code object} is not an instance of 627 * {@code interfaceName} 628 */ 629 public static Attribute 630 verifyAttributeValue(Object object, Class<?> interfaceName) { 631 632 if (object == null) { 633 throw new NullPointerException(); 634 } 635 else if (interfaceName.isInstance (object)) { 636 return (Attribute) object; 637 } else { 638 throw new ClassCastException(); 639 } 640 } 641 642 /** 643 * Verify that the given attribute category object is equal to the category 644 * of the given attribute value object. If so, this method returns doing 645 * nothing. If not, this method throws an exception. 646 * 647 * @param category attribute category to test 648 * @param attribute attribute value to test 649 * @throws NullPointerException if the {@code category} or {@code attribute} 650 * are {@code null} 651 * @throws IllegalArgumentException if the {@code category} is not equal to 652 * the category of the {@code attribute} 653 */ 654 public static void 655 verifyCategoryForValue(Class<?> category, Attribute attribute) { 656 657 if (!category.equals (attribute.getCategory())) { 658 throw new IllegalArgumentException(); 659 } 660 } 661 }