001 /*
002 * Copyright 2009-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package griffon.transform;
018
019 import org.codehaus.groovy.transform.GroovyASTTransformationClass;
020
021 import java.lang.annotation.ElementType;
022 import java.lang.annotation.Retention;
023 import java.lang.annotation.RetentionPolicy;
024 import java.lang.annotation.Target;
025
026 /**
027 * <p>Annotates a method or property.</p>
028 *
029 * Annotated elements must follow these rules
030 * <ul>
031 * <li>must be a public method or property</li>
032 * <li>name does not match an event handler</li>
033 * <li>must pass {@code griffon.util.GriffonClassUtils.isPlainMethod()} if it's a method</li>
034 * <li>its value must be a closure (including curried method pointers) if it's a property</li>
035 * </ul>
036 *
037 * This annotation takes {@code griffon.util.Threading.Policy} as value, with {@code Threading.Policy.OUTSIDE_UITHREAD} being
038 * the default value.<p>
039 *
040 * <p>The following snippet exemplifies the compactness of code when the annotation is applied </p>
041 * <pre>
042 * import griffon.transform.Threading
043 *
044 * class Sample {
045 * @Threading
046 * void doSomethingOutside(String arg) {
047 * println "Outside $arg"
048 * }
049 * @Threading(Threading.Policy.INSIDE_UITHREAD_SYNC)
050 * void doSomethingInside(String arg) {
051 * println "Inside $arg"
052 * }
053 * }
054 * </pre>
055 *
056 * <p>The equivalent, non-annotated code is</p>
057 * <pre>
058 * import griffon.core.UIThreadManager
059 *
060 * class Sample {
061 * void doSomethingOutside(String arg) {
062 * UIThreadManager.instance.executeOutside {
063 * println "Outside $arg"
064 * }
065 * }
066 * void doSomethingInside(String arg) {
067 * UIThreadManager.instance.executeSync {
068 * println "Inside $arg"
069 * }
070 * }
071 * }
072 * </pre>
073 *
074 * @author Andres Almiray
075 * @see Threading.Policy
076 * @see org.codehaus.griffon.ast.ThreadingASTTransformation
077 * @since 0.9.2
078 */
079 @Retention(RetentionPolicy.SOURCE)
080 @Target({ElementType.METHOD, ElementType.FIELD})
081 @GroovyASTTransformationClass("org.codehaus.griffon.ast.ThreadingASTTransformation")
082 public @interface Threading {
083 Policy value() default Policy.OUTSIDE_UITHREAD;
084
085 /**
086 * Indicates the type of threading management for a method or property.</p>
087 * The following values apply
088 * <ul>
089 * <li>{@code SKIP} - no threading management will be performed.</li>
090 * <li>{@code OUTSIDE_UITHREAD} - code should be invoked outside of the UI thread.</li>
091 * <li>{@code INSIDE_UITHREAD_SYNC} - code should be invoked inside the UI thread using a synchronous call.</li>
092 * <li>{@code INSIDE_UITHREAD_ASYNC} - code should be invoked inside the UI thread using an asynchronous call.</li>
093 * </ul>
094 *
095 * @author Andres Almiray
096 * @see Threading
097 * @since 0.9.2
098 */
099 public enum Policy {
100 /**
101 * Skip threading injection
102 */
103 SKIP,
104 /**
105 * Inject execOutside wrapper
106 */
107 OUTSIDE_UITHREAD,
108 /**
109 * Inject execSync wrapper
110 */
111 INSIDE_UITHREAD_SYNC,
112 /**
113 * Inject execAsync wrapper
114 */
115 INSIDE_UITHREAD_ASYNC;
116 }
117 }
|