| Parameter.java |
1 /*
2 * Parameter.java
3 *
4 * Copyright (c) 1998-2005, The University of Sheffield.
5 *
6 * This file is part of GATE (see http://gate.ac.uk/), and is free
7 * software, licenced under the GNU Library General Public License,
8 * Version 2, June 1991 (in the distribution as file licence.html,
9 * and also available at http://gate.ac.uk/gate/licence.html).
10 *
11 * Hamish Cunningham, 15/Oct/2000
12 *
13 * $Id: Parameter.java,v 1.24 2006/03/17 12:42:12 ian_roberts Exp $
14 */
15
16 package gate.creole;
17
18 import java.io.Serializable;
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.util.*;
22
23 import gate.Gate;
24 import gate.util.*;
25
26
27 /** Models a resource parameter.
28 */
29 public class Parameter implements Serializable
30 {
31 /**
32 * Constructor
33 * @param baseUrl the URL to the creole.xml file that defines the resource
34 * this parameter belongs to. This will be used a context when deriving
35 * default values for the parameters of type URL.
36 */
37 public Parameter(URL baseUrl){
38 this.baseURL = baseUrl;
39 }
40
41 /** The type name of the parameter */
42 String typeName;
43
44 /** Set the type name for this parameter */
45 public void setTypeName(String typeName) { this.typeName = typeName; }
46
47 /** Get the type name for this parameter */
48 public String getTypeName() { return typeName; }
49
50 /** Is the parameter optional? */
51 boolean optional = false;
52
53 /** Set optionality of this parameter */
54 public void setOptional(boolean optional) { this.optional = optional; }
55
56 /** Is the parameter optional? */
57 public boolean isOptional() { return optional; }
58
59 /** The name of the item's class. If the parameter is a collection then
60 * we need to know the class of its items in order to create them the
61 * way we want.
62 */
63 String itemClassName = null;
64
65 /** A set of strings representing suffixes for URL params*/
66 Set suffixes = null;
67
68 /** Calculate and return the default value for this parameter */
69 public Object calculateDefaultValue() throws ParameterException {
70 // if there's no default string and this is a builtin type, return null
71 if(
72 defaultValueString == null && typeName != null &&
73 typeName.startsWith("java.")
74 )
75 return null;
76
77 return calculateValueFromString(defaultValueString);
78 } // calculateDefaultValue()
79
80 /** Calculate and return the value for this parameter starting from a String
81 */
82 public Object calculateValueFromString(String stringValue)
83 throws ParameterException {
84 //if we have no string we can't construct a value
85 Object value = null;
86
87 // get the Class for the parameter via Class.forName or CREOLE register
88 Class paramClass = getParameterClass();
89
90
91 // Test if the paramClass is a collection and if it is, try to
92 // construct the param as a collection of items specified in the
93 // default string value...
94 if (Collection.class.isAssignableFrom(paramClass) &&
95 (!paramClass.isInterface())){
96 // Create an collection object belonging to paramClass
97 Collection colection = null;
98 try{
99 colection = (Collection)paramClass.getConstructor(new Class[]{}).
100 newInstance(new Object[]{});
101 } catch(Exception ex){
102 throw new ParameterException("Could not construct an object of type "
103 + typeName + " for param " + name +
104 "\nProblem was: " + ex.toString());
105 }// End try
106 // If an itemClassName was specified then try to create objects belonging
107 // to this class and add them to the collection. Otherwise add the
108 // string tokens to the collection.
109 if(itemClassName == null){
110 // Read the tokens from the default value and try to create items
111 // belonging to the itemClassName
112 StringTokenizer strTokenizer = new StringTokenizer(
113 defaultValueString,";");
114 while(strTokenizer.hasMoreTokens()){
115 String itemStringValue = strTokenizer.nextToken();
116 colection.add(itemStringValue);
117 }// End while
118 }else{
119 Class itemClass = null;
120 try{
121 itemClass = Gate.getClassLoader().loadClass(itemClassName);
122 }catch(ClassNotFoundException e){
123 throw new ParameterException("Could not construct a class object for "
124 + itemClassName + " for param "+ name +
125 ", with type name="+ typeName);
126 }// End try
127 // Read the tokens from the default value and try to create items
128 // belonging to the itemClassName
129 StringTokenizer strTokenizer = new StringTokenizer(
130 defaultValueString,";");
131 while(strTokenizer.hasMoreTokens()){
132 // Read a string item and construct an object belonging to
133 // itemClassName
134 String itemStringValue = strTokenizer.nextToken();
135 Object itemValue = null;
136 try{
137 itemValue = itemClass.getConstructor(new Class[]{String.class}).
138 newInstance(new Object[]{itemStringValue});
139 }catch(Exception e){
140 throw new ParameterException("Could not create an object of " +
141 itemClassName + " for param name "+ name + ", with type name ="+
142 typeName);
143 }// End try
144 // Add the item value object to the collection
145 colection.add(itemValue);
146 }// End while
147 }// End if(itemClassName == null)
148 return colection;
149 }// End if (Collection.class.isAssignableFrom(paramClass))
150 // java builtin types - for numeric types, we don't attempt to parse an
151 // empty string value, but just leave value as null
152 if(typeName.startsWith("java.")) {
153 if(typeName.equals("java.lang.Boolean"))
154 value = Boolean.valueOf(stringValue);
155 else if(typeName.equals("java.lang.Long")) {
156 if(stringValue != null && !stringValue.equals("")) {
157 value = Long.valueOf(stringValue);
158 }
159 }
160 else if(typeName.equals("java.lang.Integer")) {
161 if(stringValue != null && !stringValue.equals("")) {
162 value = Integer.valueOf(stringValue);
163 }
164 }
165 else if(typeName.equals("java.lang.String"))
166 value = stringValue;
167 else if(typeName.equals("java.lang.Double")) {
168 if(stringValue != null && !stringValue.equals("")) {
169 value = Double.valueOf(stringValue);
170 }
171 }
172 else if(typeName.equals("java.lang.Float")) {
173 if(stringValue != null && !stringValue.equals("")) {
174 value = Float.valueOf(stringValue);
175 }
176 }
177 else if(typeName.equals("java.net.URL"))
178 try{
179 value = new URL(baseURL, stringValue);
180 }catch(MalformedURLException mue){
181 value = null;
182 }
183 else{
184 //try to construct a new value from the string using a constructor
185 // e.g. for URLs
186 try{
187 if(!paramClass.isAssignableFrom(String.class)){
188 value = paramClass.getConstructor(new Class[]{String.class}).
189 newInstance(new Object[]{stringValue});
190 }
191 }catch(Exception e){
192 throw new ParameterException("Unsupported parameter type " + typeName);
193 }
194 }
195 } else {
196 // non java types
197 if(resData == null)
198 resData = (ResourceData) Gate.getCreoleRegister().get(typeName);
199 if(resData == null){
200 //unknown type
201 return null;
202 }
203
204 WeakBumpyStack instantiations = resData.getInstantiations();
205 if(! instantiations.isEmpty()) value = instantiations.peek();
206 }
207
208 return value;
209 } // calculateValueFromString()
210
211
212 /** The resource data that this parameter is part of. */
213 protected ResourceData resData;
214
215 /** Get the default value for this parameter. If the value is
216 * currently null it will try and calculate a value.
217 * @see #calculateDefaultValue()
218 */
219 public Object getDefaultValue() throws ParameterException {
220 return calculateDefaultValue();
221 } // getDefaultValue
222
223 /** Default value string (unprocessed, from the metadata)
224 * for the parameter
225 */
226 String defaultValueString;
227
228 /** Set the default value string (from the metadata)
229 * for the parameter
230 */
231 public void setDefaultValueString(String defaultValueString) {
232 this.defaultValueString = defaultValueString;
233 } // setDefaultValueString
234
235 /** Get the default value string (unprocessed, from the metadata)
236 * for the parameter
237 */
238 public String getDefaultValueString() { return defaultValueString; }
239
240 /** Comment for the parameter */
241 String comment;
242
243 /** Set the comment for this parameter */
244 public void setComment(String comment) { this.comment = comment; }
245
246 /** Get the comment for this parameter */
247 public String getComment() { return comment; }
248
249 /** Name for the parameter */
250 String name;
251
252 /** Set the name for this parameter */
253 public void setName(String name) { this.name = name; }
254
255 /** Get the name for this parameter */
256 public String getName() { return name; }
257
258 /** Get the suffixes atached with this param. If it's null then there are
259 * no suffices attached with it
260 */
261 public Set getSuffixes(){ return suffixes;}
262
263 /** Is this a run-time parameter? */
264 boolean runtime = false;
265
266 /**
267 * The URL to the creole.xml file that defines the resource this parameter
268 * belongs to. It is used for deriving default values for parameters of type
269 * {@link URL}.
270 */
271 protected URL baseURL;
272 /** Set runtime status of this parameter */
273 public void setRuntime(boolean runtime) { this.runtime = runtime; }
274
275 /** Is the parameter runtime? */
276 public boolean isRuntime() { return runtime; }
277
278 /** The Class for the parameter type */
279 protected Class paramClass;
280
281 /** Find the class for this parameter type. */
282 protected Class getParameterClass() throws ParameterException
283 {
284 // get java builtin classes via class; else look in the register
285 try {
286 ResourceData resData = (ResourceData)
287 Gate.getCreoleRegister().get(typeName);
288 if(resData == null){
289 paramClass = Gate.getClassLoader().loadClass(typeName);
290 }else{
291 paramClass = resData.getResourceClass();
292 }
293
294 // if(typeName.startsWith("java."))
295 // paramClass = Class.forName(typeName);
296 // else {
297 // ResourceData resData =
298 // (ResourceData) Gate.getCreoleRegister().get(typeName);
299 // if(resData == null)
300 // throw new ParameterException(
301 // "No resource data for " + typeName + " in Parameter/getParamClz"
302 // );
303 // paramClass = resData.getResourceClass();
304 // }
305 } catch(ClassNotFoundException e) {
306 throw new ParameterException(
307 "Couldn't find class " + typeName + ": " + Strings.getNl() + e
308 );
309 }
310
311 if(paramClass == null)
312 throw new ParameterException("Couldn't find class " + typeName);
313
314 return paramClass;
315 } // getParameterClass
316
317 /** String representation */
318 public String toString() {
319 try{
320 return "Parameter: name="+ name+ "; valueString=" + typeName +
321 "; optional=" + optional +
322 "; defaultValueString=" + defaultValueString +
323 "; defaultValue=" + getDefaultValue() + "; comment=" +
324 comment + "; runtime=" + runtime +
325 "; itemClassName=" + itemClassName +
326 "; suffixes=" + suffixes;
327 }catch(ParameterException pe){
328 throw new GateRuntimeException(pe.toString());
329 }
330 }
331
332 /**
333 * If this parameter is a List type this will return the type of the items
334 * in the list. If the type is <tt>null</tt> String will be assumed.
335 */
336 public String getItemClassName() {
337 return itemClassName;
338 } // toString()
339 } // class Parameter
340