PropertyListener.java
01 /*
02  * Copyright 2010-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 
17 package griffon.transform;
18 
19 import org.codehaus.groovy.transform.GroovyASTTransformationClass;
20 
21 import java.lang.annotation.ElementType;
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 import java.lang.annotation.Target;
25 
26 /**
27  <p>Annotates a class.</p>
28  <p>This transformation provides a convenient way to register PropertyChangeListeners
29  * on an observable bean by leveraging Groovy's closures and the Groovy cast operator.</p>
30  *
31  <p>The following code exemplifies what must be written by hand in order to register a pair
32  * of PropertyChangeListeners. One of them is a catch-all handler while the second is property specific.
33  <pre>
34  * import groovy.beans.Bindable
35  * import java.beans.PropertyChangeListener
36  *
37  * class MyModel {
38  *     &#064;Bindable String name
39  *     &#064;Bindable String lastname
40  *
41  *     def snoopAll = { evt -> ... }
42  *
43  *     MyModel() {
44  *         addPropertyChangeListener(snoopAll as PropertyChangeListener)
45  *         addPropertyChangeListener('lastname', {
46  *             controller.someAction(it)
47  *         } as PropertyChangeListener)
48  *     }
49  * }
50  </pre>
51  *
52  <p>Applying &#064;PropertyListener to the previous snippet results in the following code</p>
53  <pre>
54  * import griffon.transform.PropertyListener
55  * import groovy.beans.Bindable
56  *
57  * &#064;PropertyListener(snoopAll)
58  * class MyModel {
59  *     &#064;Bindable String name
60  *
61  *     &#064;Bindable
62  *     &#064;PropertyListener({controller.someAction(it)})
63  *     String lastname
64  *
65  *     def snoopAll = { evt -> ... }
66  * }
67  </pre>
68  *
69  * Any closures found as the annotation's value will be either transformed
70  * into inner classes that implement PropertyChangeListener (when the value
71  * is a closure defined in place) or be casted as a proxy of PropertyChangeListener
72  * (when the value is a property reference found in the same class).<p>
73  * List of closures are also supported.
74  *
75  @author Andres Almiray
76  @see org.codehaus.griffon.ast.PropertyListenerASTTransformation
77  */
78 @Retention(RetentionPolicy.SOURCE)
79 @Target({ElementType.FIELD, ElementType.TYPE})
80 @GroovyASTTransformationClass("org.codehaus.griffon.ast.PropertyListenerASTTransformation")
81 public @interface PropertyListener {
82     String value();
83 }