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 */ AttributeSetUtilities()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 private AttributeSet attrset; 90 91 /** 92 * Constructs unmodifiable view of the underlying attribute set. 93 * 94 * @param attributeSet the attribute set 95 */ UnmodifiableAttributeSet(AttributeSet attributeSet)96 public UnmodifiableAttributeSet(AttributeSet attributeSet) { 97 98 attrset = attributeSet; 99 } 100 get(Class<?> key)101 public Attribute get(Class<?> key) { 102 return attrset.get(key); 103 } 104 add(Attribute attribute)105 public boolean add(Attribute attribute) { 106 throw new UnmodifiableSetException(); 107 } 108 remove(Class<?> category)109 public synchronized boolean remove(Class<?> category) { 110 throw new UnmodifiableSetException(); 111 } 112 remove(Attribute attribute)113 public boolean remove(Attribute attribute) { 114 throw new UnmodifiableSetException(); 115 } 116 containsKey(Class<?> category)117 public boolean containsKey(Class<?> category) { 118 return attrset.containsKey(category); 119 } 120 containsValue(Attribute attribute)121 public boolean containsValue(Attribute attribute) { 122 return attrset.containsValue(attribute); 123 } 124 addAll(AttributeSet attributes)125 public boolean addAll(AttributeSet attributes) { 126 throw new UnmodifiableSetException(); 127 } 128 size()129 public int size() { 130 return attrset.size(); 131 } 132 toArray()133 public Attribute[] toArray() { 134 return attrset.toArray(); 135 } 136 clear()137 public void clear() { 138 throw new UnmodifiableSetException(); 139 } 140 isEmpty()141 public boolean isEmpty() { 142 return attrset.isEmpty(); 143 } 144 equals(Object o)145 public boolean equals(Object o) { 146 return attrset.equals (o); 147 } 148 hashCode()149 public int hashCode() { 150 return attrset.hashCode(); 151 } 152 } 153 154 /** 155 * Unmodifiable view of {@code DocAttributeSet}. 156 * 157 * @serial include 158 */ 159 private static class UnmodifiableDocAttributeSet 160 extends UnmodifiableAttributeSet 161 implements DocAttributeSet, Serializable { 162 163 /** 164 * Use serialVersionUID from JDK 1.4 for interoperability. 165 */ 166 private static final long serialVersionUID = -6349408326066898956L; 167 168 /** 169 * Constructs a new unmodifiable doc attribute set. 170 * 171 * @param attributeSet the doc attribute set 172 */ UnmodifiableDocAttributeSet(DocAttributeSet attributeSet)173 public UnmodifiableDocAttributeSet(DocAttributeSet attributeSet) { 174 175 super (attributeSet); 176 } 177 } 178 179 /** 180 * Unmodifiable view of {@code PrintRequestAttributeSet}. 181 * 182 * @serial include 183 */ 184 private static class UnmodifiablePrintRequestAttributeSet 185 extends UnmodifiableAttributeSet 186 implements PrintRequestAttributeSet, Serializable 187 { 188 189 /** 190 * Use serialVersionUID from JDK 1.4 for interoperability. 191 */ 192 private static final long serialVersionUID = 7799373532614825073L; 193 194 /** 195 * Constructs a new unmodifiable print request attribute set. 196 * 197 * @param attributeSet the print request attribute set 198 */ UnmodifiablePrintRequestAttributeSet(PrintRequestAttributeSet attributeSet)199 public UnmodifiablePrintRequestAttributeSet 200 (PrintRequestAttributeSet attributeSet) { 201 202 super (attributeSet); 203 } 204 } 205 206 /** 207 * Unmodifiable view of {@code PrintJobAttributeSet}. 208 * 209 * @serial include 210 */ 211 private static class UnmodifiablePrintJobAttributeSet 212 extends UnmodifiableAttributeSet 213 implements PrintJobAttributeSet, Serializable 214 { 215 /** 216 * Use serialVersionUID from JDK 1.4 for interoperability. 217 */ 218 private static final long serialVersionUID = -8002245296274522112L; 219 220 /** 221 * Constructs a new unmodifiable print job attribute set. 222 * 223 * @param attributeSet the print job attribute set 224 */ UnmodifiablePrintJobAttributeSet(PrintJobAttributeSet attributeSet)225 public UnmodifiablePrintJobAttributeSet 226 (PrintJobAttributeSet attributeSet) { 227 228 super (attributeSet); 229 } 230 } 231 232 /** 233 * Unmodifiable view of {@code PrintServiceAttributeSet}. 234 * 235 * @serial include 236 */ 237 private static class UnmodifiablePrintServiceAttributeSet 238 extends UnmodifiableAttributeSet 239 implements PrintServiceAttributeSet, Serializable 240 { 241 /** 242 * Use serialVersionUID from JDK 1.4 for interoperability. 243 */ 244 private static final long serialVersionUID = -7112165137107826819L; 245 246 /** 247 * Constructs a new unmodifiable print service attribute set. 248 * 249 * @param attributeSet the print service attribute set 250 */ UnmodifiablePrintServiceAttributeSet(PrintServiceAttributeSet attributeSet)251 public UnmodifiablePrintServiceAttributeSet 252 (PrintServiceAttributeSet attributeSet) { 253 254 super (attributeSet); 255 } 256 } 257 258 /** 259 * Creates an unmodifiable view of the given attribute set. 260 * 261 * @param attributeSet underlying attribute set 262 * @return unmodifiable view of {@code attributeSet} 263 * @throws NullPointerException if {@code attributeSet} is {@code null} 264 */ unmodifiableView(AttributeSet attributeSet)265 public static AttributeSet unmodifiableView(AttributeSet attributeSet) { 266 if (attributeSet == null) { 267 throw new NullPointerException(); 268 } 269 270 return new UnmodifiableAttributeSet(attributeSet); 271 } 272 273 /** 274 * Creates an unmodifiable view of the given doc attribute set. 275 * 276 * @param attributeSet underlying doc attribute set 277 * @return unmodifiable view of {@code attributeSet} 278 * @throws NullPointerException if {@code attributeSet} is {@code null} 279 */ unmodifiableView(DocAttributeSet attributeSet)280 public static DocAttributeSet unmodifiableView 281 (DocAttributeSet attributeSet) { 282 if (attributeSet == null) { 283 throw new NullPointerException(); 284 } 285 return new UnmodifiableDocAttributeSet(attributeSet); 286 } 287 288 /** 289 * Creates an unmodifiable view of the given print request attribute set. 290 * 291 * @param attributeSet underlying print request attribute set 292 * @return unmodifiable view of {@code attributeSet} 293 * @throws NullPointerException if {@code attributeSet} is {@code null} 294 */ 295 public static PrintRequestAttributeSet unmodifiableView(PrintRequestAttributeSet attributeSet)296 unmodifiableView(PrintRequestAttributeSet attributeSet) { 297 if (attributeSet == null) { 298 throw new NullPointerException(); 299 } 300 return new UnmodifiablePrintRequestAttributeSet(attributeSet); 301 } 302 303 /** 304 * Creates an unmodifiable view of the given print job attribute set. 305 * 306 * @param attributeSet underlying print job attribute set 307 * @return unmodifiable view of {@code attributeSet} 308 * @throws NullPointerException if {@code attributeSet} is {@code null} 309 */ 310 public static PrintJobAttributeSet unmodifiableView(PrintJobAttributeSet attributeSet)311 unmodifiableView(PrintJobAttributeSet attributeSet) { 312 if (attributeSet == null) { 313 throw new NullPointerException(); 314 } 315 return new UnmodifiablePrintJobAttributeSet(attributeSet); 316 } 317 318 /** 319 * Creates an unmodifiable view of the given print service attribute set. 320 * 321 * @param attributeSet underlying print service attribute set 322 * @return unmodifiable view of {@code attributeSet} 323 * @throws NullPointerException if {@code attributeSet} is {@code null} 324 */ 325 public static PrintServiceAttributeSet unmodifiableView(PrintServiceAttributeSet attributeSet)326 unmodifiableView(PrintServiceAttributeSet attributeSet) { 327 if (attributeSet == null) { 328 throw new NullPointerException(); 329 } 330 return new UnmodifiablePrintServiceAttributeSet (attributeSet); 331 } 332 333 /** 334 * Synchronized view of {@code AttributeSet}. 335 * 336 * @serial include 337 */ 338 private static class SynchronizedAttributeSet 339 implements AttributeSet, Serializable { 340 341 /** 342 * Use serialVersionUID from JDK 1.4 for interoperability. 343 */ 344 private static final long serialVersionUID = 8365731020128564925L; 345 346 /** 347 * The attribute set. 348 */ 349 private AttributeSet attrset; 350 351 /** 352 * Constructs a new synchronized attribute set. 353 * 354 * @param attributeSet the attribute set 355 */ SynchronizedAttributeSet(AttributeSet attributeSet)356 public SynchronizedAttributeSet(AttributeSet attributeSet) { 357 attrset = attributeSet; 358 } 359 get(Class<?> category)360 public synchronized Attribute get(Class<?> category) { 361 return attrset.get(category); 362 } 363 add(Attribute attribute)364 public synchronized boolean add(Attribute attribute) { 365 return attrset.add(attribute); 366 } 367 remove(Class<?> category)368 public synchronized boolean remove(Class<?> category) { 369 return attrset.remove(category); 370 } 371 remove(Attribute attribute)372 public synchronized boolean remove(Attribute attribute) { 373 return attrset.remove(attribute); 374 } 375 containsKey(Class<?> category)376 public synchronized boolean containsKey(Class<?> category) { 377 return attrset.containsKey(category); 378 } 379 containsValue(Attribute attribute)380 public synchronized boolean containsValue(Attribute attribute) { 381 return attrset.containsValue(attribute); 382 } 383 addAll(AttributeSet attributes)384 public synchronized boolean addAll(AttributeSet attributes) { 385 return attrset.addAll(attributes); 386 } 387 size()388 public synchronized int size() { 389 return attrset.size(); 390 } 391 toArray()392 public synchronized Attribute[] toArray() { 393 return attrset.toArray(); 394 } 395 clear()396 public synchronized void clear() { 397 attrset.clear(); 398 } 399 isEmpty()400 public synchronized boolean isEmpty() { 401 return attrset.isEmpty(); 402 } 403 equals(Object o)404 public synchronized boolean equals(Object o) { 405 return attrset.equals (o); 406 } 407 hashCode()408 public synchronized int hashCode() { 409 return attrset.hashCode(); 410 } 411 } 412 413 /** 414 * Synchronized view of {@code DocAttributeSet}. 415 * 416 * @serial include 417 */ 418 private static class SynchronizedDocAttributeSet 419 extends SynchronizedAttributeSet 420 implements DocAttributeSet, Serializable { 421 422 /** 423 * Use serialVersionUID from JDK 1.4 for interoperability. 424 */ 425 private static final long serialVersionUID = 6455869095246629354L; 426 427 /** 428 * Constructs a new synchronized doc attribute set. 429 * 430 * @param attributeSet the doc attribute set 431 */ SynchronizedDocAttributeSet(DocAttributeSet attributeSet)432 public SynchronizedDocAttributeSet(DocAttributeSet attributeSet) { 433 super(attributeSet); 434 } 435 } 436 437 /** 438 * Synchronized view of {@code PrintRequestAttributeSet}. 439 * 440 * @serial include 441 */ 442 private static class SynchronizedPrintRequestAttributeSet 443 extends SynchronizedAttributeSet 444 implements PrintRequestAttributeSet, Serializable { 445 446 /** 447 * Use serialVersionUID from JDK 1.4 for interoperability. 448 */ 449 private static final long serialVersionUID = 5671237023971169027L; 450 451 /** 452 * Constructs a new synchronized print request attribute set. 453 * 454 * @param attributeSet the print request attribute set 455 */ SynchronizedPrintRequestAttributeSet(PrintRequestAttributeSet attributeSet)456 public SynchronizedPrintRequestAttributeSet 457 (PrintRequestAttributeSet attributeSet) { 458 super(attributeSet); 459 } 460 } 461 462 /** 463 * Synchronized view of {@code PrintJobAttributeSet}. 464 * 465 * @serial include 466 */ 467 private static class SynchronizedPrintJobAttributeSet 468 extends SynchronizedAttributeSet 469 implements PrintJobAttributeSet, Serializable { 470 471 /** 472 * Use serialVersionUID from JDK 1.4 for interoperability. 473 */ 474 private static final long serialVersionUID = 2117188707856965749L; 475 476 /** 477 * Constructs a new synchronized print job attribute set. 478 * 479 * @param attributeSet the print job attribute set 480 */ SynchronizedPrintJobAttributeSet(PrintJobAttributeSet attributeSet)481 public SynchronizedPrintJobAttributeSet 482 (PrintJobAttributeSet attributeSet) { 483 super(attributeSet); 484 } 485 } 486 487 /** 488 * Synchronized view of {@code PrintServiceAttributeSet}. 489 * 490 * @serial include 491 */ 492 private static class SynchronizedPrintServiceAttributeSet 493 extends SynchronizedAttributeSet 494 implements PrintServiceAttributeSet, Serializable { 495 496 /** 497 * Use serialVersionUID from JDK 1.4 for interoperability. 498 */ 499 private static final long serialVersionUID = -2830705374001675073L; 500 501 /** 502 * Constructs a new synchronized print service attribute set. 503 * 504 * @param attributeSet the print service attribute set 505 */ SynchronizedPrintServiceAttributeSet(PrintServiceAttributeSet attributeSet)506 public SynchronizedPrintServiceAttributeSet 507 (PrintServiceAttributeSet attributeSet) { 508 super(attributeSet); 509 } 510 } 511 512 /** 513 * Creates a synchronized view of the given attribute set. 514 * 515 * @param attributeSet underlying attribute set 516 * @return synchronized view of {@code attributeSet} 517 * @throws NullPointerException if {@code attributeSet} is {@code null} 518 */ synchronizedView(AttributeSet attributeSet)519 public static AttributeSet synchronizedView 520 (AttributeSet attributeSet) { 521 if (attributeSet == null) { 522 throw new NullPointerException(); 523 } 524 return new SynchronizedAttributeSet(attributeSet); 525 } 526 527 /** 528 * Creates a synchronized view of the given doc attribute set. 529 * 530 * @param attributeSet underlying doc attribute set 531 * @return synchronized view of {@code attributeSet} 532 * @throws NullPointerException if {@code attributeSet} is {@code null} 533 */ 534 public static DocAttributeSet synchronizedView(DocAttributeSet attributeSet)535 synchronizedView(DocAttributeSet attributeSet) { 536 if (attributeSet == null) { 537 throw new NullPointerException(); 538 } 539 return new SynchronizedDocAttributeSet(attributeSet); 540 } 541 542 /** 543 * Creates a synchronized view of the given print request attribute set. 544 * 545 * @param attributeSet underlying print request attribute set 546 * @return synchronized view of {@code attributeSet} 547 * @throws NullPointerException if {@code attributeSet} is {@code null} 548 */ 549 public static PrintRequestAttributeSet synchronizedView(PrintRequestAttributeSet attributeSet)550 synchronizedView(PrintRequestAttributeSet attributeSet) { 551 if (attributeSet == null) { 552 throw new NullPointerException(); 553 } 554 return new SynchronizedPrintRequestAttributeSet(attributeSet); 555 } 556 557 /** 558 * Creates a synchronized view of the given print job attribute set. 559 * 560 * @param attributeSet underlying print job attribute set 561 * @return synchronized view of {@code attributeSet} 562 * @throws NullPointerException if {@code attributeSet} is {@code null} 563 */ 564 public static PrintJobAttributeSet synchronizedView(PrintJobAttributeSet attributeSet)565 synchronizedView(PrintJobAttributeSet attributeSet) { 566 if (attributeSet == null) { 567 throw new NullPointerException(); 568 } 569 return new SynchronizedPrintJobAttributeSet(attributeSet); 570 } 571 572 /** 573 * Creates a synchronized view of the given print service attribute set. 574 * 575 * @param attributeSet underlying print service attribute set 576 * @return synchronized view of {@code attributeSet} 577 * @throws NullPointerException if {@code attributeSet} is {@code null} 578 */ 579 public static PrintServiceAttributeSet synchronizedView(PrintServiceAttributeSet attributeSet)580 synchronizedView(PrintServiceAttributeSet attributeSet) { 581 if (attributeSet == null) { 582 throw new NullPointerException(); 583 } 584 return new SynchronizedPrintServiceAttributeSet(attributeSet); 585 } 586 587 /** 588 * Verify that the given object is a {@link Class Class} that implements the 589 * given interface, which is assumed to be interface 590 * {@link Attribute Attribute} or a subinterface thereof. 591 * 592 * @param object {@code Object} to test 593 * @param interfaceName interface the object must implement 594 * @return if {@code object} is a {@link Class Class} that implements 595 * {@code interfaceName}, {@code object} is returned downcast to 596 * type {@link Class Class}; otherwise an exception is thrown 597 * @throws NullPointerException if {@code object} is {@code null} 598 * @throws ClassCastException if {@code object} is not a 599 * {@link Class Class} that implements {@code interfaceName} 600 */ 601 public static Class<?> verifyAttributeCategory(Object object, Class<?> interfaceName)602 verifyAttributeCategory(Object object, Class<?> interfaceName) { 603 604 Class<?> result = (Class<?>) object; 605 if (interfaceName.isAssignableFrom (result)) { 606 return result; 607 } 608 else { 609 throw new ClassCastException(); 610 } 611 } 612 613 /** 614 * Verify that the given object is an instance of the given interface, which 615 * is assumed to be interface {@link Attribute Attribute} or a subinterface 616 * thereof. 617 * 618 * @param object {@code Object} to test 619 * @param interfaceName interface of which the object must be an instance 620 * @return if {@code object} is an instance of {@code interfaceName}, 621 * {@code object} is returned downcast to type 622 * {@link Attribute Attribute}; otherwise an exception is thrown 623 * @throws NullPointerException if {@code object} is {@code null} 624 * @throws ClassCastException if {@code object} is not an instance of 625 * {@code interfaceName} 626 */ 627 public static Attribute verifyAttributeValue(Object object, Class<?> interfaceName)628 verifyAttributeValue(Object object, Class<?> interfaceName) { 629 630 if (object == null) { 631 throw new NullPointerException(); 632 } 633 else if (interfaceName.isInstance (object)) { 634 return (Attribute) object; 635 } else { 636 throw new ClassCastException(); 637 } 638 } 639 640 /** 641 * Verify that the given attribute category object is equal to the category 642 * of the given attribute value object. If so, this method returns doing 643 * nothing. If not, this method throws an exception. 644 * 645 * @param category attribute category to test 646 * @param attribute attribute value to test 647 * @throws NullPointerException if the {@code category} or {@code attribute} 648 * are {@code null} 649 * @throws IllegalArgumentException if the {@code category} is not equal to 650 * the category of the {@code attribute} 651 */ 652 public static void verifyCategoryForValue(Class<?> category, Attribute attribute)653 verifyCategoryForValue(Class<?> category, Attribute attribute) { 654 655 if (!category.equals (attribute.getCategory())) { 656 throw new IllegalArgumentException(); 657 } 658 } 659 } 660