CallableWithArgs.java
01 /*
02  * Copyright 2009-2012 the original author or authors.
03  *
04  * Licensed under the Apache License, Version 2.0 (the "License");
05  * you may not use this file except in compliance with the License.
06  * You may obtain a copy of the License at
07  *
08  *      http://www.apache.org/licenses/LICENSE-2.0
09  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package griffon.util;
17 
18 import java.util.concurrent.Callable;
19 
20 /**
21  * A Callable that can have arguments.
22  * Instances of this class can be seen as substitutes for Closures when dealing
23  * with non-Groovy languages. There are several Griffon core and Griffon plugin APIs
24  * that accept a {@code CallableWithArgs} where a Closure would be used.</p>
25  <p>Example:</p>
26  <pre>
27 Callable&lt;Boolean&gt; c = new CallableWithArgs&lt;Boolean&gt;() {
28     public Boolean call(Object[] args) {
29         return "Hello".equals(args[0]);
30     }
31 };
32 
33 c.setArgs("Hello");
34 assert c.call()
35 c.setArgs("world!");
36 assert !c.call();
37 assert !c.call(new Object[]{ "again" });
38  </pre>
39  *
40  *
41  @author Andres Almiray
42  */
43 public abstract class CallableWithArgs<V> implements Callable<V> {
44     private static final Object[] NO_ARGS = new Object[0];
45     private final Object[] lock = new Object[0];
46     private Object[] args = NO_ARGS;
47 
48     public void setArgs(Object[] args) {
49         if (args == null) {
50             args = NO_ARGS;
51         }
52         synchronized (lock) {
53             this.args = new Object[args.length];
54             System.arraycopy(args, 0this.args, 0, args.length);
55         }
56     }
57 
58     public Object[] getArgs() {
59         synchronized (lock) {
60             return args;
61         }
62     }
63 
64     public final V call() {
65         Object[] copy = null;
66         synchronized (lock) {
67             copy = new Object[args.length];
68             System.arraycopy(args, 0, copy, 0, args.length);
69         }
70         return call(copy);
71     }
72 
73     public abstract V call(Object[] args);
74 }