1 /*
2  * $RCSfile: NegotiableCapability.java,v $
3  *
4  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5  *
6  * Use is subject to license terms.
7  *
8  * $Revision: 1.1 $
9  * $Date: 2005/02/11 04:57:51 $
10  * $State: Exp $
11  */package com.lightcrafts.mediax.jai.remote;
12 
13 import java.io.Serializable;
14 import java.util.ArrayList;
15 import java.util.Enumeration;
16 import java.util.List;
17 import java.util.Hashtable;
18 import java.util.Vector;
19 
20 import com.lightcrafts.mediax.jai.ParameterList;
21 import com.lightcrafts.mediax.jai.ParameterListImpl;
22 import com.lightcrafts.mediax.jai.ParameterListDescriptor;
23 import com.lightcrafts.mediax.jai.ParameterListDescriptorImpl;
24 import com.lightcrafts.mediax.jai.util.CaselessStringKey;
25 
26 /**
27  * A <code>NegotiableCapability</code> represents the capabilities of an
28  * object. These capabilities can be used to negotiate with the capabilities
29  * of a similar object. Each <code>NegotiableCapability</code> is
30  * characterized by the category it belongs to, as returned by the
31  * <code>getCategory()</code> method, by the actual name of the capability
32  * it represents, as returned by the <code>getCapabilityName()</code> method
33  * and by a list of parameter name-value pairs that define the
34  * <code>NegotiableCapability</code>. Every <code>NegotiableCapability</code>
35  * object also holds references to a representation of the objects that
36  * generated it. These can be accessed via the <code>getGenerators()</code>
37  * method. The creator or generator of a <code>NegotiableCapability</code>
38  * can supply any representation of itself while constructing the
39  * <code>NegotiableCapability</code>. No interpretation is forced by this
40  * class, that is left upto the generating class and to the class that
41  * utilizes the <code>NegotiableCapability</code> to get the negotiated
42  * results. The negotiation is performed by the
43  * <code>negotiate()</code> method. Since this method returns a
44  * <code>NegotiableCapability</code>, this method can be used repeatedly to
45  * perform multiple negotiations. If the negotiation fails, null will be
46  * returned from the <code>negotiate()</code> method. Every successful
47  * negotiation will add the generator of the <code>NegotiableCapability</code>
48  * negotiated with, to the set of generators of the resultant
49  * <code>NegotiableCapability</code>. The generators are intended to help
50  * the user of <code>NegotiableCapability</code> identify the object that
51  * created the <code>NegotiableCapability</code> and therefore the object
52  * that can be relied on to be able to handle the parameters agreed on during
53  * negotiation. For example, if the negotiation is to be performed to choose
54  * a compatible <code>TileEncoder</code>, <code>TileDecoder</code> pair
55  * for data compression/decompression, the category would be "tileCodec",
56  * the capabilityName would be a specific tile encoding format, say "jpeg"
57  * and the generator for the <code>NegotiableCapability</code> could be the
58  * <code>TileDecoderFactory</code>/<code>TileEncoderFactory</code> object
59  * that generated that <code>NegotiableCapability</code>. After a
60  * successful negotiation, the <code>NegotiableCapability</code> that is
61  * the result of the negotiation will contain a
62  * <code>TileEncoderFactory</code> and a <code>TileDecoderFactory</code>
63  * object as the generators for that <code>NegotiableCapability</code>.
64  * These two objects can then be retrieved using the
65  * <code>getGenerators</code> method and used to do the encoding and
66  * decoding and can be relied to be compatible, since the negotiation
67  * was successful between their respective
68  * <code>NegotiableCapability</code> objects.
69  *
70  * <p> The number, name, Class type and default values for the parameters in
71  * this class is specified by the <code>ParameterListDescriptor</code>
72  * returned from <code>getParameterListDescriptor</code> method. Each
73  * parameter value in this class must be a class that implements the
74  * <code>Negotiable</code> interface. It is for this reason that all of
75  * the <code>ParameterList</code> set methods that take primitive data
76  * types as arguments and all the <code>ParameterList</code> get methods
77  * that return primitive data types are overridden in this class
78  * to throw an IllegalArgumentException, as this class only accepts
79  * <code>Negotiable</code>'s as parameter values in order to facilitate
80  * negotiation on parameters. It may be noted that the implementation of
81  * the version of <code>ParameterList.setParameter</code> that takes
82  * an <code>Object</code> as the parameter value, in this class
83  * throws an <code>IllegalArgumentException</code> if the supplied
84  * <code>Object</code> to be set does not implement the
85  * <code>Negotiable</code> interface. If no <code>Negotiable</code> value is
86  * available as the value for a particular parameter, <code>null</code>
87  * should be set as the value. A null value returned from the
88  * <code>getNegotiatedValue(String)</code> method is however valid, since
89  * the single value result of the negotiation can be null.
90  * Similarly the <code>Object</code> returned from the
91  * <code>ParameterList.getObjectParameter</code> implementation in this class
92  * is always a class that implements the <code>Negotiable</code> interface,
93  * and not a wrapper class of a primitive data type, as documented for this
94  * method in <code>ParameterList</code>. The
95  * <code>getParamValueRange(String parameterName)</code> and the
96  * <code>getEnumeratedParameterValues(String parameterName)</code> methods
97  * of the <code>ParameterListDescriptor</code> returned from
98  * <code>getParameterListDescriptor</code> method of this class should be
99  * implemented to return null, since these methods are not meaningful when
100  * the parameter values are <code>Negotiable</code>.
101  *
102  * <p>In order for the negotiation to be successful, the category and the
103  * capabilityName of the two <code>NegotiableCapability</code> objects must be
104  * the same. In addition, negotiation on each of the parameters must be
105  * successful. Since each parameter is represented as a
106  * <code>Negotiable</code>, negotiation on it can be performed using the
107  * <code>Negotiable.negotiate(Negotiable negotiable)</code> method. The
108  * <code>NegotiableCapability</code> returned from the
109  * <code>negotiate(NegotiableCapability capability)</code> method
110  * contains the same category and capabilityName as that of the
111  * <code>NegotiableCapability</code> objects being negotiated as well as
112  * including the negotiated values for each parameter. If the negotiation fails
113  * for any one parameter, the negotiation for the
114  * <code>NegotiableCapability</code>s as a whole is said to fail (unless
115  * preference <code>NegotiableCapability</code> objects are involved in
116  * the negotiation, as described below) and a null is returned.
117  *
118  * <p> In order to get a single negotiated value from the set of valid
119  * values represented as the <code>Negotiable</code> value for a parameter,
120  * the <code>getNegotiatedValue(String parameterName)</code> method can be
121  * called. If the negotiation was successful, an <code>Object</code> which
122  * is the negotiated result will be returned, otherwise a
123  * <code>null</code> (signifying that the negotiation failed) will be
124  * returned.
125  *
126  * <p> <code>NegotiableCapability</code> objects can be classified as being
127  * either preferences or non-preferences. A non-preference describes the
128  * capabilities of an object completely by specifying <code>Negotiable</code>
129  * values for each and every parameter defined in the
130  * <code>ParameterListDescriptor</code> returned from
131  * <code>getParameterListDescriptor</code> method. A non-preference is allowed
132  * to not specify the value of a particular parameter, if a default value
133  * for that parameter exists (i.e. the default value is not
134  * <code>null</code>). When a non-preference is created, all parameter
135  * values are initialized to their default values, and therefore if any
136  * parameter value is left unset at the time of the negotiation, the
137  * default value that was set at time of initialization will be used for
138  * the negotiation. If the default value happened to be <code>null</code>,
139  * the negotiation in this case would fail. Note that all references to
140  * values in this paragraph, whether default or not, refered to the
141  * objects implementing the <code>Negotiable</code> interface that are
142  * the values set for a particular parameter name.
143  *
144  * A preference on the other hand specifies preferences for the selection of
145  * a prefered set of (maybe even a single) parameter value from the set of
146  * valid ones at negotiation time.
147  * A preference is allowed to specify <code>Negotiable</code> parameter
148  * values for a subset of parameters, if it so wishes. For those parameters
149  * for whom the preference does not specify values, the preference is
150  * indicating a don't-care attitude, and the result of the negotiation for
151  * such a parameter will be the <code>Negotiable</code> value from the
152  * non-preference object the preference is negotiating with. Note that the
153  * default value is not substituted for a parameter whose value has not been
154  * specified in a preference. A <code>NegotiableCapability</code> which is
155  * a preference should return true from the <code>isPreference</code> method,
156  * a non-preference object that defines values for all the parameters (or
157  * relies on defaults) should return false from this method. As a rule, the
158  * result of negotiation between one non-preference and another is a
159  * non-preference, between a preference and a non-preference is a
160  * non-preference and that between two preferences is a preference, if
161  * the negotiation is successful. It may be noted that preferences are
162  * not expected to specify their generators, since in general, preferences
163  * don't come from objects that can support them. However if generators are
164  * specified within a preference, they will be added to the set of generators
165  * of the resultant <code>NegotiableCapability</code> in the event of a
166  * successful negotiation.
167  *
168  * <p> Negotiation between a preference and a non-preference
169  * <code>NegotiableCapability</code> results in a non-preference
170  * <code>NegotiableCapability</code>. For each parameter, if a value is
171  * specified (i.e the value is not <code>null</code>)
172  * in both the preference and the non-preference, then if these values
173  * have a common subset, the negotiation will succeed on this parameter,
174  * if there is no commonality, then the negotiation will fail on this
175  * parameter and thus also fail as a whole. If the preference doesn't
176  * specify a value for a parameter (i.e the value is <code>null</code>),
177  * then the value specified by the non-preference for that same parameter
178  * is chosen as a result of the successful negotiation on that parameter.
179  *
180  * <p> Negotiation between two preference <code>NegotiableCapability</code>
181  * objects results in a preference <code>NegotiableCapability</code>. For
182  * each parameter, if a value is specified (i.e the value is not
183  * <code>null</code>) in both the preference objects, the negotiation on
184  * that parameter will have a value which is the portion that is common
185  * to both. If there is no commonality, negotiation will fail on this
186  * parameter (<code>null</code> will be returned) and thus also fail as
187  * a whole. If the value for a particular parameter is specified in one
188  * preference and not in the other, the negotiated value will be the one
189  * specified. If for a particular parameter, no value is specified in
190  * either preference, the negotiated value for that parameter will be
191  * <code>null</code>, and the negotiation as a whole on the
192  * <code>NegotiableCapability</code> will not fail.
193  *
194  * <p> When a preference <code>NegotiableCapability</code> is constructed,
195  * the values of all the parameters defined in the
196  * <code>ParameterListDescriptor</code> returned from
197  * <code>getParameterListDescriptor</code> method, are initialized to
198  * <code>null</code>. <code>null</code> within this class represents a
199  * value that has not been specified. Such values are only allowed on
200  * a preference <code>NegotiableCapability</code>. On the other hand when
201  * a non-preference <code>NegotiableCapability</code> is
202  * constructed, all the values are initialized to their default values.
203  *
204  * <p>All names are treated in a case-retentive and case-insensitive manner.
205  *
206  * @since JAI 1.1
207  */
208 public class NegotiableCapability extends ParameterListImpl implements Serializable {
209 
210     private String category;
211     private String capabilityName;
212     private List generators;
213     private boolean isPreference = false;
214 
215     /**
216      * Creates a <code>NegotiableCapability</code> with the specified
217      * <code>category</code> and <code>capabilityName</code>.
218      *
219      * @param category        The category this capability belongs to.
220      * @param capabilityName  The name of this capability.
221      * @param generators      A <code>List</code> containing representations
222      *                        of the objects that generated this
223      *                        <code>NegotiableCapability</code> or null, if
224      *                        there are none.
225      * @param descriptor      The descriptor that describes the parameters for
226      *                        this class.
227      * @param isPreference    Boolean specifying whether this class represents
228      *                        a preference or a non-preference.
229      *
230      * @throws IllegalArgumentException if category is null.
231      * @throws IllegalArgumentException if capabilityName is null.
232      * @throws IllegalArgumentException if descriptor is null.
233      * @throws IllegalArgumentException if any of the default values returned
234      * from the supplied descriptor's getParamDefaults() method is
235      * ParameterListDescriptor.NO_PARAMETER_DEFAULT. null should be used to
236      * represent the absence of a default.
237      * @throws IllegalArgumentException if any of the <code>Class</code>
238      * types returned from the supplied descriptor's getParamClasses() method
239      * does not implement <code>Negotiable</code>.
240      */
NegotiableCapability(String category, String capabilityName, List generators, ParameterListDescriptor descriptor, boolean isPreference)241     public NegotiableCapability(String category,
242 				String capabilityName,
243 				List generators,
244 				ParameterListDescriptor descriptor,
245 				boolean isPreference) {
246 	super(descriptor);
247 
248 	if (category == null) {
249 	    throw new IllegalArgumentException(
250 				JaiI18N.getString("NegotiableCapability0"));
251 	}
252 
253 	if (capabilityName == null) {
254 	    throw new IllegalArgumentException(
255 				JaiI18N.getString("NegotiableCapability1"));
256 	}
257 
258 	ParameterListDescriptor desc = getParameterListDescriptor();
259 	int numParams = desc.getNumParameters();
260 	String names[] = desc.getParamNames();
261 	Class classes[] = desc.getParamClasses();
262 	Object defaults[] = desc.getParamDefaults();
263 
264 	for (int i=0; i<numParams; i++) {
265 
266 	    // Check that all paramClasses implement Negotiable.
267 	    if (Negotiable.class.isAssignableFrom(classes[i]) == false) {
268 		throw new IllegalArgumentException(
269 				   JaiI18N.getString("NegotiableCapability4"));
270 	    }
271 
272 	    if (defaults[i] == ParameterListDescriptor.NO_PARAMETER_DEFAULT) {
273 		throw new IllegalArgumentException(
274 				JaiI18N.getString("NegotiableCapability5"));
275 	    }
276 	}
277 
278 	this.category = category;
279 	this.capabilityName = capabilityName;
280 	this.generators = generators;
281 	this.isPreference = isPreference;
282     }
283 
284     /**
285      * Returns the category of this <code>NegotiableCapability</code>.
286      */
getCategory()287     public String getCategory() {
288 	return category;
289     }
290 
291     /**
292      * Returns the name of this <code>NegotiableCapability</code>.
293      */
getCapabilityName()294     public String getCapabilityName() {
295 	return capabilityName;
296     }
297 
298     /**
299      * Returns the <code>List</code> containing representations of the
300      * objects that generated this <code>NegotiableCapability</code>. This
301      * method will return null, if there are no generators for this
302      * <code>NegotiableCapability</code>.
303      */
getGenerators()304     public List getGenerators() {
305 	return generators;
306     }
307 
308     /**
309      * Set the specified <code>List</code> as the generators for this
310      * <code>NegotiableCapability</code>. A generator is a representation
311      * of the object that generated this <code>NegotiableCapability</code>.
312      *
313      * @param generators The <code>List</code> of generators.
314      */
setGenerators(List generators)315     public void setGenerators(List generators) {
316 	this.generators = generators;
317     }
318 
319     /**
320      * Returns true if this <code>NegotiableCapability</code> is a
321      * preference, false otherwise.
322      */
isPreference()323     public boolean isPreference() {
324 	return isPreference;
325     }
326 
327     /**
328      * Returns a single negotiated value from the <code>Negotiable</code> that
329      * represents the set of valid values for the given parameter. This
330      * method uses the <code>Negotiable.getNegotiatedValue</code> to get
331      * the negotiated value for the <code>Negotiable</code> value of the
332      * parameter specified by <code>parameterName</code>. If this
333      * <code>NegotiableCapability</code> is a non-preference, then a valid
334      * <code>Negotiable</code> must be present as the value of the specified
335      * parameter, and a single value from that <code>Negotiable</code> will
336      * be returned. If this <code>NegotiableCapability</code> is a preference
337      * the specified parameter may have a <code>null</code> as its value.
338      * In this case, this <code>null</code> will be returned as the
339      * negotiated value.
340      *
341      * @param parameterName The name of parameter to return the negotiated
342      *                      value for.
343      * @throws IllegalArgumentException if the parameterName is not one of
344      * those described by the associated <code>ParameterListDescriptor</code>.
345      */
getNegotiatedValue(String parameterName)346     public Object getNegotiatedValue(String parameterName) {
347 	Negotiable value = (Negotiable)getObjectParameter(parameterName);
348 	if (value == null)
349 	    return null;
350 	return value.getNegotiatedValue();
351     }
352 
353     /**
354      * Performs negotiation between this <code>NegotiableCapability</code>
355      * and the given <code>NegotiableCapability</code>. Returns the common
356      * subset supported by this <code>NegotiableCapability</code> and the given
357      * <code>NegotiableCapability</code> if the negotiation is successful,
358      * null otherwise.
359      *
360      * <p>In order for the negotiation to be successful, the category and the
361      * capabilityName of the supplied <code>NegotiableCapability</code> object
362      * must be the same as of this class. In addition, negotiation on each of
363      * the parameters must be successful. Since each parameter is represented
364      * as a <code>Negotiable</code>, negotiation on it can be performed using
365      * the <code>Negotiable.negotiate()</code> method. The
366      * <code>NegotiableCapability</code> returned contains the same category,
367      * capabilityName as that of this class and also includes the negotiated
368      * values for each parameter. If the negotiation fails for any one
369      * parameter, the negotiation for the <code>NegotiableCapability</code>s
370      * as a whole is said to fail and a null is returned. The result of
371      * negotiation between one non-preference and another is a non-preference,
372      * between a preference and a non-preference is a non-preference and
373      * that between two preferences is a preference, if the negotiation is
374      * successful.
375      *
376      * If this <code>NegotiableCapability</code> is a non-preference, i.e
377      * the <code>isPreference()</code> method returns false, and the
378      * supplied <code>NegotiableCapability</code> argument is also a
379      * non-preference, then the negotiation will fail if the number and
380      * <code>Class</code> of parameters in both the
381      * <code>NegotiableCapability</code> objects is not the same.
382      * If either one of the <code>NegotiableCapability</code> objects is
383      * a preference and the other is a non-preference, the number of
384      * parameters are not required to match. For those parameters whose names
385      * are the same in both the <code>NegotiableCapability</code> objects,
386      * the <code>Class</code> types have to match, otherwise the negotiation
387      * will fail. Those parameters that exist in the non-preference
388      * <code>NegotiableCapability</code> object but not in the preference
389      * <code>NegotiableCapability</code> object do not take part in the
390      * negotiation, but are directly set on the resultant
391      * <code>NegotiableCapability</code> object if the negotiation
392      * is successful on the common parameters. Those parameters that
393      * exist in the preference <code>NegotiableCapability</code> object but
394      * not in the non-preference <code>NegotiableCapability</code> object
395      * are ignored, do not take part in the negotiation and are not
396      * reflected in the resultant <code>NegotiableCapability</code> in the
397      * event of a successful negotiation. If both the
398      * <code>NegotiableCapability</code> objects are preferences, then
399      * only the common parameters take part in the negotiation and the
400      * ones that aren't present in both the <code>NegotiableCapability</code>s
401      * are directly set on the resultant <code>NegotiableCapability</code>
402      * object if the negotiation is successful on the common parameters.
403      * For the common parameters, the <code>Class</code> types have to match,
404      * otherwise the negotiation will fail. The check for the compatibility
405      * of the <code>ParameterListDescriptor</code> of the supplied
406      * <code>NegotiableCapability</code> with the current
407      * <code>NegotiableCapability</code>'s <code>ParameterListDescriptor</code>
408      * is done using the <code>areParameterListDescriptorsCompatible()</code>
409      * method.
410 
411      * It may be noted that the <code>ParameterListDescriptor</code> of
412      * the <code>NegotiableCapability</code> returned as a result of a
413      * successful negotiation will implement the getParamDefaults() and
414      * the getParamValueRange() methods in terms of the values returned
415      * from the same methods on the <code>ParameterListDescriptor</code>
416      * associated with this class, if the negotiation took place between
417      * two preferences, or from the same methods on the
418      * <code>ParameterListDescriptor</code> associated with the
419      * non-preference otherwise.
420      *
421      * <p> If the supplied <code>NegotiableCapability</code> is null, then
422      * the negotiation will fail and null will be returned.
423      *
424      * @param capability The <code>NegotiableCapability</code> to negotiate
425      *                   with.
426      * @returns the <code>NegotiableCapability</code> that is the result of a
427      * successful negotiation, null if the negotiation failed.
428      */
negotiate(NegotiableCapability capability)429     public NegotiableCapability negotiate(NegotiableCapability capability) {
430 
431 	if (capability == null) {
432 	    return null;
433 	}
434 
435 	if (capability.getCategory().equalsIgnoreCase(category) == false ||
436 	    capability.getCapabilityName().equalsIgnoreCase(capabilityName)
437 	    == false) {
438 	    // Negotiation failed
439 	    return null;
440 	}
441 
442 	// If the PLD's are not compatible for negotiation, fail the
443 	// negotiation
444 	if (areParameterListDescriptorsCompatible(capability) == false) {
445 	    return null;
446 	}
447 
448 	int negStatus;
449 	if (capability.isPreference() == true) {
450 	    if (isPreference == true) {
451 		negStatus = 0;
452 	    } else {
453 		negStatus = 1;
454 	    }
455 	} else {
456 	    if (isPreference == true) {
457 		negStatus = 2;
458 	    } else {
459 		negStatus = 3;
460 	    }
461 	}
462 
463 	ParameterListDescriptor pld = getParameterListDescriptor();
464 	ParameterListDescriptor otherPld =
465 	    capability.getParameterListDescriptor();
466 	String thisNames[] = pld.getParamNames();
467         if (thisNames == null)
468             thisNames = new String[0];
469 	String otherNames[] = otherPld.getParamNames();
470         if (otherNames == null)
471             otherNames = new String[0];
472 	Hashtable thisHash = hashNames(thisNames);
473 	Hashtable otherHash = hashNames(otherNames);
474 
475 	Class thisClasses[] = pld.getParamClasses();
476 	Class otherClasses[] = otherPld.getParamClasses();
477 	Object thisDefaults[] = pld.getParamDefaults();
478 	Object otherDefaults[] = otherPld.getParamDefaults();
479 
480 	NegotiableCapability result = null;
481 	String currParam;
482 	Negotiable thisValue, otherValue, resultValue;
483 	ArrayList resultGenerators = new ArrayList();
484 	if (generators != null)
485 	    resultGenerators.addAll(generators);
486 	if (capability.getGenerators() != null)
487 	    resultGenerators.addAll(capability.getGenerators());
488 
489 	switch (negStatus) {
490 
491 	case 0:
492 
493 	    Vector commonNames = commonElements(thisHash, otherHash);
494 	    Hashtable commonHash = hashNames(commonNames);
495 	    Vector thisExtras = removeAll(thisHash, commonHash);
496 	    Vector otherExtras = removeAll(otherHash, commonHash);
497 
498 	    int thisExtraLength = thisExtras.size();
499 	    int otherExtraLength = otherExtras.size();
500 
501 	    // Create a new PLD which is the amalgamation of the two
502 	    // NC's PLD's
503 	    Vector resultParams = new Vector(commonNames);
504 	    resultParams.addAll(thisExtras);
505 	    resultParams.addAll(otherExtras);
506 	    int resultLength = resultParams.size();
507 	    String resultNames[] = new String[resultLength];
508 	    for (int i=0; i<resultLength; i++) {
509 		resultNames[i] = (String)resultParams.elementAt(i);
510 	    }
511 
512 	    Class resultClasses[] = new Class[resultLength];
513 	    Object resultDefaults[] = new Object[resultLength];
514 	    Object resultValidValues[] = new Object[resultLength];
515 	    String name;
516 	    int count;
517 	    for (count=0; count<commonNames.size(); count++) {
518 		name = (String)commonNames.elementAt(count);
519 		resultClasses[count] = thisClasses[getIndex(thisHash, name)];
520 		resultDefaults[count] = thisDefaults[getIndex(thisHash, name)];
521 		resultValidValues[count] = pld.getParamValueRange(name);
522 	    }
523 	    for (int i=0; i<thisExtraLength; i++) {
524 		name = (String)thisExtras.elementAt(i);
525 		resultClasses[count+i] = thisClasses[getIndex(thisHash, name)];
526 		resultDefaults[count+i] = thisDefaults[getIndex(thisHash,
527 								name)];
528 		resultValidValues[count+i] = pld.getParamValueRange(name);
529 	    }
530 	    count += thisExtraLength;
531 	    for (int i=0; i<otherExtraLength; i++) {
532 		name = (String)otherExtras.elementAt(i);
533 		resultClasses[i+count] = otherClasses[getIndex(otherHash,
534 							       name)];
535 		resultDefaults[i+count] = otherDefaults[getIndex(otherHash,
536 								 name)];
537 		resultValidValues[i+count] = otherPld.getParamValueRange(name);
538 	    }
539 
540 	    ParameterListDescriptorImpl resultPLD =
541 		new ParameterListDescriptorImpl(null,
542 						resultNames,
543 						resultClasses,
544 						resultDefaults,
545 						resultValidValues);
546 
547 	    // Both NC's are preferences
548 	    result = new NegotiableCapability(category,
549 					      capabilityName,
550 					      resultGenerators,
551 					      resultPLD,
552 					      true);
553 
554 	    for (int i=0; i<commonNames.size(); i++) {
555 		currParam = (String)commonNames.elementAt(i);
556 		thisValue = (Negotiable)getObjectParameter(currParam);
557 		otherValue =
558 		    (Negotiable)capability.getObjectParameter(currParam);
559 
560 		// If one of the values is null, select the other one, and
561 		// negotiation succeeds. Note that this also takes care
562 		// of the scenario when both are null, therefore the result
563 		// is null, and on a non-pref, this would have failed the
564 		// negotiation, but on a pref, it doesn't, so we just set
565 		// null (otherValue) as the result and allow negotiation to
566 		// succeed.
567 		if (thisValue == null) {
568 		    result.setParameter(currParam, otherValue);
569 		    continue;
570 		}
571 
572 		if (otherValue == null) {
573 		    result.setParameter(currParam, thisValue);
574 		    continue;
575 		}
576 
577 		// Following only gets executed if neither of the two is
578 		// a null, and therefore both have set values. If negotiation
579 		// fails, the negotiation as a whole is failed, otherwise
580 		// set the result on the resultant NC.
581 		resultValue = thisValue.negotiate(otherValue);
582 		if (resultValue == null) {
583 		    return null;
584 		}
585 
586 		result.setParameter(currParam, resultValue);
587 	    }
588 
589 	    // Copy the extra ones directly into the result
590 	    for (int i=0; i<thisExtraLength; i++) {
591 		currParam = (String)thisExtras.elementAt(i);
592 		result.setParameter(currParam,
593 				    (Negotiable)getObjectParameter(currParam));
594 	    }
595 
596 	    for (int i=0; i<otherExtraLength; i++) {
597 		currParam = (String)otherExtras.elementAt(i);
598 		result.setParameter(currParam,
599 			 (Negotiable)capability.getObjectParameter(currParam));
600 	    }
601 
602 	    break;
603 
604 	case 1:
605 
606 	    // The given capability is a pref, while this is a non-pref
607 	    commonNames = commonElements(thisHash, otherHash);
608 	    commonHash = hashNames(commonNames);
609 	    thisExtras = removeAll(thisHash, commonHash);
610 
611 	    // Create a new PLD which is the amalgamation of the two
612 	    // NC's PLD's
613 	    resultParams = new Vector(commonNames);
614 	    resultParams.addAll(thisExtras);
615 	    resultLength = resultParams.size();
616 	    resultNames = new String[resultLength];
617 	    for (int i=0; i<resultLength; i++) {
618 		resultNames[i] = (String)resultParams.elementAt(i);
619 	    }
620 
621 	    resultClasses = new Class[resultLength];
622 	    resultDefaults = new Object[resultLength];
623 	    resultValidValues = new Object[resultLength];
624 
625 	    count = 0;
626 	    for (count=0; count<commonNames.size(); count++) {
627 		name = (String)commonNames.elementAt(count);
628 		resultClasses[count] = thisClasses[getIndex(thisHash, name)];
629 		resultDefaults[count] = thisDefaults[getIndex(thisHash, name)];
630 		resultValidValues[count] = pld.getParamValueRange(name);
631 	    }
632 	    for (int i=0; i<thisExtras.size(); i++) {
633 		name = (String)thisExtras.elementAt(i);
634 		resultClasses[i+count] = thisClasses[getIndex(thisHash, name)];
635 		resultDefaults[i+count] = thisDefaults[getIndex(thisHash,
636 								name)];
637 		resultValidValues[i+count] = pld.getParamValueRange(name);
638 	    }
639 
640 	    resultPLD = new ParameterListDescriptorImpl(null,
641 							resultNames,
642 							resultClasses,
643 							resultDefaults,
644 							resultValidValues);
645 
646 	    result = new NegotiableCapability(category,
647 					      capabilityName,
648 					      resultGenerators,
649 					      resultPLD,
650 					      false);
651 
652 	    for (int i=0; i<commonNames.size(); i++) {
653 		currParam = (String)commonNames.elementAt(i);
654 		thisValue = (Negotiable)getObjectParameter(currParam);
655 		otherValue =
656 		    (Negotiable)capability.getObjectParameter(currParam);
657 
658 		if (thisValue == null) {
659 		    // If non-pref doesn't have value, negotiation fails right
660 		    // away
661 		    return null;
662 		}
663 
664 		if (otherValue == null) {
665 		    // If pref value is null, then non-pref's value wins.
666 		    // This needs to be done separately, since
667 		    // non-null.negotiate(null) returns null, which is *not*
668 		    // what we want.
669 		    result.setParameter(currParam, thisValue);
670 		} else {
671 		    // Do the negotiation.
672 		    resultValue = thisValue.negotiate(otherValue);
673 
674 		    if (resultValue == null) {
675 			// Negotiation on one parameter failed, so negotiation
676 			// on the entire NC has also failed, return null to
677 			// signify this
678 			return null;
679 		    } else {
680 			result.setParameter(currParam, resultValue);
681 		    }
682 		}
683 	    }
684 
685 	    // Copy the extra ones directly into the result
686 	    for (int i=0; i<thisExtras.size(); i++) {
687 		currParam = (String)thisExtras.elementAt(i);
688 		resultValue = (Negotiable)getObjectParameter(currParam);
689 		if (resultValue == null)
690 		    return null;
691 		result.setParameter(currParam, resultValue);
692 	    }
693 
694 	    break;
695 
696 	case 2:
697 
698 	    // The given capability is a non-pref, while this is a pref
699 	    commonNames = commonElements(thisHash, otherHash);
700 	    commonHash = hashNames(commonNames);
701 	    otherExtras = removeAll(otherHash, commonHash);
702 
703 	    // Create a new PLD which is the amalgamation of the two
704 	    // NC's PLD's
705 	    resultParams = new Vector(commonNames);
706 	    resultParams.addAll(otherExtras);
707 	    resultLength = resultParams.size();
708 	    resultNames = new String[resultLength];
709 	    for (int i=0; i<resultLength; i++) {
710 		resultNames[i] = (String)resultParams.elementAt(i);
711 	    }
712 
713 	    resultClasses = new Class[resultLength];
714 	    resultDefaults = new Object[resultLength];
715 	    resultValidValues = new Object[resultLength];
716 	    count = 0;
717 	    for (count=0; count<commonNames.size(); count++) {
718 		name = (String)commonNames.elementAt(count);
719 		resultClasses[count] = thisClasses[getIndex(thisHash, name)];
720 		resultDefaults[count] = thisDefaults[getIndex(thisHash, name)];
721 		resultValidValues[count] = pld.getParamValueRange(name);
722 	    }
723 
724 	    for (int i=0; i<otherExtras.size(); i++) {
725 		name = (String)otherExtras.elementAt(i);
726 		resultClasses[i+count] = otherClasses[getIndex(otherHash,
727 							       name)];
728 		resultDefaults[i+count] = otherDefaults[getIndex(otherHash,
729 								 name)];
730 		resultValidValues[i+count] = otherPld.getParamValueRange(name);
731 	    }
732 
733 	    resultPLD = new ParameterListDescriptorImpl(null,
734 							resultNames,
735 							resultClasses,
736 							resultDefaults,
737 							resultValidValues);
738 
739 	    result = new NegotiableCapability(category,
740 					      capabilityName,
741 					      resultGenerators,
742 					      resultPLD,
743 					      false);
744 
745 	    for (int i=0; i<commonNames.size(); i++) {
746 		currParam = (String)commonNames.elementAt(i);
747 		thisValue = (Negotiable)getObjectParameter(currParam);
748 		otherValue =
749 		    (Negotiable)capability.getObjectParameter(currParam);
750 
751 		// If non-pref doesn't have value, negotiation fails right
752 		// away
753 		if (otherValue == null) {
754 		    return null;
755 		}
756 
757 		if (thisValue == null) {
758 		    // If pref value is null, then non-pref's value wins.
759 		    // This needs to be done separately, since
760 		    // non-null.negotiate(null) returns null, which is *not*
761 		    // what we want.
762 		    result.setParameter(currParam, otherValue);
763 		} else {
764 		    // Do the negotiation.
765 		    resultValue = otherValue.negotiate(thisValue);
766 
767 		    if (resultValue == null) {
768 			// Negotiation on one parameter failed, so negotiation
769 			// on the entire NC has also failed, return null to
770 			// signify this
771 			return null;
772 		    } else {
773 			result.setParameter(currParam, resultValue);
774 		    }
775 		}
776 	    }
777 
778 	    for (int i=0; i<otherExtras.size(); i++) {
779 		currParam = (String)otherExtras.elementAt(i);
780 		resultValue =
781 		    (Negotiable)capability.getObjectParameter(currParam);
782 		if (resultValue == null)
783 		    return null;
784 		result.setParameter(currParam, resultValue);
785 	    }
786 
787 	    break;
788 
789 	case 3:
790 
791 	    // Both are non-prefs
792 	    result = new NegotiableCapability(category, capabilityName,
793 					      resultGenerators, pld, false);
794 
795 	    for (int i=0; i<thisNames.length; i++) {
796 		currParam = thisNames[i];
797 		thisValue = (Negotiable)getObjectParameter(currParam);
798 		otherValue =
799 		    (Negotiable)capability.getObjectParameter(currParam);
800 
801 		// failed since in nonpref-nonpref negotiation, both
802 		// Negotiables must have a non-null value
803 		if (thisValue == null ||
804 		    otherValue == null) {
805 		    return null;
806 		}
807 
808 		resultValue = thisValue.negotiate(otherValue);
809 
810 		if (resultValue == null) {
811 		    // Negotiation on one parameter failed, so negotiation
812 		    // on the entire NC has also failed, return null to
813 		    // signify this
814 		    return null;
815 		} else {
816 		    result.setParameter(currParam, resultValue);
817 		}
818 	    }
819 
820 	    break;
821 	}
822 
823 	return result;
824     }
825 
826     /**
827      * Returns true if the <code>ParameterListDescriptor</code> of the
828      * supplied <code>NegotiableCapability</code> is compatible with the
829      * <code>ParameterListDescriptor</code> of this class for negotiation
830      * purposes. If both the <code>NegotiableCapability</code> objects are
831      * non-preferences, both the number of parameters as well as the
832      * <code>Class</code> type of the parameters has to match for this
833      * method to return true. If either one or both of the
834      * <code>NegotiableCapability</code> objects is a preference, then
835      * the <code>Class</code> type of the same named parameters in both
836      * the <code>NegotiableCapability</code> object's
837      * <code>ParameterListDescriptor</code>s has to match for this
838      * method to return true.
839      *
840      * @param other   The <code>NegotiableCapability</code> to check
841      *                compatibility for negotiation purposes for.
842      * @throws IllegalArgumentException if other is null.
843      */
areParameterListDescriptorsCompatible(NegotiableCapability other)844     public boolean areParameterListDescriptorsCompatible(NegotiableCapability
845 							 other) {
846 
847 	if (other == null) {
848 	    throw new IllegalArgumentException(
849 				  JaiI18N.getString("NegotiableCapability6"));
850 	}
851 
852 	ParameterListDescriptor thisDesc = getParameterListDescriptor();
853 	ParameterListDescriptor otherDesc = other.getParameterListDescriptor();
854 
855 	String thisNames[] = thisDesc.getParamNames();
856         if (thisNames == null)
857             thisNames = new String[0];
858 	String otherNames[] = otherDesc.getParamNames();
859         if (otherNames == null)
860             otherNames = new String[0];
861 	Hashtable thisHash = hashNames(thisNames);
862 	Hashtable otherHash = hashNames(otherNames);
863 
864 	if (isPreference == false && other.isPreference() == false) {
865 
866 	    // The number of parameters must be the same.
867 	    if (thisDesc.getNumParameters() != otherDesc.getNumParameters())
868 		return false;
869 
870 	    // The same names should be present in both in the same order.
871 	    if (containsAll(thisHash, otherHash) == false)
872 		return false;
873 
874 	    Class thisParamClasses[] = thisDesc.getParamClasses();
875 	    Class otherParamClasses[] = otherDesc.getParamClasses();
876 	    for (int i=0; i<thisNames.length; i++) {
877 		if (thisParamClasses[i] !=
878                     otherParamClasses[getIndex(otherHash, thisNames[i])])
879 		    return false;
880 	    }
881 
882 	    return true;
883 
884 	} else {
885 
886 	    Vector commonNames = commonElements(thisHash, otherHash);
887 
888 	    Class thisParamClasses[] = thisDesc.getParamClasses();
889 	    Class otherParamClasses[] = otherDesc.getParamClasses();
890 	    String currName;
891 	    for (int i=0; i<commonNames.size(); i++) {
892 		currName = (String)commonNames.elementAt(i);
893 		if (thisParamClasses[getIndex(thisHash, currName)] !=
894 		    otherParamClasses[getIndex(otherHash, currName)])
895 		    return false;
896 	    }
897 
898 	    return true;
899 	}
900     }
901 
902     // A case insensitive containsAll for Hashtables containing Strings
containsAll(Hashtable thisHash, Hashtable otherHash)903     private boolean containsAll(Hashtable thisHash, Hashtable otherHash) {
904 
905 	CaselessStringKey thisNameKey;
906 	for (Enumeration i=thisHash.keys(); i.hasMoreElements(); ) {
907 	    thisNameKey = (CaselessStringKey)i.nextElement();
908 	    if (otherHash.containsKey(thisNameKey) == false)
909 		return false;
910 	}
911 
912 	return true;
913     }
914 
915     // Return only those names which exist in thisNames but not in otherNames
removeAll(Hashtable thisHash, Hashtable otherHash)916     private Vector removeAll(Hashtable thisHash, Hashtable otherHash) {
917 
918 	Vector v = new Vector();
919 	CaselessStringKey thisNameKey;
920 	for (Enumeration i=thisHash.keys(); i.hasMoreElements(); ) {
921 	    thisNameKey = (CaselessStringKey)i.nextElement();
922 	    if (otherHash.containsKey(thisNameKey))
923 		continue;
924 	    else
925 		v.add(thisNameKey.toString());
926 	}
927 
928 	return v;
929     }
930 
getIndex(Hashtable h, String s)931     private int getIndex(Hashtable h, String s) {
932 	return ((Integer)h.get(new CaselessStringKey(s))).intValue();
933     }
934 
commonElements(Hashtable thisHash, Hashtable otherHash)935     private Vector commonElements(Hashtable thisHash,
936 				  Hashtable otherHash) {
937 
938 	Vector v = new Vector();
939 	CaselessStringKey thisNameKey;
940 	for (Enumeration i=thisHash.keys(); i.hasMoreElements(); ) {
941 	    thisNameKey = (CaselessStringKey)i.nextElement();
942 	    if (otherHash.containsKey(thisNameKey))
943 		v.add(thisNameKey.toString());
944 	}
945 
946 	return v;
947     }
948 
hashNames(String paramNames[])949     private Hashtable hashNames(String paramNames[]) {
950 
951 	Hashtable h = new Hashtable();
952         if (paramNames != null) {
953 	    for (int i=0; i<paramNames.length; i++) {
954 	        h.put(new CaselessStringKey(paramNames[i]), new Integer(i));
955 	    }
956         }
957 
958         return h;
959     }
960 
hashNames(Vector paramNames)961     private Hashtable hashNames(Vector paramNames) {
962 
963 	Hashtable h = new Hashtable();
964         if (paramNames != null) {
965 	    for (int i=0; i<paramNames.size(); i++) {
966 	        h.put(new CaselessStringKey((String)(paramNames.elementAt(i))),
967 		      new Integer(i));
968 	    }
969         }
970 
971         return h;
972     }
973 
974     /***************** Overridden methods from ParameterList *****************/
975 
976     /**
977      * Overrides the method in <code>ParameterListImpl</code> to throw
978      * an IllegalArgumentException since parameter values set on this class
979      * must be a <code>Negotiable</code>.
980      *
981      * @param paramName a <code>String</code> naming a parameter.
982      * @param b a <code>byte</code> value for the parameter.
983      *
984      * @throws IllegalArgumentException since the value being set is not a
985      *         <code>Negotiable</code>.
986      */
setParameter(String paramName, byte b)987     public ParameterList setParameter(String paramName, byte b) {
988 	throw new IllegalArgumentException(
989 				JaiI18N.getString("NegotiableCapability2"));
990     }
991 
992     /**
993      * Overrides the method in <code>ParameterListImpl</code> to throw
994      * an IllegalArgumentException since parameter values set on this class
995      * must be a <code>Negotiable</code>.
996      *
997      * @param paramName a <code>String</code> naming a parameter.
998      * @param b a <code>boolean</code> value for the parameter.
999      *
1000      * @throws IllegalArgumentException since the value being set is not a
1001      *         <code>Negotiable</code>.
1002      */
setParameter(String paramName, boolean b)1003     public ParameterList setParameter(String paramName, boolean b) {
1004 	throw new IllegalArgumentException(
1005 				JaiI18N.getString("NegotiableCapability2"));
1006     }
1007 
1008     /**
1009      * Overrides the method in <code>ParameterListImpl</code> to throw
1010      * an IllegalArgumentException since parameter values set on this class
1011      * must be a <code>Negotiable</code>.
1012      *
1013      * @param paramName a <code>String</code> naming a parameter.
1014      * @param c a <code>char</code> value for the parameter.
1015      *
1016      * @throws IllegalArgumentException since the value being set is not a
1017      *         <code>Negotiable</code>.
1018      */
setParameter(String paramName, char c)1019     public ParameterList setParameter(String paramName, char c) {
1020  	throw new IllegalArgumentException(
1021 				JaiI18N.getString("NegotiableCapability2"));
1022     }
1023 
1024     /**
1025      * Overrides the method in <code>ParameterListImpl</code> to throw
1026      * an IllegalArgumentException since parameter values set on this class
1027      * must be a <code>Negotiable</code>.
1028      *
1029      * @param paramName a <code>String</code> naming a parameter.
1030      * @param s a short value for the parameter.
1031      *
1032      * @throws IllegalArgumentException since the value being set is not a
1033      *         <code>Negotiable</code>.
1034      */
setParameter(String paramName, short s)1035     public ParameterList setParameter(String paramName, short s) {
1036 	throw new IllegalArgumentException(
1037 				JaiI18N.getString("NegotiableCapability2"));
1038     }
1039 
1040     /**
1041      * Overrides the method in <code>ParameterListImpl</code> to throw
1042      * an IllegalArgumentException since parameter values set on this class
1043      * must be a <code>Negotiable</code>.
1044      *
1045      * @param paramName a <code>String</code> naming a parameter.
1046      * @param i an <code>int</code> value for the parameter.
1047      *
1048      * @throws IllegalArgumentException since the value being set is not a
1049      *         <code>Negotiable</code>.
1050      */
setParameter(String paramName, int i)1051     public ParameterList setParameter(String paramName, int i) {
1052 	throw new IllegalArgumentException(
1053 				JaiI18N.getString("NegotiableCapability2"));
1054     }
1055 
1056     /**
1057      * Overrides the method in <code>ParameterListImpl</code> to throw
1058      * an IllegalArgumentException since parameter values set on this class
1059      * must be a <code>Negotiable</code>.
1060      *
1061      * @param paramName a <code>String</code> naming a parameter.
1062      * @param l a <code>long</code> value for the parameter.
1063      *
1064      * @throws IllegalArgumentException since the value being set is not a
1065      *         <code>Negotiable</code>.
1066      */
setParameter(String paramName, long l)1067     public ParameterList setParameter(String paramName, long l) {
1068 	throw new IllegalArgumentException(
1069 				JaiI18N.getString("NegotiableCapability2"));
1070     }
1071 
1072     /**
1073      * Overrides the method in <code>ParameterListImpl</code> to throw
1074      * an IllegalArgumentException since parameter values set on this class
1075      * must be a <code>Negotiable</code>.
1076      *
1077      * @param paramName a <code>String</code> naming a parameter.
1078      * @param f a <code>float</code> value for the parameter.
1079      *
1080      * @throws IllegalArgumentException since the value being set is not a
1081      *         <code>Negotiable</code>.
1082      */
setParameter(String paramName, float f)1083     public ParameterList setParameter(String paramName, float f) {
1084 	throw new IllegalArgumentException(
1085 				JaiI18N.getString("NegotiableCapability2"));
1086     }
1087 
1088     /**
1089      * Overrides the method in <code>ParameterListImpl</code> to throw
1090      * an IllegalArgumentException since parameter values set on this class
1091      * must be a <code>Negotiable</code>.
1092      *
1093      * @param paramName a <code>String</code> naming a parameter.
1094      * @param d a <code>double</code> value for the parameter.
1095      *
1096      * @throws IllegalArgumentException since the value being set is not a
1097      *         <code>Negotiable</code>.
1098      */
setParameter(String paramName, double d)1099     public ParameterList setParameter(String paramName, double d) {
1100 	throw new IllegalArgumentException(
1101 				JaiI18N.getString("NegotiableCapability2"));
1102     }
1103 
1104     /**
1105      * Overrides the superclass method to ensure only a <code>Negotiable</code>
1106      * object can be added as the value of the parameter.
1107      *
1108      * @param paramName A <code>String</code> naming a parameter.
1109      * @param obj       An Object value for the parameter.
1110      *
1111      * @throws IllegalArgumentException if obj is not an instance of
1112      * <code>Negotiable</code>.
1113      */
setParameter(String paramName, Object obj)1114     public ParameterList setParameter(String paramName, Object obj) {
1115 
1116 	if (obj != null && !(obj instanceof Negotiable)) {
1117 	    throw new IllegalArgumentException(
1118 				JaiI18N.getString("NegotiableCapability2"));
1119 	}
1120 
1121 	super.setParameter(paramName, obj);
1122 	return this;
1123     }
1124 
1125     // getObjectParameter method doesn't need to be overridden since it
1126     // is implemented in ParameterListImpl and can return a Negotiable as
1127     // an Object
1128 
1129     /**
1130      * Overrides the method in <code>ParameterListImpl</code> to throw
1131      * an IllegalArgumentException since parameter values in this class
1132      * are <code>Negotiable</code> and therefore cannot be returned as
1133      * a primitive data type.
1134      *
1135      * @param paramName the name of the parameter to be returned.
1136      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1137      * cannot be returned as a primitive data type.
1138      */
getByteParameter(String paramName)1139     public byte getByteParameter(String paramName) {
1140 	throw new IllegalArgumentException(
1141 				JaiI18N.getString("NegotiableCapability3"));
1142     }
1143 
1144     /**
1145      * Overrides the method in <code>ParameterListImpl</code> to throw
1146      * an IllegalArgumentException since parameter values in this class
1147      * are <code>Negotiable</code> and therefore cannot be returned as
1148      * a primitive data type.
1149      *
1150      * @param paramName the name of the parameter to be returned.
1151      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1152      * cannot be returned as a primitive data type.
1153      */
getBooleanParameter(String paramName)1154     public boolean getBooleanParameter(String paramName) {
1155 	throw new IllegalArgumentException(
1156 				JaiI18N.getString("NegotiableCapability3"));
1157     }
1158 
1159     /**
1160      * Overrides the method in <code>ParameterListImpl</code> to throw
1161      * an IllegalArgumentException since parameter values in this class
1162      * are <code>Negotiable</code> and therefore cannot be returned as
1163      * a primitive data type.
1164      *
1165      * @param paramName the name of the parameter to be returned.
1166      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1167      * cannot be returned as a primitive data type.
1168      */
getCharParameter(String paramName)1169     public char getCharParameter(String paramName) {
1170 	throw new IllegalArgumentException(
1171 				JaiI18N.getString("NegotiableCapability3"));
1172     }
1173 
1174     /**
1175      * Overrides the method in <code>ParameterListImpl</code> to throw
1176      * an IllegalArgumentException since parameter values in this class
1177      * are <code>Negotiable</code> and therefore cannot be returned as
1178      * a primitive data type.
1179      *
1180      * @param paramName the name of the parameter to be returned.
1181      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1182      * cannot be returned as a primitive data type.
1183      */
getShortParameter(String paramName)1184     public short getShortParameter(String paramName) {
1185 	throw new IllegalArgumentException(
1186 				JaiI18N.getString("NegotiableCapability3"));
1187     }
1188 
1189     /**
1190      * Overrides the method in <code>ParameterListImpl</code> to throw
1191      * an IllegalArgumentException since parameter values in this class
1192      * are <code>Negotiable</code> and therefore cannot be returned as
1193      * a primitive data type.
1194      *
1195      * @param paramName the name of the parameter to be returned.
1196      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1197      * cannot be returned as a primitive data type.
1198      */
getIntParameter(String paramName)1199     public int getIntParameter(String paramName) {
1200 	throw new IllegalArgumentException(
1201 				JaiI18N.getString("NegotiableCapability3"));
1202     }
1203 
1204     /**
1205      * Overrides the method in <code>ParameterListImpl</code> to throw
1206      * an IllegalArgumentException since parameter values in this class
1207      * are <code>Negotiable</code> and therefore cannot be returned as
1208      * a primitive data type.
1209      *
1210      * @param paramName the name of the parameter to be returned.
1211      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1212      * cannot be returned as a primitive data type.
1213      */
getLongParameter(String paramName)1214     public long getLongParameter(String paramName) {
1215 	throw new IllegalArgumentException(
1216 				JaiI18N.getString("NegotiableCapability3"));
1217     }
1218 
1219     /**
1220      * Overrides the method in <code>ParameterListImpl</code> to throw
1221      * an IllegalArgumentException since parameter values in this class
1222      * are <code>Negotiable</code> and therefore cannot be returned as
1223      * a primitive data type.
1224      *
1225      * @param paramName the name of the parameter to be returned.
1226      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1227      * cannot be returned as a primitive data type.
1228      */
getFloatParameter(String paramName)1229     public float getFloatParameter(String paramName) {
1230 	throw new IllegalArgumentException(
1231 				JaiI18N.getString("NegotiableCapability3"));
1232     }
1233 
1234     /**
1235      * Overrides the method in <code>ParameterListImpl</code> to throw
1236      * an IllegalArgumentException since parameter values in this class
1237      * are <code>Negotiable</code> and therefore cannot be returned as
1238      * a primitive data type.
1239      *
1240      * @param paramName the name of the parameter to be returned.
1241      * @throws IllegalArgumentException since a <code>Negotiable</code> value
1242      * cannot be returned as a primitive data type.
1243      */
getDoubleParameter(String paramName)1244     public double getDoubleParameter(String paramName) {
1245 	throw new IllegalArgumentException(
1246 				JaiI18N.getString("NegotiableCapability3"));
1247     }
1248 }
1249