01 /*
02 * SPDX-License-Identifier: Apache-2.0
03 *
04 * Copyright 2008-2021 the original author or authors.
05 *
06 * Licensed under the Apache License, Version 2.0 (the "License");
07 * you may not use this file except in compliance with the License.
08 * You may obtain a copy of the License at
09 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package griffon.transform;
19
20 import org.codehaus.groovy.transform.GroovyASTTransformationClass;
21
22 import java.lang.annotation.ElementType;
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 import java.lang.annotation.Target;
26
27 /**
28 * <p>Annotates a property.</p>
29 * <p>This transformation provides a convenient way to register InvalidationListeners
30 * on an observable bean by leveraging Groovy's closures and the Groovy cast operator.</p>
31 * <p/>
32 * <p>The following code exemplifies what must be written by hand in order to register an InvalidationListener.
33 * <pre>
34 * import griffon.transform.FXObservable
35 * import javafx.beans.InvalidationListener
36 *
37 * class MyModel {
38 * @FXObservable String name
39 * @FXObservable String lastname
40 *
41 * private def snoopAll = { ... }
42 *
43 * MyModel() {
44 * nameProperty().addListener(snoopAll as InvalidationListener)
45 * lastnameProperty().addListener({
46 * controller.someAction(it)
47 * } as InvalidationListener)
48 * }
49 * }
50 * </pre>
51 * <p/>
52 * <p>Applying @InvalidationListener to the previous snippet results in the following code</p>
53 * <pre>
54 * import griffon.transform.FXObservable
55 * import griffon.transform.InvalidationListener
56 *
57 * class MyModel {
58 * @FXObservable
59 * @InvalidationListener(snoopAll)
60 * String name
61 *
62 * @FXObservable
63 * @InvalidationListener({ controller.someAction(it)})
64 * String lastname
65 *
66 * private def snoopAll = { ... }
67 * }
68 * </pre>
69 * <p>
70 * Any closures found as the annotation's value will be either transformed
71 * into inner classes that implement InvalidationListener (when the value
72 * is a closure defined in place) or be casted as a proxy of InvalidationListener
73 * (when the value is a property reference found in the same class).<p>
74 * List of closures are also supported.
75 *
76 * @author Andres Almiray
77 */
78 @Retention(RetentionPolicy.SOURCE)
79 @Target({ElementType.FIELD})
80 @GroovyASTTransformationClass("org.codehaus.griffon.compile.core.ast.transform.InvalidationListenerASTTransformation")
81 public @interface InvalidationListener {
82 String value();
83
84 /**
85 * If the {@code InvalidationListener} should be wrapped with a {@code WeakInvalidationListener} or not
86 *
87 * @since 2.4.0
88 */
89 boolean weak() default false;
90 }
|