01 /*
02 * Copyright 2008-2015 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.transform;
17
18 import org.codehaus.groovy.transform.GroovyASTTransformationClass;
19
20 import java.lang.annotation.ElementType;
21 import java.lang.annotation.Retention;
22 import java.lang.annotation.RetentionPolicy;
23 import java.lang.annotation.Target;
24
25 /**
26 * <p>Annotates a property.</p>
27 * <p>This transformation provides a convenient way to register InvalidationListeners
28 * on an observable bean by leveraging Groovy's closures and the Groovy cast operator.</p>
29 * <p/>
30 * <p>The following code exemplifies what must be written by hand in order to register an InvalidationListener.
31 * <pre>
32 * import griffon.transform.FXObservable
33 * import javafx.beans.InvalidationListener
34 *
35 * class MyModel {
36 * @FXObservable String name
37 * @FXObservable String lastname
38 *
39 * private def snoopAll = { ... }
40 *
41 * MyModel() {
42 * nameProperty().addListener(snoopAll as InvalidationListener)
43 * lastnameProperty().addListener({
44 * controller.someAction(it)
45 * } as InvalidationListener)
46 * }
47 * }
48 * </pre>
49 * <p/>
50 * <p>Applying @InvalidationListener to the previous snippet results in the following code</p>
51 * <pre>
52 * import griffon.transform.FXObservable
53 * import griffon.transform.InvalidationListener
54 *
55 * class MyModel {
56 * @FXObservable
57 * @InvalidationListener(snoopAll)
58 * String name
59 *
60 * @FXObservable
61 * @InvalidationListener({ controller.someAction(it)})
62 * String lastname
63 *
64 * private def snoopAll = { ... }
65 * }
66 * </pre>
67 * <p>
68 * Any closures found as the annotation's value will be either transformed
69 * into inner classes that implement InvalidationListener (when the value
70 * is a closure defined in place) or be casted as a proxy of InvalidationListener
71 * (when the value is a property reference found in the same class).<p>
72 * List of closures are also supported.
73 *
74 * @author Andres Almiray
75 */
76 @Retention(RetentionPolicy.SOURCE)
77 @Target({ElementType.FIELD})
78 @GroovyASTTransformationClass("org.codehaus.griffon.compile.core.ast.transform.InvalidationListenerASTTransformation")
79 public @interface InvalidationListener {
80 String value();
81
82 /**
83 * If the {@code InvalidationListener} should be wrapped with a {@code WeakInvalidationListener} or not
84 *
85 * @since 2.4.0
86 */
87 boolean weak() default false;
88 }
|