1 | /*
|
---|
2 | * The Apache Software License, Version 1.1
|
---|
3 | *
|
---|
4 | * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
|
---|
5 | * reserved.
|
---|
6 | *
|
---|
7 | * Redistribution and use in source and binary forms, with or without
|
---|
8 | * modification, are permitted provided that the following conditions
|
---|
9 | * are met:
|
---|
10 | *
|
---|
11 | * 1. Redistributions of source code must retain the above copyright
|
---|
12 | * notice, this list of conditions and the following disclaimer.
|
---|
13 | *
|
---|
14 | * 2. Redistributions in binary form must reproduce the above copyright
|
---|
15 | * notice, this list of conditions and the following disclaimer in
|
---|
16 | * the documentation and/or other materials provided with the
|
---|
17 | * distribution.
|
---|
18 | *
|
---|
19 | * 3. The end-user documentation included with the redistribution, if
|
---|
20 | * any, must include the following acknowlegement:
|
---|
21 | * "This product includes software developed by the
|
---|
22 | * Apache Software Foundation (http://www.apache.org/)."
|
---|
23 | * Alternately, this acknowlegement may appear in the software itself,
|
---|
24 | * if and wherever such third-party acknowlegements normally appear.
|
---|
25 | *
|
---|
26 | * 4. The names "The Jakarta Project", "Ant", and "Apache Software
|
---|
27 | * Foundation" must not be used to endorse or promote products derived
|
---|
28 | * from this software without prior written permission. For written
|
---|
29 | * permission, please contact [email protected].
|
---|
30 | *
|
---|
31 | * 5. Products derived from this software may not be called "Apache"
|
---|
32 | * nor may "Apache" appear in their names without prior written
|
---|
33 | * permission of the Apache Group.
|
---|
34 | *
|
---|
35 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
---|
36 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
---|
37 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
---|
38 | * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
---|
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
---|
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
---|
41 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
---|
42 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
---|
43 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
---|
44 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
---|
45 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
---|
46 | * SUCH DAMAGE.
|
---|
47 | * ====================================================================
|
---|
48 | *
|
---|
49 | * This software consists of voluntary contributions made by many
|
---|
50 | * individuals on behalf of the Apache Software Foundation. For more
|
---|
51 | * information on the Apache Software Foundation, please see
|
---|
52 | * <http://www.apache.org/>.
|
---|
53 | */
|
---|
54 | package ise.antelope.tasks;
|
---|
55 |
|
---|
56 | import java.lang.reflect.Method;
|
---|
57 | import java.lang.reflect.Array;
|
---|
58 | import java.util.Vector;
|
---|
59 | import java.util.Enumeration;
|
---|
60 |
|
---|
61 | /**
|
---|
62 | * Provides access to java.lang.Math and java.lang.StrictMath for Ant. Provides
|
---|
63 | * add, subtract, multiply, divide and mod methods as well as access to all methods
|
---|
64 | * java.lang.Math and java.lang.StrictMath via reflection.
|
---|
65 | * @author Dale Anson, [email protected]
|
---|
66 | */
|
---|
67 | public class Math {
|
---|
68 |
|
---|
69 | private boolean strict = false;
|
---|
70 |
|
---|
71 | public Math() {}
|
---|
72 |
|
---|
73 | public Math( boolean strict ) {
|
---|
74 | this.strict = strict;
|
---|
75 | }
|
---|
76 |
|
---|
77 | public void setStrict( boolean strict ) {
|
---|
78 | this.strict = strict;
|
---|
79 | }
|
---|
80 |
|
---|
81 | public boolean isStrict() {
|
---|
82 | return strict;
|
---|
83 | }
|
---|
84 |
|
---|
85 | public static double add( double a, double b ) {
|
---|
86 | return a + b;
|
---|
87 | }
|
---|
88 | public static float add( float a, float b ) {
|
---|
89 | return a + b;
|
---|
90 | }
|
---|
91 | public static long add( long a, long b ) {
|
---|
92 | return a + b;
|
---|
93 | }
|
---|
94 | public static int add( int a, int b ) {
|
---|
95 | return a + b;
|
---|
96 | }
|
---|
97 | public static double add( double[] a ) {
|
---|
98 | if ( a.length == 0 )
|
---|
99 | throw new IllegalArgumentException();
|
---|
100 | if ( a.length == 1 )
|
---|
101 | return a[ 0 ];
|
---|
102 | double b = a[ 0 ];
|
---|
103 | for ( int i = 1; i < a.length; i++ )
|
---|
104 | b += a[ i ];
|
---|
105 | return b;
|
---|
106 | }
|
---|
107 | public static float add( float[] a ) {
|
---|
108 | if ( a.length == 0 )
|
---|
109 | throw new IllegalArgumentException();
|
---|
110 | if ( a.length == 1 )
|
---|
111 | return a[ 0 ];
|
---|
112 | float b = a[ 0 ];
|
---|
113 | for ( int i = 1; i < a.length; i++ )
|
---|
114 | b += a[ i ];
|
---|
115 | return b;
|
---|
116 | }
|
---|
117 | public static long add( long[] a ) {
|
---|
118 | if ( a.length == 0 )
|
---|
119 | throw new IllegalArgumentException();
|
---|
120 | if ( a.length == 1 )
|
---|
121 | return a[ 0 ];
|
---|
122 | long b = a[ 0 ];
|
---|
123 | for ( int i = 1; i < a.length; i++ )
|
---|
124 | b += a[ i ];
|
---|
125 | return b;
|
---|
126 | }
|
---|
127 | public static int add( int[] a ) {
|
---|
128 | if ( a.length == 0 )
|
---|
129 | throw new IllegalArgumentException();
|
---|
130 | if ( a.length == 1 )
|
---|
131 | return a[ 0 ];
|
---|
132 | int b = a[ 0 ];
|
---|
133 | for ( int i = 1; i < a.length; i++ )
|
---|
134 | b += a[ i ];
|
---|
135 | return b;
|
---|
136 | }
|
---|
137 |
|
---|
138 | public static double subtract( double a, double b ) {
|
---|
139 | return a - b;
|
---|
140 | }
|
---|
141 | public static float subtract( float a, float b ) {
|
---|
142 | return a - b;
|
---|
143 | }
|
---|
144 | public static long subtract( long a, long b ) {
|
---|
145 | return a - b;
|
---|
146 | }
|
---|
147 | public static int subtract( int a, int b ) {
|
---|
148 | return a - b;
|
---|
149 | }
|
---|
150 | public static double subtract( double[] a ) {
|
---|
151 | if ( a.length == 0 )
|
---|
152 | throw new IllegalArgumentException();
|
---|
153 | if ( a.length == 1 )
|
---|
154 | return a[ 0 ];
|
---|
155 | double b = a[ 0 ];
|
---|
156 | for ( int i = 1; i < a.length; i++ )
|
---|
157 | b -= a[ i ];
|
---|
158 | return b;
|
---|
159 | }
|
---|
160 | public static float subtract( float[] a ) {
|
---|
161 | if ( a.length == 0 )
|
---|
162 | throw new IllegalArgumentException();
|
---|
163 | if ( a.length == 1 )
|
---|
164 | return a[ 0 ];
|
---|
165 | float b = a[ 0 ];
|
---|
166 | for ( int i = 1; i < a.length; i++ )
|
---|
167 | b -= a[ i ];
|
---|
168 | return b;
|
---|
169 | }
|
---|
170 | public static long subtract( long[] a ) {
|
---|
171 | if ( a.length == 0 )
|
---|
172 | throw new IllegalArgumentException();
|
---|
173 | if ( a.length == 1 )
|
---|
174 | return a[ 0 ];
|
---|
175 | long b = a[ 0 ];
|
---|
176 | for ( int i = 1; i < a.length; i++ )
|
---|
177 | b -= a[ i ];
|
---|
178 | return b;
|
---|
179 | }
|
---|
180 | public static int subtract( int[] a ) {
|
---|
181 | if ( a.length == 0 )
|
---|
182 | throw new IllegalArgumentException();
|
---|
183 | if ( a.length == 1 )
|
---|
184 | return a[ 0 ];
|
---|
185 | int b = a[ 0 ];
|
---|
186 | for ( int i = 1; i < a.length; i++ )
|
---|
187 | b -= a[ i ];
|
---|
188 | return b;
|
---|
189 | }
|
---|
190 |
|
---|
191 | public static double multiply( double a, double b ) {
|
---|
192 | return a * b;
|
---|
193 | }
|
---|
194 | public static float multiply( float a, float b ) {
|
---|
195 | return a * b;
|
---|
196 | }
|
---|
197 | public static long multiply( long a, long b ) {
|
---|
198 | return a * b;
|
---|
199 | }
|
---|
200 | public static int multiply( int a, int b ) {
|
---|
201 | return a * b;
|
---|
202 | }
|
---|
203 | public static double multiply( double[] a ) {
|
---|
204 | if ( a.length == 0 )
|
---|
205 | throw new IllegalArgumentException();
|
---|
206 | if ( a.length == 1 )
|
---|
207 | return a[ 0 ];
|
---|
208 | double b = a[ 0 ];
|
---|
209 | for ( int i = 1; i < a.length; i++ )
|
---|
210 | b *= a[ i ];
|
---|
211 | return b;
|
---|
212 | }
|
---|
213 | public static float multiply( float[] a ) {
|
---|
214 | if ( a.length == 0 )
|
---|
215 | throw new IllegalArgumentException();
|
---|
216 | if ( a.length == 1 )
|
---|
217 | return a[ 0 ];
|
---|
218 | float b = a[ 0 ];
|
---|
219 | for ( int i = 1; i < a.length; i++ )
|
---|
220 | b *= a[ i ];
|
---|
221 | return b;
|
---|
222 | }
|
---|
223 | public static long multiply( long[] a ) {
|
---|
224 | if ( a.length == 0 )
|
---|
225 | throw new IllegalArgumentException();
|
---|
226 | if ( a.length == 1 )
|
---|
227 | return a[ 0 ];
|
---|
228 | long b = a[ 0 ];
|
---|
229 | for ( int i = 1; i < a.length; i++ )
|
---|
230 | b *= a[ i ];
|
---|
231 | return b;
|
---|
232 | }
|
---|
233 | public static int multiply( int[] a ) {
|
---|
234 | if ( a.length == 0 )
|
---|
235 | throw new IllegalArgumentException();
|
---|
236 | if ( a.length == 1 )
|
---|
237 | return a[ 0 ];
|
---|
238 | int b = a[ 0 ];
|
---|
239 | for ( int i = 1; i < a.length; i++ )
|
---|
240 | b *= a[ i ];
|
---|
241 | return b;
|
---|
242 | }
|
---|
243 |
|
---|
244 | public static double divide( double a, double b ) {
|
---|
245 | return a / b;
|
---|
246 | }
|
---|
247 | public static float divide( float a, float b ) {
|
---|
248 | return a / b;
|
---|
249 | }
|
---|
250 | public static long divide( long a, long b ) {
|
---|
251 | return a / b;
|
---|
252 | }
|
---|
253 | public static int divide( int a, int b ) {
|
---|
254 | return a / b;
|
---|
255 | }
|
---|
256 | public static double divide( double[] a ) {
|
---|
257 | if ( a.length == 0 )
|
---|
258 | throw new IllegalArgumentException();
|
---|
259 | if ( a.length == 1 )
|
---|
260 | return a[ 0 ];
|
---|
261 | double b = a[ 0 ];
|
---|
262 | for ( int i = 1; i < a.length; i++ )
|
---|
263 | b /= a[ i ];
|
---|
264 | return b;
|
---|
265 | }
|
---|
266 | public static float divide( float[] a ) {
|
---|
267 | if ( a.length == 0 )
|
---|
268 | throw new IllegalArgumentException();
|
---|
269 | if ( a.length == 1 )
|
---|
270 | return a[ 0 ];
|
---|
271 | float b = a[ 0 ];
|
---|
272 | for ( int i = 1; i < a.length; i++ )
|
---|
273 | b /= a[ i ];
|
---|
274 | return b;
|
---|
275 | }
|
---|
276 | public static long divide( long[] a ) {
|
---|
277 | if ( a.length == 0 )
|
---|
278 | throw new IllegalArgumentException();
|
---|
279 | if ( a.length == 1 )
|
---|
280 | return a[ 0 ];
|
---|
281 | long b = a[ 0 ];
|
---|
282 | for ( int i = 1; i < a.length; i++ )
|
---|
283 | b /= a[ i ];
|
---|
284 | return b;
|
---|
285 | }
|
---|
286 | public static int divide( int[] a ) {
|
---|
287 | if ( a.length == 0 )
|
---|
288 | throw new IllegalArgumentException();
|
---|
289 | if ( a.length == 1 )
|
---|
290 | return a[ 0 ];
|
---|
291 | int b = a[ 0 ];
|
---|
292 | for ( int i = 1; i < a.length; i++ )
|
---|
293 | b /= a[ i ];
|
---|
294 | return b;
|
---|
295 | }
|
---|
296 |
|
---|
297 | public static double mod( double a, double b ) {
|
---|
298 | return a % b;
|
---|
299 | }
|
---|
300 | public static float mod( float a, float b ) {
|
---|
301 | return a % b;
|
---|
302 | }
|
---|
303 | public static long mod( long a, long b ) {
|
---|
304 | return a % b;
|
---|
305 | }
|
---|
306 | public static int mod( int a, int b ) {
|
---|
307 | return a % b;
|
---|
308 | }
|
---|
309 | public static double mod( double[] a ) {
|
---|
310 | if ( a.length == 0 )
|
---|
311 | throw new IllegalArgumentException();
|
---|
312 | if ( a.length == 1 )
|
---|
313 | return a[ 0 ];
|
---|
314 | double b = a[ 0 ];
|
---|
315 | for ( int i = 1; i < a.length; i++ )
|
---|
316 | b %= a[ i ];
|
---|
317 | return b;
|
---|
318 | }
|
---|
319 | public static float mod( float[] a ) {
|
---|
320 | if ( a.length == 0 )
|
---|
321 | throw new IllegalArgumentException();
|
---|
322 | if ( a.length == 1 )
|
---|
323 | return a[ 0 ];
|
---|
324 | float b = a[ 0 ];
|
---|
325 | for ( int i = 1; i < a.length; i++ )
|
---|
326 | b %= a[ i ];
|
---|
327 | return b;
|
---|
328 | }
|
---|
329 | public static long mod( long[] a ) {
|
---|
330 | if ( a.length == 0 )
|
---|
331 | throw new IllegalArgumentException();
|
---|
332 | if ( a.length == 1 )
|
---|
333 | return a[ 0 ];
|
---|
334 | long b = a[ 0 ];
|
---|
335 | for ( int i = 1; i < a.length; i++ )
|
---|
336 | b %= a[ i ];
|
---|
337 | return b;
|
---|
338 | }
|
---|
339 | public static int mod( int[] a ) {
|
---|
340 | if ( a.length == 0 )
|
---|
341 | throw new IllegalArgumentException();
|
---|
342 | if ( a.length == 1 )
|
---|
343 | return a[ 0 ];
|
---|
344 | int b = a[ 0 ];
|
---|
345 | for ( int i = 1; i < a.length; i++ )
|
---|
346 | b %= a[ i ];
|
---|
347 | return b;
|
---|
348 | }
|
---|
349 |
|
---|
350 | /**
|
---|
351 | * Do a mathematical calculation. The allowed operations are all
|
---|
352 | * operations supported by java.lang.Math and this class. Assumes data
|
---|
353 | * type is "double".
|
---|
354 | * @param op the name of a mathematical operation to perform
|
---|
355 | * @param the operands for the operation, these strings must parse to numbers.
|
---|
356 | */
|
---|
357 | public Number calculate( String op, String[] operands ) {
|
---|
358 | return calculate( op, "double", operands );
|
---|
359 | }
|
---|
360 |
|
---|
361 | /**
|
---|
362 | * Do a mathematical calculation. The allowed operations are all
|
---|
363 | * operations supported by java.lang.Math.
|
---|
364 | * @param op the name of a mathematical operation to perform
|
---|
365 | * @param type the data type of the operands
|
---|
366 | * @param the operands for the operation
|
---|
367 | */
|
---|
368 | public Number calculate( String op, String type, String[] operands ) {
|
---|
369 | try {
|
---|
370 | if ( operands.length > 2 ) {
|
---|
371 | if ( op.equals( "add" ) ||
|
---|
372 | op.equals( "subtract" ) ||
|
---|
373 | op.equals( "multiply" ) ||
|
---|
374 | op.equals( "divide" ) ||
|
---|
375 | op.equals( "mod" ) ) {
|
---|
376 | return calculateArray( op, type, operands );
|
---|
377 | }
|
---|
378 | else
|
---|
379 | throw new IllegalArgumentException( "too many operands" );
|
---|
380 | }
|
---|
381 |
|
---|
382 | Class c;
|
---|
383 | if ( strict )
|
---|
384 | c = Class.forName( "java.lang.StrictMath" );
|
---|
385 | else
|
---|
386 | c = Class.forName( "java.lang.Math" );
|
---|
387 |
|
---|
388 | // check if op is 'random'. Random is a special case in that it is
|
---|
389 | // the only method in Math that takes no parameters.
|
---|
390 | if ( op.equals( "random" ) ) {
|
---|
391 | Method m = c.getDeclaredMethod( op, new Class[] {} );
|
---|
392 | Object result = m.invoke( c, null );
|
---|
393 | return ( Number ) result;
|
---|
394 | }
|
---|
395 |
|
---|
396 | // find candidate methods for the requested operation
|
---|
397 | Vector candidates = new Vector();
|
---|
398 | Method[] methods = c.getDeclaredMethods();
|
---|
399 | for ( int i = 0; i < methods.length; i++ ) {
|
---|
400 | String name = methods[ i ].getName();
|
---|
401 | if ( name.equals( op ) ) {
|
---|
402 | candidates.addElement( methods[ i ] );
|
---|
403 | }
|
---|
404 | }
|
---|
405 |
|
---|
406 | if ( candidates.size() == 0 ) {
|
---|
407 | // try the other Math
|
---|
408 | //c = Class.forName( "ise.antelope.tasks.Math" );
|
---|
409 | c = this.getClass();
|
---|
410 | methods = c.getDeclaredMethods();
|
---|
411 | for ( int i = 0; i < methods.length; i++ ) {
|
---|
412 | String name = methods[ i ].getName();
|
---|
413 | if ( name.equals( op ) ) {
|
---|
414 | candidates.addElement( methods[ i ] );
|
---|
415 | }
|
---|
416 | }
|
---|
417 | }
|
---|
418 |
|
---|
419 | if ( candidates.size() == 0 )
|
---|
420 | throw new RuntimeException( "Unknown operation: " + op );
|
---|
421 |
|
---|
422 | // get the desired data type for the operation, default is
|
---|
423 | // Double.TYPE if no other match is found
|
---|
424 | Class wantTypeClass = getDataType( type );
|
---|
425 |
|
---|
426 | // get the parameter count for the candidate methods -- in Math,
|
---|
427 | // all like named methods have the same number of parameters, just
|
---|
428 | // the data types are different. (Fix for bug # 724812 -- the above
|
---|
429 | // statement is true of java.lang.Math, but not of this class.)
|
---|
430 | //int paramCount = ( ( Method ) candidates.elementAt( 0 ) ).getParameterTypes().length;
|
---|
431 | int paramCount = -1;
|
---|
432 | try {
|
---|
433 | for (int i = 0; i <= candidates.size(); i++) {
|
---|
434 | Method candidate = (Method)candidates.elementAt(i);
|
---|
435 | paramCount = candidate.getParameterTypes().length;
|
---|
436 | if (paramCount == operands.length)
|
---|
437 | break;
|
---|
438 | }
|
---|
439 | }
|
---|
440 | catch(Exception e) {
|
---|
441 | throw new RuntimeException("Wrong number of arguments, have " +
|
---|
442 | operands.length + ", but can't find corresponding method.");
|
---|
443 | }
|
---|
444 |
|
---|
445 | // make sure there are enough arguments to pass to the method
|
---|
446 | // see bug fix above, this is no longer necessary
|
---|
447 | //if ( operands.length != paramCount )
|
---|
448 | // throw new RuntimeException( "Wrong number of arguments, have " +
|
---|
449 | // operands.length + ", expected " + paramCount );
|
---|
450 |
|
---|
451 | // determine the actual type class for the method to invoke.
|
---|
452 | // Some methods have only one implementation so determine the
|
---|
453 | // typeClass from the method itself, not the desired.
|
---|
454 | Class typeClass = null;
|
---|
455 | if ( candidates.size() == 1 ) {
|
---|
456 | Method m = ( Method ) candidates.elementAt( 0 );
|
---|
457 | typeClass = m.getParameterTypes() [ 0 ];
|
---|
458 | }
|
---|
459 | else {
|
---|
460 | // check each candidate to find one with the desired type
|
---|
461 | Enumeration en = candidates.elements();
|
---|
462 | while ( en.hasMoreElements() ) {
|
---|
463 | Method m = ( Method ) en.nextElement();
|
---|
464 | if ( m.getParameterTypes() [ 0 ].equals( wantTypeClass ) ) {
|
---|
465 | typeClass = wantTypeClass;
|
---|
466 | break;
|
---|
467 | }
|
---|
468 | }
|
---|
469 | if ( typeClass == null )
|
---|
470 | throw new RuntimeException( "Can't find a method with parameters of type " + type );
|
---|
471 | }
|
---|
472 |
|
---|
473 | // get the method to invoke
|
---|
474 | Class[] paramTypes = new Class[ paramCount ];
|
---|
475 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
476 | paramTypes[ i ] = typeClass;
|
---|
477 | }
|
---|
478 | Method m = c.getDeclaredMethod( op, paramTypes );
|
---|
479 |
|
---|
480 | // load the parameters and invoke the method
|
---|
481 | Object[] params = getParams( typeClass, operands );
|
---|
482 | Object result = m.invoke( c, params );
|
---|
483 |
|
---|
484 | return ( Number ) result;
|
---|
485 |
|
---|
486 | }
|
---|
487 | catch ( Exception e ) {
|
---|
488 | e.printStackTrace();
|
---|
489 | }
|
---|
490 | return null;
|
---|
491 | }
|
---|
492 |
|
---|
493 | /**
|
---|
494 | * Performs a calculation on an array of numbers. The mathematical methods
|
---|
495 | * in this class will accept an array of numbers, so
|
---|
496 | * <code>add(new int[]{1, 2, 3})</code>
|
---|
497 | * is equivalent to
|
---|
498 | * <code>add(add(1, 2), 3)</code>
|
---|
499 | * which is equivalent to 1 + 2 + 3.
|
---|
500 | * @param op the operation to perform
|
---|
501 | * @type the data type of the operands. All operands will be cast to the same
|
---|
502 | * data type
|
---|
503 | * @param operands these strings must parse to numbers.
|
---|
504 | */
|
---|
505 | private Number calculateArray( String op, String type, String[] operands ) {
|
---|
506 | try {
|
---|
507 | Class c = this.getClass();
|
---|
508 |
|
---|
509 | // find candidate methods for the requested operation
|
---|
510 | Vector candidates = new Vector();
|
---|
511 | Method[] methods = c.getDeclaredMethods();
|
---|
512 | for ( int i = 0; i < methods.length; i++ ) {
|
---|
513 | String name = methods[ i ].getName();
|
---|
514 | if ( name.equals( op ) ) {
|
---|
515 | if ( methods[ i ].getParameterTypes().length == 1 ) {
|
---|
516 | if ( methods[ i ].getParameterTypes() [ 0 ].isArray() )
|
---|
517 | candidates.addElement( methods[ i ] );
|
---|
518 | }
|
---|
519 | }
|
---|
520 | }
|
---|
521 | if ( candidates.size() == 0 )
|
---|
522 | throw new RuntimeException( "Unknown operation: " + op );
|
---|
523 |
|
---|
524 | // get the desired data type for the operation, default is
|
---|
525 | // Double.TYPE if no other match is found
|
---|
526 | Object wantTypeClass = getDataTypeArray( type, operands.length );
|
---|
527 |
|
---|
528 | // find the actual method to invoke and invoke it immediately once
|
---|
529 | // it is found
|
---|
530 | Class typeClass = null;
|
---|
531 | Enumeration en = candidates.elements();
|
---|
532 | while ( en.hasMoreElements() ) {
|
---|
533 | Method m = ( Method ) en.nextElement();
|
---|
534 | if ( m.getParameterTypes() [ 0 ].equals( wantTypeClass.getClass() ) ) {
|
---|
535 | typeClass = getDataType( type );
|
---|
536 | Object[] params = getParamsArray( typeClass, operands );
|
---|
537 | Object result = m.invoke( c, params );
|
---|
538 | return ( Number ) result;
|
---|
539 | }
|
---|
540 | }
|
---|
541 | }
|
---|
542 | catch ( Exception e ) {
|
---|
543 | e.printStackTrace();
|
---|
544 | }
|
---|
545 | return null;
|
---|
546 | }
|
---|
547 |
|
---|
548 | /**
|
---|
549 | * Converts a string representing a data type into the actual type.
|
---|
550 | * @param type one of "int", "long", "float", or "double"
|
---|
551 | * @return one of Integer.TYPE, Long.TYPE, Float.TYPE, or Double.TYPE. If the
|
---|
552 | * given type is null or not one of the allowed types, Double.TYPE will be
|
---|
553 | * returned.
|
---|
554 | */
|
---|
555 | private Class getDataType( String type ) {
|
---|
556 | if ( type == null )
|
---|
557 | return Double.TYPE;
|
---|
558 | if ( type.equals( "int" ) ) {
|
---|
559 | return Integer.TYPE;
|
---|
560 | }
|
---|
561 | else if ( type.equals( "long" ) ) {
|
---|
562 | return Long.TYPE;
|
---|
563 | }
|
---|
564 | else if ( type.equals( "float" ) ) {
|
---|
565 | return Float.TYPE;
|
---|
566 | }
|
---|
567 | else {
|
---|
568 | return Double.TYPE;
|
---|
569 | }
|
---|
570 | }
|
---|
571 |
|
---|
572 | /**
|
---|
573 | * Converts a string representing a data type into an Array.
|
---|
574 | * @param type one of "int", "long", "float", or "double"
|
---|
575 | * @param length how long to make the array
|
---|
576 | * @return an Array representing the data type
|
---|
577 | */
|
---|
578 | private Object getDataTypeArray( String type, int length ) {
|
---|
579 | if ( type == null )
|
---|
580 | return Array.newInstance( Double.TYPE, length );
|
---|
581 | if ( type.equals( "int" ) ) {
|
---|
582 | return Array.newInstance( Integer.TYPE, length );
|
---|
583 | }
|
---|
584 | else if ( type.equals( "long" ) ) {
|
---|
585 | return Array.newInstance( Long.TYPE, length );
|
---|
586 | }
|
---|
587 | else if ( type.equals( "float" ) ) {
|
---|
588 | return Array.newInstance( Float.TYPE, length );
|
---|
589 | }
|
---|
590 | else {
|
---|
591 | return Array.newInstance( Double.TYPE, length );
|
---|
592 | }
|
---|
593 | }
|
---|
594 |
|
---|
595 | /**
|
---|
596 | * @returns the given operands as an array of the given type.
|
---|
597 | */
|
---|
598 | private Object[] getParams( Class typeClass, String[] operands ) {
|
---|
599 | int paramCount = operands.length;
|
---|
600 | Object[] params = new Object[ paramCount ];
|
---|
601 | if ( typeClass == Double.TYPE ) {
|
---|
602 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
603 | params[ i ] = new Double( operands[ i ] );
|
---|
604 | }
|
---|
605 | }
|
---|
606 | else if ( typeClass == Long.TYPE ) {
|
---|
607 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
608 | params[ i ] = new Long( operands[ i ] );
|
---|
609 | }
|
---|
610 | }
|
---|
611 | else if ( typeClass == Float.TYPE ) {
|
---|
612 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
613 | params[ i ] = new Float( operands[ i ] );
|
---|
614 | }
|
---|
615 | }
|
---|
616 | else {
|
---|
617 | // Integer.TYPE is only other choice
|
---|
618 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
619 | params[ i ] = new Integer( operands[ i ] );
|
---|
620 | }
|
---|
621 | }
|
---|
622 | if ( paramCount > 2 )
|
---|
623 | params = new Object[] {params};
|
---|
624 | return params;
|
---|
625 | }
|
---|
626 |
|
---|
627 | /**
|
---|
628 | * Converts the given operands into an array of the given type.
|
---|
629 | */
|
---|
630 | private Object[] getParamsArray( Class typeClass, String[] operands ) {
|
---|
631 | int paramCount = operands.length;
|
---|
632 | if ( typeClass == Double.TYPE ) {
|
---|
633 | double[] array = ( double[] ) Array.newInstance( typeClass, operands.length );
|
---|
634 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
635 | Array.setDouble( array, i, new Double( operands[ i ] ).doubleValue() );
|
---|
636 | }
|
---|
637 | return new Object[] {array};
|
---|
638 | }
|
---|
639 | else if ( typeClass == Long.TYPE ) {
|
---|
640 | long[] array = ( long[] ) Array.newInstance( typeClass, operands.length );
|
---|
641 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
642 | Array.setLong( array, i, new Long( operands[ i ] ).longValue() );
|
---|
643 | }
|
---|
644 | return new Object[] {array};
|
---|
645 | }
|
---|
646 | else if ( typeClass == Float.TYPE ) {
|
---|
647 | float[] array = ( float[] ) Array.newInstance( typeClass, operands.length );
|
---|
648 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
649 | Array.setFloat( array, i, new Float( operands[ i ] ).floatValue() );
|
---|
650 | }
|
---|
651 | return new Object[] {array};
|
---|
652 | }
|
---|
653 | else {
|
---|
654 | // Integer.TYPE is only other choice
|
---|
655 | Object array = Array.newInstance( typeClass, operands.length );
|
---|
656 | for ( int i = 0; i < paramCount; i++ ) {
|
---|
657 | Array.setInt( array, i, new Integer( operands[ i ] ).intValue() );
|
---|
658 | }
|
---|
659 | return new Object[] {array};
|
---|
660 | }
|
---|
661 | }
|
---|
662 |
|
---|
663 | public static void main ( String[] args ) {
|
---|
664 | Math math = new Math();
|
---|
665 | System.out.println( math.calculate( "add", new String[] {"6", "5", "4"} ) );
|
---|
666 | }
|
---|
667 | }
|
---|