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     public Object clone() {
 157         ParameterBlock theClone;
 158 
 159         try {
 160             theClone = (ParameterBlock) super.clone();
 161         } catch (Exception e) {
 162             // We can't be here since we implement Cloneable.
 163             return null;
 164         }
 165 
 166         if (sources != null) {
 167             theClone.setSources((Vector)sources.clone());
 168         }
 169         if (parameters != null) {
 170             theClone.setParameters((Vector)parameters.clone());
 171         }
 172         return (Object) theClone;
 173     }
 174 
 175     /**
 176      * Adds an image to end of the list of sources.  The image is
 177      * stored as an object in order to allow new node types in the
 178      * future.
 179      *
 180      * @param source an image object to be stored in the source list.
 181      * @return a new <code>ParameterBlock</code> containing the specified
 182      *         <code>source</code>.
 183      */
 184     public ParameterBlock addSource(Object source) {
 185         sources.addElement(source);
 186         return this;
 187     }
 188 
 189     /**
 190      * Returns a source as a general Object.  The caller must cast it into
 191      * an appropriate type.
 192      *
 193      * @param index the index of the source to be returned.
 194      * @return an <code>Object</code> that represents the source located
 195      *         at the specified index in the <code>sources</code>
 196      *         <code>Vector</code>.
 197      * @see #setSource(Object, int)
 198      */
 199     public Object getSource(int index) {
 200         return sources.elementAt(index);
 201     }
 202 
 203     /**
 204      * Replaces an entry in the list of source with a new source.
 205      * If the index lies beyond the current source list,
 206      * the list is extended with nulls as needed.
 207      * @param source the specified source image
 208      * @param index the index into the <code>sources</code>
 209      *              <code>Vector</code> at which to
 210      *              insert the specified <code>source</code>
 211      * @return a new <code>ParameterBlock</code> that contains the
 212      *         specified <code>source</code> at the specified
 213      *         <code>index</code>.
 214      * @see #getSource(int)
 215      */
 216     public ParameterBlock setSource(Object source, int index) {
 217         int oldSize = sources.size();
 218         int newSize = index + 1;
 219         if (oldSize < newSize) {
 220             sources.setSize(newSize);
 221         }
 222         sources.setElementAt(source, index);
 223         return this;
 224     }
 225 
 226     /**
 227      * Returns a source as a <code>RenderedImage</code>.  This method is
 228      * a convenience method.
 229      * An exception will be thrown if the source is not a RenderedImage.
 230      *
 231      * @param index the index of the source to be returned
 232      * @return a <code>RenderedImage</code> that represents the source
 233      *         image that is at the specified index in the
 234      *         <code>sources</code> <code>Vector</code>.
 235      */
 236     public RenderedImage getRenderedSource(int index) {
 237         return (RenderedImage) sources.elementAt(index);
 238     }
 239 
 240     /**
 241      * Returns a source as a RenderableImage.  This method is a
 242      * convenience method.
 243      * An exception will be thrown if the sources is not a RenderableImage.
 244      *
 245      * @param index the index of the source to be returned
 246      * @return a <code>RenderableImage</code> that represents the source
 247      *         image that is at the specified index in the
 248      *         <code>sources</code> <code>Vector</code>.
 249      */
 250     public RenderableImage getRenderableSource(int index) {
 251         return (RenderableImage) sources.elementAt(index);
 252     }
 253 
 254     /**
 255      * Returns the number of source images.
 256      * @return the number of source images in the <code>sources</code>
 257      *         <code>Vector</code>.
 258      */
 259     public int getNumSources() {
 260         return sources.size();
 261     }
 262 
 263     /**
 264      * Returns the entire Vector of sources.
 265      * @return the <code>sources</code> <code>Vector</code>.
 266      * @see #setSources(Vector)
 267      */
 268     public Vector<Object> getSources() {
 269         return sources;
 270     }
 271 
 272     /**
 273      * Sets the entire Vector of sources to a given Vector.
 274      * @param sources the <code>Vector</code> of source images
 275      * @see #getSources
 276      */
 277     public void setSources(Vector<Object> sources) {
 278         this.sources = sources;
 279     }
 280 
 281     /** Clears the list of source images. */
 282     public void removeSources() {
 283         sources = new Vector();
 284     }
 285 
 286     /**
 287      * Returns the number of parameters (not including source images).
 288      * @return the number of parameters in the <code>parameters</code>
 289      *         <code>Vector</code>.
 290      */
 291     public int getNumParameters() {
 292         return parameters.size();
 293     }
 294 
 295     /**
 296      * Returns the entire Vector of parameters.
 297      * @return the <code>parameters</code> <code>Vector</code>.
 298      * @see #setParameters(Vector)
 299      */
 300     public Vector<Object> getParameters() {
 301         return parameters;
 302     }
 303 
 304     /**
 305      * Sets the entire Vector of parameters to a given Vector.
 306      * @param parameters the specified <code>Vector</code> of
 307      *        parameters
 308      * @see #getParameters
 309      */
 310     public void setParameters(Vector<Object> parameters) {
 311         this.parameters = parameters;
 312     }
 313 
 314     /** Clears the list of parameters. */
 315     public void removeParameters() {
 316         parameters = new Vector();
 317     }
 318 
 319     /**
 320      * Adds an object to the list of parameters.
 321      * @param obj the <code>Object</code> to add to the
 322      *            <code>parameters</code> <code>Vector</code>
 323      * @return a new <code>ParameterBlock</code> containing
 324      *         the specified parameter.
 325      */
 326     public ParameterBlock add(Object obj) {
 327         parameters.addElement(obj);
 328         return this;
 329     }
 330 
 331     /**
 332      * Adds a Byte to the list of parameters.
 333      * @param b the byte to add to the
 334      *            <code>parameters</code> <code>Vector</code>
 335      * @return a new <code>ParameterBlock</code> containing
 336      *         the specified parameter.
 337      */
 338     public ParameterBlock add(byte b) {
 339         return add(new Byte(b));
 340     }
 341 
 342     /**
 343      * Adds a Character to the list of parameters.
 344      * @param c the char to add to the
 345      *            <code>parameters</code> <code>Vector</code>
 346      * @return a new <code>ParameterBlock</code> containing
 347      *         the specified parameter.
 348      */
 349     public ParameterBlock add(char c) {
 350         return add(new Character(c));
 351     }
 352 
 353     /**
 354      * Adds a Short to the list of parameters.
 355      * @param s the short to add to the
 356      *            <code>parameters</code> <code>Vector</code>
 357      * @return a new <code>ParameterBlock</code> containing
 358      *         the specified parameter.
 359      */
 360     public ParameterBlock add(short s) {
 361         return add(new Short(s));
 362     }
 363 
 364     /**
 365      * Adds a Integer to the list of parameters.
 366      * @param i the int to add to the
 367      *            <code>parameters</code> <code>Vector</code>
 368      * @return a new <code>ParameterBlock</code> containing
 369      *         the specified parameter.
 370      */
 371     public ParameterBlock add(int i) {
 372         return add(new Integer(i));
 373     }
 374 
 375     /**
 376      * Adds a Long to the list of parameters.
 377      * @param l the long to add to the
 378      *            <code>parameters</code> <code>Vector</code>
 379      * @return a new <code>ParameterBlock</code> containing
 380      *         the specified parameter.
 381      */
 382     public ParameterBlock add(long l) {
 383         return add(new Long(l));
 384     }
 385 
 386     /**
 387      * Adds a Float to the list of parameters.
 388      * @param f the float to add to the
 389      *            <code>parameters</code> <code>Vector</code>
 390      * @return a new <code>ParameterBlock</code> containing
 391      *         the specified parameter.
 392      */
 393     public ParameterBlock add(float f) {
 394         return add(new Float(f));
 395     }
 396 
 397     /**
 398      * Adds a Double to the list of parameters.
 399      * @param d the double to add to the
 400      *            <code>parameters</code> <code>Vector</code>
 401      * @return a new <code>ParameterBlock</code> containing
 402      *         the specified parameter.
 403      */
 404     public ParameterBlock add(double d) {
 405         return add(new Double(d));
 406     }
 407 
 408     /**
 409      * Replaces an Object in the list of parameters.
 410      * If the index lies beyond the current source list,
 411      * the list is extended with nulls as needed.
 412      * @param obj the parameter that replaces the
 413      *        parameter at the specified index in the
 414      *        <code>parameters</code> <code>Vector</code>
 415      * @param index the index of the parameter to be
 416      *        replaced with the specified parameter
 417      * @return a new <code>ParameterBlock</code> containing
 418      *        the specified parameter.
 419      */
 420     public ParameterBlock set(Object obj, int index) {
 421         int oldSize = parameters.size();
 422         int newSize = index + 1;
 423         if (oldSize < newSize) {
 424             parameters.setSize(newSize);
 425         }
 426         parameters.setElementAt(obj, index);
 427         return this;
 428     }
 429 
 430     /**
 431      * Replaces an Object in the list of parameters with a Byte.
 432      * If the index lies beyond the current source list,
 433      * the list is extended with nulls as needed.
 434      * @param b the parameter that replaces the
 435      *        parameter at the specified index in the
 436      *        <code>parameters</code> <code>Vector</code>
 437      * @param index the index of the parameter to be
 438      *        replaced with the specified parameter
 439      * @return a new <code>ParameterBlock</code> containing
 440      *        the specified parameter.
 441      */
 442     public ParameterBlock set(byte b, int index) {
 443         return set(new Byte(b), index);
 444     }
 445 
 446     /**
 447      * Replaces an Object in the list of parameters with a Character.
 448      * If the index lies beyond the current source list,
 449      * the list is extended with nulls as needed.
 450      * @param c the parameter that replaces the
 451      *        parameter at the specified index in the
 452      *        <code>parameters</code> <code>Vector</code>
 453      * @param index the index of the parameter to be
 454      *        replaced with the specified parameter
 455      * @return a new <code>ParameterBlock</code> containing
 456      *        the specified parameter.
 457      */
 458     public ParameterBlock set(char c, int index) {
 459         return set(new Character(c), index);
 460     }
 461 
 462     /**
 463      * Replaces an Object in the list of parameters with a Short.
 464      * If the index lies beyond the current source list,
 465      * the list is extended with nulls as needed.
 466      * @param s the parameter that replaces the
 467      *        parameter at the specified index in the
 468      *        <code>parameters</code> <code>Vector</code>
 469      * @param index the index of the parameter to be
 470      *        replaced with the specified parameter
 471      * @return a new <code>ParameterBlock</code> containing
 472      *        the specified parameter.
 473      */
 474     public ParameterBlock set(short s, int index) {
 475         return set(new Short(s), index);
 476     }
 477 
 478     /**
 479      * Replaces an Object in the list of parameters with an Integer.
 480      * If the index lies beyond the current source list,
 481      * the list is extended with nulls as needed.
 482      * @param i the parameter that replaces the
 483      *        parameter at the specified index in the
 484      *        <code>parameters</code> <code>Vector</code>
 485      * @param index the index of the parameter to be
 486      *        replaced with the specified parameter
 487      * @return a new <code>ParameterBlock</code> containing
 488      *        the specified parameter.
 489      */
 490     public ParameterBlock set(int i, int index) {
 491         return set(new Integer(i), index);
 492     }
 493 
 494     /**
 495      * Replaces an Object in the list of parameters with a Long.
 496      * If the index lies beyond the current source list,
 497      * the list is extended with nulls as needed.
 498      * @param l the parameter that replaces the
 499      *        parameter at the specified index in the
 500      *        <code>parameters</code> <code>Vector</code>
 501      * @param index the index of the parameter to be
 502      *        replaced with the specified parameter
 503      * @return a new <code>ParameterBlock</code> containing
 504      *        the specified parameter.
 505      */
 506     public ParameterBlock set(long l, int index) {
 507         return set(new Long(l), index);
 508     }
 509 
 510     /**
 511      * Replaces an Object in the list of parameters with a Float.
 512      * If the index lies beyond the current source list,
 513      * the list is extended with nulls as needed.
 514      * @param f the parameter that replaces the
 515      *        parameter at the specified index in the
 516      *        <code>parameters</code> <code>Vector</code>
 517      * @param index the index of the parameter to be
 518      *        replaced with the specified parameter
 519      * @return a new <code>ParameterBlock</code> containing
 520      *        the specified parameter.
 521      */
 522     public ParameterBlock set(float f, int index) {
 523         return set(new Float(f), index);
 524     }
 525 
 526     /**
 527      * Replaces an Object in the list of parameters with a Double.
 528      * If the index lies beyond the current source list,
 529      * the list is extended with nulls as needed.
 530      * @param d the parameter that replaces the
 531      *        parameter at the specified index in the
 532      *        <code>parameters</code> <code>Vector</code>
 533      * @param index the index of the parameter to be
 534      *        replaced with the specified parameter
 535      * @return a new <code>ParameterBlock</code> containing
 536      *        the specified parameter.
 537      */
 538     public ParameterBlock set(double d, int index) {
 539         return set(new Double(d), index);
 540     }
 541 
 542     /**
 543      * Gets a parameter as an object.
 544      * @param index the index of the parameter to get
 545      * @return an <code>Object</code> representing the
 546      *         the parameter at the specified index
 547      *         into the <code>parameters</code>
 548      *         <code>Vector</code>.
 549      */
 550     public Object getObjectParameter(int index) {
 551         return parameters.elementAt(index);
 552     }
 553 
 554     /**
 555      * A convenience method to return a parameter as a byte.  An
 556      * exception is thrown if the parameter is
 557      * <code>null</code> or not a <code>Byte</code>.
 558      *
 559      * @param index the index of the parameter to be returned.
 560      * @return the parameter at the specified index
 561      *         as a <code>byte</code> value.
 562      * @throws ClassCastException if the parameter at the
 563      *         specified index is not a <code>Byte</code>
 564      * @throws NullPointerException if the parameter at the specified
 565      *         index is <code>null</code>
 566      * @throws ArrayIndexOutOfBoundsException if <code>index</code>
 567      *         is negative or not less than the current size of this
 568      *         <code>ParameterBlock</code> object
 569      */
 570     public byte getByteParameter(int index) {
 571         return ((Byte)parameters.elementAt(index)).byteValue();
 572     }
 573 
 574     /**
 575      * A convenience method to return a parameter as a char.  An
 576      * exception is thrown if the parameter is
 577      * <code>null</code> or not a <code>Character</code>.
 578      *
 579      * @param index the index of the parameter to be returned.
 580      * @return the parameter at the specified index
 581      *         as a <code>char</code> value.
 582      * @throws ClassCastException if the parameter at the
 583      *         specified index is not a <code>Character</code>
 584      * @throws NullPointerException if the parameter at the specified
 585      *         index is <code>null</code>
 586      * @throws ArrayIndexOutOfBoundsException if <code>index</code>
 587      *         is negative or not less than the current size of this
 588      *         <code>ParameterBlock</code> object
 589      */
 590     public char getCharParameter(int index) {
 591         return ((Character)parameters.elementAt(index)).charValue();
 592     }
 593 
 594     /**
 595      * A convenience method to return a parameter as a short.  An
 596      * exception is thrown if the parameter is
 597      * <code>null</code> or not a <code>Short</code>.
 598      *
 599      * @param index the index of the parameter to be returned.
 600      * @return the parameter at the specified index
 601      *         as a <code>short</code> value.
 602      * @throws ClassCastException if the parameter at the
 603      *         specified index is not a <code>Short</code>
 604      * @throws NullPointerException if the parameter at the specified
 605      *         index is <code>null</code>
 606      * @throws ArrayIndexOutOfBoundsException if <code>index</code>
 607      *         is negative or not less than the current size of this
 608      *         <code>ParameterBlock</code> object
 609      */
 610     public short getShortParameter(int index) {
 611         return ((Short)parameters.elementAt(index)).shortValue();
 612     }
 613 
 614     /**
 615      * A convenience method to return a parameter as an int.  An
 616      * exception is thrown if the parameter is
 617      * <code>null</code> or not an <code>Integer</code>.
 618      *
 619      * @param index the index of the parameter to be returned.
 620      * @return the parameter at the specified index
 621      *         as a <code>int</code> value.
 622      * @throws ClassCastException if the parameter at the
 623      *         specified index is not a <code>Integer</code>
 624      * @throws NullPointerException if the parameter at the specified
 625      *         index is <code>null</code>
 626      * @throws ArrayIndexOutOfBoundsException if <code>index</code>
 627      *         is negative or not less than the current size of this
 628      *         <code>ParameterBlock</code> object
 629      */
 630     public int getIntParameter(int index) {
 631         return ((Integer)parameters.elementAt(index)).intValue();
 632     }
 633 
 634     /**
 635      * A convenience method to return a parameter as a long.  An
 636      * exception is thrown if the parameter is
 637      * <code>null</code> or not a <code>Long</code>.
 638      *
 639      * @param index the index of the parameter to be returned.
 640      * @return the parameter at the specified index
 641      *         as a <code>long</code> value.
 642      * @throws ClassCastException if the parameter at the
 643      *         specified index is not a <code>Long</code>
 644      * @throws NullPointerException if the parameter at the specified
 645      *         index is <code>null</code>
 646      * @throws ArrayIndexOutOfBoundsException if <code>index</code>
 647      *         is negative or not less than the current size of this
 648      *         <code>ParameterBlock</code> object
 649      */
 650     public long getLongParameter(int index) {
 651         return ((Long)parameters.elementAt(index)).longValue();
 652     }
 653 
 654     /**
 655      * A convenience method to return a parameter as a float.  An
 656      * exception is thrown if the parameter is
 657      * <code>null</code> or not a <code>Float</code>.
 658      *
 659      * @param index the index of the parameter to be returned.
 660      * @return the parameter at the specified index
 661      *         as a <code>float</code> value.
 662      * @throws ClassCastException if the parameter at the
 663      *         specified index is not a <code>Float</code>
 664      * @throws NullPointerException if the parameter at the specified
 665      *         index is <code>null</code>
 666      * @throws ArrayIndexOutOfBoundsException if <code>index</code>
 667      *         is negative or not less than the current size of this
 668      *         <code>ParameterBlock</code> object
 669      */
 670     public float getFloatParameter(int index) {
 671         return ((Float)parameters.elementAt(index)).floatValue();
 672     }
 673 
 674     /**
 675      * A convenience method to return a parameter as a double.  An
 676      * exception is thrown if the parameter is
 677      * <code>null</code> or not a <code>Double</code>.
 678      *
 679      * @param index the index of the parameter to be returned.
 680      * @return the parameter at the specified index
 681      *         as a <code>double</code> value.
 682      * @throws ClassCastException if the parameter at the
 683      *         specified index is not a <code>Double</code>
 684      * @throws NullPointerException if the parameter at the specified
 685      *         index is <code>null</code>
 686      * @throws ArrayIndexOutOfBoundsException if <code>index</code>
 687      *         is negative or not less than the current size of this
 688      *         <code>ParameterBlock</code> object
 689      */
 690     public double getDoubleParameter(int index) {
 691         return ((Double)parameters.elementAt(index)).doubleValue();
 692     }
 693 
 694     /**
 695      * Returns an array of Class objects describing the types
 696      * of the parameters.
 697      * @return an array of <code>Class</code> objects.
 698      */
 699     public Class [] getParamClasses() {
 700         int numParams = getNumParameters();
 701         Class [] classes = new Class[numParams];
 702         int i;
 703 
 704         for (i = 0; i < numParams; i++) {
 705             Object obj = getObjectParameter(i);
 706             if (obj instanceof Byte) {
 707               classes[i] = byte.class;
 708             } else if (obj instanceof Character) {
 709               classes[i] = char.class;
 710             } else if (obj instanceof Short) {
 711               classes[i] = short.class;
 712             } else if (obj instanceof Integer) {
 713               classes[i] = int.class;
 714             } else if (obj instanceof Long) {
 715               classes[i] = long.class;
 716             } else if (obj instanceof Float) {
 717               classes[i] = float.class;
 718             } else if (obj instanceof Double) {
 719               classes[i] = double.class;
 720             } else {
 721               classes[i] = obj.getClass();
 722             }
 723         }
 724 
 725         return classes;
 726     }
 727 }