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