1 /* 2 * Copyright (c) 1998, 2014, 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 java.awt.image.renderable; 27 import java.awt.image.RenderedImage; 28 import java.io.Serializable; 29 import java.util.Vector; 30 31 /** 32 * A <code>ParameterBlock</code> encapsulates all the information about sources and 33 * parameters (Objects) required by a RenderableImageOp, or other 34 * classes that process images. 35 * 36 * <p> Although it is possible to place arbitrary objects in the 37 * source Vector, users of this class may impose semantic constraints 38 * such as requiring all sources to be RenderedImages or 39 * RenderableImage. <code>ParameterBlock</code> itself is merely a container and 40 * performs no checking on source or parameter types. 41 * 42 * <p> All parameters in a <code>ParameterBlock</code> are objects; convenience 43 * add and set methods are available that take arguments of base type and 44 * construct the appropriate subclass of Number (such as 45 * Integer or Float). Corresponding get methods perform a 46 * downward cast and have return values of base type; an exception 47 * will be thrown if the stored values do not have the correct type. 48 * There is no way to distinguish between the results of 49 * "short s; add(s)" and "add(new Short(s))". 50 * 51 * <p> Note that the get and set methods operate on references. 52 * Therefore, one must be careful not to share references between 53 * <code>ParameterBlock</code>s when this is inappropriate. For example, to create 54 * a new <code>ParameterBlock</code> that is equal to an old one except for an 55 * added source, one might be tempted to write: 56 * 57 * <pre> 58 * ParameterBlock addSource(ParameterBlock pb, RenderableImage im) { 59 * ParameterBlock pb1 = new ParameterBlock(pb.getSources()); 60 * pb1.addSource(im); 61 * return pb1; 62 * } 63 * </pre> 64 * 65 * <p> This code will have the side effect of altering the original 66 * <code>ParameterBlock</code>, since the getSources operation returned a reference 67 * to its source Vector. Both pb and pb1 share their source Vector, 68 * and a change in either is visible to both. 69 * 70 * <p> A correct way to write the addSource function is to clone 71 * the source Vector: 72 * 73 * <pre> 74 * ParameterBlock addSource (ParameterBlock pb, RenderableImage im) { 75 * ParameterBlock pb1 = new ParameterBlock(pb.getSources().clone()); 76 * pb1.addSource(im); 77 * return pb1; 78 * } 79 * </pre> 80 * 81 * <p> The clone method of <code>ParameterBlock</code> has been defined to 82 * perform a clone of both the source and parameter Vectors for 83 * this reason. A standard, shallow clone is available as 84 * shallowClone. 85 * 86 * <p> The addSource, setSource, add, and set methods are 87 * defined to return 'this' after adding their argument. This allows 88 * use of syntax like: 89 * 90 * <pre> 91 * ParameterBlock pb = new ParameterBlock(); 92 * op = new RenderableImageOp("operation", pb.add(arg1).add(arg2)); 93 * </pre> 94 * */ 95 public class ParameterBlock implements Cloneable, Serializable { 96 private static final long serialVersionUID = -7577115551785240750L; 97 98 /** A Vector of sources, stored as arbitrary Objects. */ 99 protected Vector<Object> sources = new Vector<Object>(); 100 101 /** A Vector of non-source parameters, stored as arbitrary Objects. */ 102 protected Vector<Object> parameters = new Vector<Object>(); 103 104 /** A dummy constructor. */ 105 public ParameterBlock() {} 106 107 /** 108 * Constructs a <code>ParameterBlock</code> with a given Vector 109 * of sources. 110 * @param sources a <code>Vector</code> of source images 111 */ 112 public ParameterBlock(Vector<Object> sources) { 113 setSources(sources); 114 } 115 116 /** 117 * Constructs a <code>ParameterBlock</code> with a given Vector of sources and 118 * Vector of parameters. 119 * @param sources a <code>Vector</code> of source images 120 * @param parameters a <code>Vector</code> of parameters to be used in the 121 * rendering operation 122 */ 123 public ParameterBlock(Vector<Object> sources, 124 Vector<Object> parameters) 125 { 126 setSources(sources); 127 setParameters(parameters); 128 } 129 130 /** 131 * Creates a shallow copy of a <code>ParameterBlock</code>. The source and 132 * parameter Vectors are copied by reference -- additions or 133 * changes will be visible to both versions. 134 * 135 * @return an Object clone of the <code>ParameterBlock</code>. 136 */ 137 public Object shallowClone() { 138 try { 139 return super.clone(); 140 } catch (Exception e) { 141 // We can't be here since we implement Cloneable. 142 return null; 143 } 144 } 145 146 /** 147 * Creates a copy of a <code>ParameterBlock</code>. The source and parameter 148 * Vectors are cloned, but the actual sources and parameters are 149 * copied by reference. This allows modifications to the order 150 * and number of sources and parameters in the clone to be invisible 151 * to the original <code>ParameterBlock</code>. Changes to the shared sources or 152 * parameters themselves will still be visible. 153 * 154 * @return an Object clone of the <code>ParameterBlock</code>. 155 */ 156 @SuppressWarnings("unchecked") // casts from clone 157 public Object clone() { 158 ParameterBlock theClone; 159 160 try { 161 theClone = (ParameterBlock) super.clone(); 162 } catch (Exception e) { 163 // We can't be here since we implement Cloneable. 164 return null; 165 } 166 167 if (sources != null) { 168 theClone.setSources((Vector<Object>)sources.clone()); 169 } 170 if (parameters != null) { 171 theClone.setParameters((Vector<Object>)parameters.clone()); 172 } 173 return (Object) theClone; 174 } 175 176 /** 177 * Adds an image to end of the list of sources. The image is 178 * stored as an object in order to allow new node types in the 179 * future. 180 * 181 * @param source an image object to be stored in the source list. 182 * @return a new <code>ParameterBlock</code> containing the specified 183 * <code>source</code>. 184 */ 185 public ParameterBlock addSource(Object source) { 186 sources.addElement(source); 187 return this; 188 } 189 190 /** 191 * Returns a source as a general Object. The caller must cast it into 192 * an appropriate type. 193 * 194 * @param index the index of the source to be returned. 195 * @return an <code>Object</code> that represents the source located 196 * at the specified index in the <code>sources</code> 197 * <code>Vector</code>. 198 * @see #setSource(Object, int) 199 */ 200 public Object getSource(int index) { 201 return sources.elementAt(index); 202 } 203 204 /** 205 * Replaces an entry in the list of source with a new source. 206 * If the index lies beyond the current source list, 207 * the list is extended with nulls as needed. 208 * @param source the specified source image 209 * @param index the index into the <code>sources</code> 210 * <code>Vector</code> at which to 211 * insert the specified <code>source</code> 212 * @return a new <code>ParameterBlock</code> that contains the 213 * specified <code>source</code> at the specified 214 * <code>index</code>. 215 * @see #getSource(int) 216 */ 217 public ParameterBlock setSource(Object source, int index) { 218 int oldSize = sources.size(); 219 int newSize = index + 1; 220 if (oldSize < newSize) { 221 sources.setSize(newSize); 222 } 223 sources.setElementAt(source, index); 224 return this; 225 } 226 227 /** 228 * Returns a source as a <code>RenderedImage</code>. This method is 229 * a convenience method. 230 * An exception will be thrown if the source is not a RenderedImage. 231 * 232 * @param index the index of the source to be returned 233 * @return a <code>RenderedImage</code> that represents the source 234 * image that is at the specified index in the 235 * <code>sources</code> <code>Vector</code>. 236 */ 237 public RenderedImage getRenderedSource(int index) { 238 return (RenderedImage) sources.elementAt(index); 239 } 240 241 /** 242 * Returns a source as a RenderableImage. This method is a 243 * convenience method. 244 * An exception will be thrown if the sources is not a RenderableImage. 245 * 246 * @param index the index of the source to be returned 247 * @return a <code>RenderableImage</code> that represents the source 248 * image that is at the specified index in the 249 * <code>sources</code> <code>Vector</code>. 250 */ 251 public RenderableImage getRenderableSource(int index) { 252 return (RenderableImage) sources.elementAt(index); 253 } 254 255 /** 256 * Returns the number of source images. 257 * @return the number of source images in the <code>sources</code> 258 * <code>Vector</code>. 259 */ 260 public int getNumSources() { 261 return sources.size(); 262 } 263 264 /** 265 * Returns the entire Vector of sources. 266 * @return the <code>sources</code> <code>Vector</code>. 267 * @see #setSources(Vector) 268 */ 269 public Vector<Object> getSources() { 270 return sources; 271 } 272 273 /** 274 * Sets the entire Vector of sources to a given Vector. 275 * @param sources the <code>Vector</code> of source images 276 * @see #getSources 277 */ 278 public void setSources(Vector<Object> sources) { 279 this.sources = sources; 280 } 281 282 /** Clears the list of source images. */ 283 public void removeSources() { 284 sources = new Vector<>(); 285 } 286 287 /** 288 * Returns the number of parameters (not including source images). 289 * @return the number of parameters in the <code>parameters</code> 290 * <code>Vector</code>. 291 */ 292 public int getNumParameters() { 293 return parameters.size(); 294 } 295 296 /** 297 * Returns the entire Vector of parameters. 298 * @return the <code>parameters</code> <code>Vector</code>. 299 * @see #setParameters(Vector) 300 */ 301 public Vector<Object> getParameters() { 302 return parameters; 303 } 304 305 /** 306 * Sets the entire Vector of parameters to a given Vector. 307 * @param parameters the specified <code>Vector</code> of 308 * parameters 309 * @see #getParameters 310 */ 311 public void setParameters(Vector<Object> parameters) { 312 this.parameters = parameters; 313 } 314 315 /** Clears the list of parameters. */ 316 public void removeParameters() { 317 parameters = new Vector<>(); 318 } 319 320 /** 321 * Adds an object to the list of parameters. 322 * @param obj the <code>Object</code> to add to the 323 * <code>parameters</code> <code>Vector</code> 324 * @return a new <code>ParameterBlock</code> containing 325 * the specified parameter. 326 */ 327 public ParameterBlock add(Object obj) { 328 parameters.addElement(obj); 329 return this; 330 } 331 332 /** 333 * Adds a Byte to the list of parameters. 334 * @param b the byte to add to the 335 * <code>parameters</code> <code>Vector</code> 336 * @return a new <code>ParameterBlock</code> containing 337 * the specified parameter. 338 */ 339 public ParameterBlock add(byte b) { 340 return add(Byte.valueOf(b)); 341 } 342 343 /** 344 * Adds a Character to the list of parameters. 345 * @param c the char to add to the 346 * <code>parameters</code> <code>Vector</code> 347 * @return a new <code>ParameterBlock</code> containing 348 * the specified parameter. 349 */ 350 public ParameterBlock add(char c) { 351 return add(Character.valueOf(c)); 352 } 353 354 /** 355 * Adds a Short to the list of parameters. 356 * @param s the short to add to the 357 * <code>parameters</code> <code>Vector</code> 358 * @return a new <code>ParameterBlock</code> containing 359 * the specified parameter. 360 */ 361 public ParameterBlock add(short s) { 362 return add(Short.valueOf(s)); 363 } 364 365 /** 366 * Adds a Integer to the list of parameters. 367 * @param i the int to add to the 368 * <code>parameters</code> <code>Vector</code> 369 * @return a new <code>ParameterBlock</code> containing 370 * the specified parameter. 371 */ 372 public ParameterBlock add(int i) { 373 return add(new Integer(i)); 374 } 375 376 /** 377 * Adds a Long to the list of parameters. 378 * @param l the long to add to the 379 * <code>parameters</code> <code>Vector</code> 380 * @return a new <code>ParameterBlock</code> containing 381 * the specified parameter. 382 */ 383 public ParameterBlock add(long l) { 384 return add(Long.valueOf(l)); 385 } 386 387 /** 388 * Adds a Float to the list of parameters. 389 * @param f the float to add to the 390 * <code>parameters</code> <code>Vector</code> 391 * @return a new <code>ParameterBlock</code> containing 392 * the specified parameter. 393 */ 394 public ParameterBlock add(float f) { 395 return add(new Float(f)); 396 } 397 398 /** 399 * Adds a Double to the list of parameters. 400 * @param d the double to add to the 401 * <code>parameters</code> <code>Vector</code> 402 * @return a new <code>ParameterBlock</code> containing 403 * the specified parameter. 404 */ 405 public ParameterBlock add(double d) { 406 return add(new Double(d)); 407 } 408 409 /** 410 * Replaces an Object in the list of parameters. 411 * If the index lies beyond the current source list, 412 * the list is extended with nulls as needed. 413 * @param obj the parameter that replaces the 414 * parameter at the specified index in the 415 * <code>parameters</code> <code>Vector</code> 416 * @param index the index of the parameter to be 417 * replaced with the specified parameter 418 * @return a new <code>ParameterBlock</code> containing 419 * the specified parameter. 420 */ 421 public ParameterBlock set(Object obj, int index) { 422 int oldSize = parameters.size(); 423 int newSize = index + 1; 424 if (oldSize < newSize) { 425 parameters.setSize(newSize); 426 } 427 parameters.setElementAt(obj, index); 428 return this; 429 } 430 431 /** 432 * Replaces an Object in the list of parameters with a Byte. 433 * If the index lies beyond the current source list, 434 * the list is extended with nulls as needed. 435 * @param b the parameter that replaces the 436 * parameter at the specified index in the 437 * <code>parameters</code> <code>Vector</code> 438 * @param index the index of the parameter to be 439 * replaced with the specified parameter 440 * @return a new <code>ParameterBlock</code> containing 441 * the specified parameter. 442 */ 443 public ParameterBlock set(byte b, int index) { 444 return set(Byte.valueOf(b), index); 445 } 446 447 /** 448 * Replaces an Object in the list of parameters with a Character. 449 * If the index lies beyond the current source list, 450 * the list is extended with nulls as needed. 451 * @param c the parameter that replaces the 452 * parameter at the specified index in the 453 * <code>parameters</code> <code>Vector</code> 454 * @param index the index of the parameter to be 455 * replaced with the specified parameter 456 * @return a new <code>ParameterBlock</code> containing 457 * the specified parameter. 458 */ 459 public ParameterBlock set(char c, int index) { 460 return set(Character.valueOf(c), index); 461 } 462 463 /** 464 * Replaces an Object in the list of parameters with a Short. 465 * If the index lies beyond the current source list, 466 * the list is extended with nulls as needed. 467 * @param s the parameter that replaces the 468 * parameter at the specified index in the 469 * <code>parameters</code> <code>Vector</code> 470 * @param index the index of the parameter to be 471 * replaced with the specified parameter 472 * @return a new <code>ParameterBlock</code> containing 473 * the specified parameter. 474 */ 475 public ParameterBlock set(short s, int index) { 476 return set(Short.valueOf(s), index); 477 } 478 479 /** 480 * Replaces an Object in the list of parameters with an Integer. 481 * If the index lies beyond the current source list, 482 * the list is extended with nulls as needed. 483 * @param i the parameter that replaces the 484 * parameter at the specified index in the 485 * <code>parameters</code> <code>Vector</code> 486 * @param index the index of the parameter to be 487 * replaced with the specified parameter 488 * @return a new <code>ParameterBlock</code> containing 489 * the specified parameter. 490 */ 491 public ParameterBlock set(int i, int index) { 492 return set(new Integer(i), index); 493 } 494 495 /** 496 * Replaces an Object in the list of parameters with a Long. 497 * If the index lies beyond the current source list, 498 * the list is extended with nulls as needed. 499 * @param l the parameter that replaces the 500 * parameter at the specified index in the 501 * <code>parameters</code> <code>Vector</code> 502 * @param index the index of the parameter to be 503 * replaced with the specified parameter 504 * @return a new <code>ParameterBlock</code> containing 505 * the specified parameter. 506 */ 507 public ParameterBlock set(long l, int index) { 508 return set(Long.valueOf(l), index); 509 } 510 511 /** 512 * Replaces an Object in the list of parameters with a Float. 513 * If the index lies beyond the current source list, 514 * the list is extended with nulls as needed. 515 * @param f the parameter that replaces the 516 * parameter at the specified index in the 517 * <code>parameters</code> <code>Vector</code> 518 * @param index the index of the parameter to be 519 * replaced with the specified parameter 520 * @return a new <code>ParameterBlock</code> containing 521 * the specified parameter. 522 */ 523 public ParameterBlock set(float f, int index) { 524 return set(new Float(f), index); 525 } 526 527 /** 528 * Replaces an Object in the list of parameters with a Double. 529 * If the index lies beyond the current source list, 530 * the list is extended with nulls as needed. 531 * @param d the parameter that replaces the 532 * parameter at the specified index in the 533 * <code>parameters</code> <code>Vector</code> 534 * @param index the index of the parameter to be 535 * replaced with the specified parameter 536 * @return a new <code>ParameterBlock</code> containing 537 * the specified parameter. 538 */ 539 public ParameterBlock set(double d, int index) { 540 return set(new Double(d), index); 541 } 542 543 /** 544 * Gets a parameter as an object. 545 * @param index the index of the parameter to get 546 * @return an <code>Object</code> representing the 547 * the parameter at the specified index 548 * into the <code>parameters</code> 549 * <code>Vector</code>. 550 */ 551 public Object getObjectParameter(int index) { 552 return parameters.elementAt(index); 553 } 554 555 /** 556 * A convenience method to return a parameter as a byte. An 557 * exception is thrown if the parameter is 558 * <code>null</code> or not a <code>Byte</code>. 559 * 560 * @param index the index of the parameter to be returned. 561 * @return the parameter at the specified index 562 * as a <code>byte</code> value. 563 * @throws ClassCastException if the parameter at the 564 * specified index is not a <code>Byte</code> 565 * @throws NullPointerException if the parameter at the specified 566 * index is <code>null</code> 567 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 568 * is negative or not less than the current size of this 569 * <code>ParameterBlock</code> object 570 */ 571 public byte getByteParameter(int index) { 572 return ((Byte)parameters.elementAt(index)).byteValue(); 573 } 574 575 /** 576 * A convenience method to return a parameter as a char. An 577 * exception is thrown if the parameter is 578 * <code>null</code> or not a <code>Character</code>. 579 * 580 * @param index the index of the parameter to be returned. 581 * @return the parameter at the specified index 582 * as a <code>char</code> value. 583 * @throws ClassCastException if the parameter at the 584 * specified index is not a <code>Character</code> 585 * @throws NullPointerException if the parameter at the specified 586 * index is <code>null</code> 587 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 588 * is negative or not less than the current size of this 589 * <code>ParameterBlock</code> object 590 */ 591 public char getCharParameter(int index) { 592 return ((Character)parameters.elementAt(index)).charValue(); 593 } 594 595 /** 596 * A convenience method to return a parameter as a short. An 597 * exception is thrown if the parameter is 598 * <code>null</code> or not a <code>Short</code>. 599 * 600 * @param index the index of the parameter to be returned. 601 * @return the parameter at the specified index 602 * as a <code>short</code> value. 603 * @throws ClassCastException if the parameter at the 604 * specified index is not a <code>Short</code> 605 * @throws NullPointerException if the parameter at the specified 606 * index is <code>null</code> 607 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 608 * is negative or not less than the current size of this 609 * <code>ParameterBlock</code> object 610 */ 611 public short getShortParameter(int index) { 612 return ((Short)parameters.elementAt(index)).shortValue(); 613 } 614 615 /** 616 * A convenience method to return a parameter as an int. An 617 * exception is thrown if the parameter is 618 * <code>null</code> or not an <code>Integer</code>. 619 * 620 * @param index the index of the parameter to be returned. 621 * @return the parameter at the specified index 622 * as a <code>int</code> value. 623 * @throws ClassCastException if the parameter at the 624 * specified index is not a <code>Integer</code> 625 * @throws NullPointerException if the parameter at the specified 626 * index is <code>null</code> 627 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 628 * is negative or not less than the current size of this 629 * <code>ParameterBlock</code> object 630 */ 631 public int getIntParameter(int index) { 632 return ((Integer)parameters.elementAt(index)).intValue(); 633 } 634 635 /** 636 * A convenience method to return a parameter as a long. An 637 * exception is thrown if the parameter is 638 * <code>null</code> or not a <code>Long</code>. 639 * 640 * @param index the index of the parameter to be returned. 641 * @return the parameter at the specified index 642 * as a <code>long</code> value. 643 * @throws ClassCastException if the parameter at the 644 * specified index is not a <code>Long</code> 645 * @throws NullPointerException if the parameter at the specified 646 * index is <code>null</code> 647 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 648 * is negative or not less than the current size of this 649 * <code>ParameterBlock</code> object 650 */ 651 public long getLongParameter(int index) { 652 return ((Long)parameters.elementAt(index)).longValue(); 653 } 654 655 /** 656 * A convenience method to return a parameter as a float. An 657 * exception is thrown if the parameter is 658 * <code>null</code> or not a <code>Float</code>. 659 * 660 * @param index the index of the parameter to be returned. 661 * @return the parameter at the specified index 662 * as a <code>float</code> value. 663 * @throws ClassCastException if the parameter at the 664 * specified index is not a <code>Float</code> 665 * @throws NullPointerException if the parameter at the specified 666 * index is <code>null</code> 667 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 668 * is negative or not less than the current size of this 669 * <code>ParameterBlock</code> object 670 */ 671 public float getFloatParameter(int index) { 672 return ((Float)parameters.elementAt(index)).floatValue(); 673 } 674 675 /** 676 * A convenience method to return a parameter as a double. An 677 * exception is thrown if the parameter is 678 * <code>null</code> or not a <code>Double</code>. 679 * 680 * @param index the index of the parameter to be returned. 681 * @return the parameter at the specified index 682 * as a <code>double</code> value. 683 * @throws ClassCastException if the parameter at the 684 * specified index is not a <code>Double</code> 685 * @throws NullPointerException if the parameter at the specified 686 * index is <code>null</code> 687 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 688 * is negative or not less than the current size of this 689 * <code>ParameterBlock</code> object 690 */ 691 public double getDoubleParameter(int index) { 692 return ((Double)parameters.elementAt(index)).doubleValue(); 693 } 694 695 /** 696 * Returns an array of Class objects describing the types 697 * of the parameters. 698 * @return an array of <code>Class</code> objects. 699 */ 700 public Class<?>[] getParamClasses() { 701 int numParams = getNumParameters(); 702 Class<?>[] classes = new Class<?>[numParams]; 703 int i; 704 705 for (i = 0; i < numParams; i++) { 706 Object obj = getObjectParameter(i); 707 if (obj instanceof Byte) { 708 classes[i] = byte.class; 709 } else if (obj instanceof Character) { 710 classes[i] = char.class; 711 } else if (obj instanceof Short) { 712 classes[i] = short.class; 713 } else if (obj instanceof Integer) { 714 classes[i] = int.class; 715 } else if (obj instanceof Long) { 716 classes[i] = long.class; 717 } else if (obj instanceof Float) { 718 classes[i] = float.class; 719 } else if (obj instanceof Double) { 720 classes[i] = double.class; 721 } else { 722 classes[i] = obj.getClass(); 723 } 724 } 725 726 return classes; 727 } 728 }