Threading.java
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  *     &#064;Threading
046  *     void doSomethingOutside(String arg) {
047  *         println "Outside $arg"
048  *     }
049  *     &#064;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 }