KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > functions > Parameters


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10
11 package org.mmbase.util.functions;
12
13 import org.mmbase.util.Casting;
14 import java.util.*;
15 import org.mmbase.util.logging.*;
16
17 /**
18  * This class implemements the Parameters interface.
19  * It provides a convenient way to create a List that allows the use of 'named parameters'.
20  * This List is therefore backed by a HashMap, but it behaves as a list. So if you set
21  * a parameter with a certain name, it always appears in the same location of the List.
22  * This List is modifiable but not resizeable. It is always the size of the definition array.
23  *
24  * @author Michiel Meeuwissen
25  * @since MMBase-1.7
26  * @version $Id: Parameters.java,v 1.23.2.1 2006/10/18 10:01:03 michiel Exp $
27  * @see Parameter
28  * @see #Parameters(Parameter[])
29  */

30
31 public class Parameters extends AbstractList implements java.io.Serializable JavaDoc {
32     private static final Logger log = Logging.getLoggerInstance(Parameters.class);
33
34     private static final int serialVersionUID = 1;
35
36     /**
37      * No need to bother for the functions with no parameters. This is a constant you could supply.
38      */

39     public static final Parameters VOID = new Parameters(Parameter.EMPTY);
40
41
42     /**
43      * The contents of this List are stored in this HashMap.
44      */

45     protected Map backing; /* String -> Value */
46
47     /**
48      * This array maps integers (position in array) to map keys, making it possible to implement
49      * List.
50      */

51     protected Parameter[] definition = null;
52
53     /**
54      * If <code>true</code>, values are automatically cast to the right type (if possible) when set.
55      */

56     protected boolean autoCasting = false;
57
58     private int fromIndex = 0;
59     protected int toIndex;
60
61     /**
62      * Constructor, taking an Parameter[] array argument.
63      * The Parameter may also be Parameter.Wrapper
64      * (to implement overriding of functions). The idea is that these array arguments are defined
65      * as constants in the classes which define a function with variable arguments.
66      * <br />
67      * The Parameter[] array could e.g. be somewhere defined as a constant, like this:
68      * <pre>
69      * <code>
70      * public final static Parameter[] MYFUNCTION_PARAMETERS = {
71      * new Parameter("type", Integer.class),
72      * new Parameter("text", String.class),
73      * Parameter.CLOUD, // a predefined parameter
74      * new Parameter.Wrapper(OTHERFUNCTION_PARAMETERS) // a way to include another definition in this one
75      * };
76      * </code>
77      * </pre>
78      */

79     public Parameters(Parameter[] def) {
80         definition = (Parameter[]) Functions.define(def, new ArrayList()).toArray(Parameter.EMPTY);
81         toIndex = definition.length;
82         if (log.isDebugEnabled()) {
83             log.debug("Found definition " + Arrays.asList(definition));
84         }
85         backing = new HashMap();
86         // fill with default values, and check for non-unique keys.
87
for (int i = fromIndex; i < toIndex; i++) {
88             if (backing.put(definition[i].getName(), definition[i].getDefaultValue()) != null) {
89                 throw new IllegalArgumentException JavaDoc("Parameter keys not unique");
90             }
91
92         }
93
94     }
95
96     /**
97      * If you happen to have a List of parameters, then you can wrap it into an Parameters with this constructor.
98      *
99      * @param values Collection with values. This Collection should have a predictable iteration order.
100      * @throws NullPointerException if definition is null
101      * @see #Parameters(Parameter[])
102      */

103     public Parameters(Parameter[] def, Collection values) {
104         this(def);
105         setAll(values);
106     }
107
108     /**
109      * Used for nicer implemenation of subList (which we want to also be instanceof Parameters).
110      */

111     protected Parameters(Parameters params, int from, int to) {
112         backing = params.backing;
113         definition = params.definition;
114         fromIndex = from + params.fromIndex;
115         toIndex = to + params.fromIndex;
116         if (fromIndex < 0) throw new IndexOutOfBoundsException JavaDoc("fromIndex < 0");
117         if (toIndex > definition.length) throw new IndexOutOfBoundsException JavaDoc("toIndex greater then length of list");
118         if (fromIndex > toIndex) throw new IndexOutOfBoundsException JavaDoc("fromIndex > toIndex");
119
120     }
121
122     public String JavaDoc toString() {
123         StringBuffer JavaDoc buf = new StringBuffer JavaDoc("[");
124         for (int i = fromIndex; i < toIndex; i++) {
125             if (i > fromIndex) buf.append(", ");
126             buf.append(definition[i]).append('=').append(get(i));
127         }
128         buf.append("]");
129         return buf.toString();
130     }
131
132     public Class JavaDoc[] toClassArray() {
133         Class JavaDoc[] array = new Class JavaDoc[toIndex - fromIndex];
134         for (int i = fromIndex; i < toIndex; i++) {
135             array[i - fromIndex] = definition[i].getDataType().getTypeAsClass();
136         }
137         return array;
138     }
139
140     /**
141      * Sets the 'auto casting' property (which on default is false)
142      * @param autocast the new value for autocast
143      * @see #isAutoCasting
144      */

145     public void setAutoCasting(boolean autocast) {
146         autoCasting = autocast;
147     }
148
149     public Parameter[] getDefinition() {
150         if (fromIndex > 0 || toIndex != definition.length - 1) {
151             return (Parameter[]) Arrays.asList(definition).subList(fromIndex, toIndex).toArray(Parameter.EMPTY);
152         } else {
153             return definition;
154         }
155     }
156
157     /**
158      * Whether this Parameters object is 'automaticly casting'. If it is, that means that you can set e.g.
159      * an Integer by a String.
160      * @return <code>true</code> if autocasting is on
161      */

162     public boolean isAutoCasting() {
163         return autoCasting;
164     }
165
166     // implementation of List
167
// @throws NullPointerException if definition not set
168
public int size() {
169         return toIndex - fromIndex;
170     }
171
172     // implementation of List
173
// @throws NullPointerException if definition not set
174
public Object JavaDoc get(int i) {
175         return backing.get(definition[i + fromIndex].getName());
176     }
177
178     // implementation of (modifiable) List
179
// @throws NullPointerException if definition not set
180
public Object JavaDoc set(int i, Object JavaDoc value) {
181         Parameter a = definition[i + fromIndex];
182         if (autoCasting) value = a.autoCast(value);
183         a.checkType(value);
184         return backing.put(a.getName(), value);
185     }
186
187
188     /**
189      * Throws an IllegalArgumentException if one of the required parameters was not entered.
190      */

191     public void checkRequiredParameters() {
192         for (int i = fromIndex; i < toIndex; i++) {
193             Parameter a = definition[i];
194             if (a.isRequired() && (get(a.getName()) == null)) {
195                 throw new IllegalArgumentException JavaDoc("Required parameter '" + a.getName() + "' is null (of (" + toString() + ")");
196             }
197         }
198     }
199
200     /**
201      * Returns the position of a parameter in the parameters list, using the Parameter as a qualifier.
202      * you can tehn acecss that paramter with {@link #get(int)}.
203      * @param parameter the parameter
204      * @return the index of the parameter, or -1 if it doesn't exist
205      */

206
207     public int indexOfParameter(Parameter parameter) {
208         int index = -1;
209         for (int i = fromIndex; i < toIndex; i++) {
210             if (definition[i].equals(parameter)) {
211                 index = i - fromIndex;
212                 break;
213             }
214         }
215         return index;
216     }
217
218
219     /**
220      * Returns the position of a parameter in the parameters list, using the parameter name as a qualifier.
221      * you can then acecss that paramter with {@link #get(int)}.
222      * @param parameterName the name of the parameter
223      * @return the index of the parameter, or -1 if it doesn't exist
224      */

225     public int indexOfParameter(String JavaDoc parameterName) {
226         int index = -1;
227         for (int i = fromIndex; i < toIndex; i++) {
228             if (definition[i].getName().equals(parameterName)) {
229                 index = i - fromIndex;
230                 break;
231             }
232         }
233         return index;
234     }
235
236
237     /**
238      * Checks wether a certain parameter is available, using the Parameter as a qualifier.
239      * @param parameter the parameter
240      * @return <code>true</code> if a parameter exists.
241      */

242     public boolean containsParameter(Parameter parameter) {
243         return indexOfParameter(parameter) != -1;
244     }
245
246     /**
247      * Checks wether a certain parameter is available, using the parameter name as a qualifier.
248      * @param parameterName the name of the parameter
249      * @return <code>true</code> if a parameter exists.
250      */

251     public boolean containsParameter(String JavaDoc parameterName) {
252         return indexOfParameter(parameterName) != -1;
253     }
254
255     /**
256      * Sets the value of a parameter.
257      * @param parameter the Parameter describing the parameter to set
258      * @param value the object value to set
259      * @throws IllegalArgumentException if either the argument name is unknown to this Parameters, or the value is of the wrong type.
260      */

261     public Parameters set(Parameter parameter, Object JavaDoc value) {
262         int index = indexOfParameter(parameter);
263         if (index > -1) {
264             set(index, value);
265             return this;
266         } else {
267             throw new IllegalArgumentException JavaDoc("The parameter '" + parameter + "' is not defined (defined are " + toString() + ")");
268         }
269     }
270
271     /**
272      * Sets the value of a parameter.
273      * @param parameterName the name of the parameter to set
274      * @param value the object value to set
275      * @throws IllegalArgumentException if either the argument name is unknown to this Parameters, or the value is of the wrong type.
276      */

277     public Parameters set(String JavaDoc parameterName, Object JavaDoc value) {
278         int index = indexOfParameter(parameterName);
279         if (index > -1) {
280             set(index, value);
281             return this;
282         } else {
283             throw new IllegalArgumentException JavaDoc("The parameter '" + parameterName + "' is not defined (defined are " + toString() + ")");
284         }
285     }
286
287     /**
288      * Copies all values of a map to the corresponding values of this Parameters Object.
289      */

290     public Parameters setAll(Map map) {
291         if (map != null) {
292             Iterator i = map.entrySet().iterator();
293             while (i.hasNext()) {
294                 Map.Entry entry = (Map.Entry) i.next();
295                 set((String JavaDoc) entry.getKey(), entry.getValue());
296             }
297         }
298         return this;
299     }
300
301     /**
302      * Copies all values of a collection to the corresponding values of this Parameters Object.
303      */

304     public Parameters setAll(Collection values) {
305         if (values != null) {
306             if (log.isDebugEnabled()) {
307                 if (values.size() > definition.length) {
308                     log.debug("Given too many values. " + values + " does not match " + Arrays.asList(definition));
309                 }
310             }
311             Iterator valueIterator = values.iterator();
312             int i = 0;
313             while (valueIterator.hasNext()) {
314                 set(i++, valueIterator.next());
315             }
316         }
317         return this;
318     }
319
320     public List subList(int fromIndex, int toIndex) {
321         return new Parameters(this, fromIndex, toIndex);
322     }
323
324
325     /**
326      * Sets the value of an argument, if the argument is defined, otherwise do nothing.
327      * @param parameter the parameter to set
328      * @param value the object value to set
329      */

330     public Parameters setIfDefined(Parameter parameter, Object JavaDoc value) {
331         int index = indexOfParameter(parameter);
332         if (index > -1) {
333             set(index, value);
334         }
335         return this;
336     }
337
338
339     /**
340      * Sets the value of an argument, if the argument is defined, otherwise do nothing.
341      * @param parameterName the name of the parameter to set
342      * @param value the object value to set
343      */

344     public Parameters setIfDefined(String JavaDoc parameterName, Object JavaDoc value) {
345         int index = indexOfParameter(parameterName);
346         if (index > -1) {
347             set(index, value);
348         }
349         return this;
350     }
351
352     /**
353      * Gets the value of a parameter.
354      * @param parameter the parameter to get
355      * @return value the parameter value
356      */

357     public Object JavaDoc get(Parameter parameter) {
358         return get(parameter.getName());
359     }
360
361
362     /**
363      * Gets the value of a parameter.
364      * @param parameterName the name of the parameter to get
365      * @return value the parameter value
366      */

367     public Object JavaDoc get(String JavaDoc parameterName) {
368         return backing.get(parameterName);
369     }
370
371
372     /**
373      * Gets the value of a parameter, cast to a String.
374      * @param parameter the parameter to get
375      * @return value the parameter value as a <code>STring</code>
376      */

377
378     public String JavaDoc getString(Parameter parameter) {
379         return getString(parameter.getName());
380     }
381
382
383     /**
384      * Gets the value of a parameter, cast to a String.
385      * @param parameterName the name of the parameter to get
386      * @return value the parameter value as a <code>STring</code>
387      */

388     public String JavaDoc getString(String JavaDoc parameterName) {
389         return Casting.toString(get(parameterName));
390     }
391
392     /**
393      * Gives the arguments back as a (unmodifiable) map.
394      */

395     public Map toMap() {
396         return Collections.unmodifiableMap(backing);
397     }
398
399 }
400
Popular Tags