Threading.java
001 /*
002  * Copyright 2008-2014 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 package griffon.transform;
017 
018 import java.lang.annotation.ElementType;
019 import java.lang.annotation.Retention;
020 import java.lang.annotation.RetentionPolicy;
021 import java.lang.annotation.Target;
022 
023 /**
024  <p>Annotates a calls or method.</p>
025  <p/>
026  * Annotated elements must follow these rules
027  <ul>
028  <li>must be a public method</li>
029  <li>name does not match an event handler</li>
030  <li>must pass {@code griffon.util.GriffonClassUtils.isPlainMethod()} if it's a method</li>
031  </ul>
032  <p/>
033  * This annotation takes {@code griffon.util.Threading.Policy} as value, with {@code Threading.Policy.OUTSIDE_UITHREAD} being
034  * the default value.<p>
035  <p/>
036  <p>The following snippet exemplifies the compactness of code when the annotation is applied </p>
037  <pre>
038  * import griffon.transform.Threading
039  *
040  * class Sample {
041  *     &#064;Threading
042  *     void doSomethingOutside(String arg) {
043  *         println "Outside $arg"
044  *     }
045  *     &#064;Threading(Threading.Policy.INSIDE_UITHREAD_SYNC)
046  *     void doSomethingInside(String arg) {
047  *         println "Inside $arg"
048  *     }
049  * }
050  </pre>
051  <p/>
052  <p>The equivalent, non-annotated code is</p>
053  <pre>
054  * import griffon.core.threading.UIThreadManager
055  *
056  * class Sample {
057  *     void doSomethingOutside(String arg) {
058  *         UIThreadManager.instance.executeOutside {
059  *             println "Outside $arg"
060  *         }
061  *     }
062  *     void doSomethingInside(String arg) {
063  *         UIThreadManager.instance.executeSync {
064  *             println "Inside $arg"
065  *         }
066  *     }
067  * }
068  </pre>
069  *
070  @author Andres Almiray
071  @see Threading.Policy
072  @since 2.0.0
073  */
074 @Retention(RetentionPolicy.RUNTIME)
075 @Target({ElementType.TYPE, ElementType.METHOD})
076 public @interface Threading {
077     Policy value() default Policy.OUTSIDE_UITHREAD;
078 
079     /**
080      * Indicates the type of threading management for a method or property.</p>
081      * The following values apply
082      <ul>
083      <li>{@code SKIP} - no threading management will be performed.</li>
084      <li>{@code OUTSIDE_UITHREAD} - code should be invoked outside of the UI thread.</li>
085      <li>{@code INSIDE_UITHREAD_SYNC} - code should be invoked inside the UI thread using a synchronous call.</li>
086      <li>{@code INSIDE_UITHREAD_ASYNC} - code should be invoked inside the UI thread using an asynchronous call.</li>
087      </ul>
088      *
089      @author Andres Almiray
090      @see Threading
091      @since 2.0.0
092      */
093     public enum Policy {
094         /**
095          * Skip threading injection
096          */
097         SKIP,
098         /**
099          * Inject execOutside wrapper
100          */
101         OUTSIDE_UITHREAD,
102         /**
103          * Inject execSync wrapper
104          */
105         INSIDE_UITHREAD_SYNC,
106         /**
107          * Inject execAsync wrapper
108          */
109         INSIDE_UITHREAD_ASYNC
110     }
111 }