GriffonPivotFuncRule.java
001 /*
002  * Copyright 2008-2016 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.pivot.test;
017 
018 import griffon.core.GriffonApplication;
019 import griffon.exceptions.GriffonException;
020 import org.apache.pivot.wtk.Component;
021 import org.apache.pivot.wtk.Window;
022 import org.codehaus.griffon.runtime.pivot.TestDesktopPivotApplication;
023 
024 import javax.annotation.Nonnull;
025 import java.awt.EventQueue;
026 import java.lang.reflect.InvocationTargetException;
027 import java.util.concurrent.CountDownLatch;
028 
029 import static griffon.pivot.support.PivotUtils.findComponentByName;
030 import static griffon.util.GriffonNameUtils.requireNonBlank;
031 import static java.util.Objects.requireNonNull;
032 
033 /**
034  @author Andres Almiray
035  @since 2.0.0
036  */
037 public class GriffonPivotFuncRule extends GriffonPivotRule {
038     private static final String ERROR_RUNNABLE_NULL = "Argument 'runnable' must not be null";
039 
040     private Window window;
041 
042     public GriffonPivotFuncRule() {
043     }
044 
045     public GriffonPivotFuncRule(@Nonnull String[] startupArgs) {
046         super(startupArgs);
047     }
048 
049     @Override
050     @SuppressWarnings("ConstantConditions")
051     protected void before(@Nonnull GriffonApplication application, @Nonnull Object targetthrows Throwable {
052         application.startup();
053         application.ready();
054         TestDesktopPivotApplication.getReadyLatch().await();
055 
056         window = (Windowapplication.getWindowManager().getStartingWindow();
057     }
058 
059     @Nonnull
060     public Window getWindow() {
061         return window;
062     }
063 
064     @Nonnull
065     public <T> T find(@Nonnull String name, Class<T> type) {
066         requireNonBlank(name, "Argument 'name' must not be blank");
067         requireNonNull(type, "Argument 'type' must not be null");
068 
069         Component component = findComponentByName(name, window);
070         if (component != null) {
071             if (type.isAssignableFrom(component.getClass())) {
072                 return type.cast(component);
073             }
074             throw new IllegalArgumentException("Could not find a component name '"
075                 + name + "' with type " + type.getName()
076                 "; found type " + component.getClass().getName() " instead");
077         }
078 
079         throw new IllegalArgumentException("Could not find a component name '" + name + "' with type " + type.getName());
080     }
081 
082     public void runInsideUISync(final @Nonnull Runnable runnable) {
083         requireNonNull(runnable, ERROR_RUNNABLE_NULL);
084         Throwable t = null;
085         final CountDownLatch latch = new CountDownLatch(1);
086         final Runnable worker = new Runnable() {
087             @Override
088             public void run() {
089                 try {
090                     runnable.run();
091                 finally {
092                     latch.countDown();
093                 }
094             }
095         };
096         try {
097             EventQueue.invokeAndWait(worker);
098         catch (InterruptedException e) {
099             latch.countDown();
100             t = e;
101         catch (InvocationTargetException e) {
102             latch.countDown();
103             t = e.getTargetException();
104         }
105 
106         try {
107             latch.await();
108         catch (InterruptedException e) {
109             throw new GriffonException(e);
110         }
111 
112         if (t != null) {
113             if (instanceof AssertionError) {
114                 throw (AssertionErrort;
115             else if (instanceof RuntimeException) {
116                 throw (RuntimeExceptiont;
117             else {
118                 throw new GriffonException(t);
119             }
120         }
121     }
122 
123     public void runInsideUIAsync(final @Nonnull Runnable runnable) {
124         requireNonNull(runnable, ERROR_RUNNABLE_NULL);
125         final Throwable[] ts = new Throwable[1];
126         final CountDownLatch latch = new CountDownLatch(1);
127         final Runnable worker = new Runnable() {
128             @Override
129             public void run() {
130                 try {
131                     runnable.run();
132                 catch (Throwable t) {
133                     ts[0= t;
134                 finally {
135                     latch.countDown();
136                 }
137             }
138         };
139 
140         EventQueue.invokeLater(worker);
141 
142         try {
143             latch.await();
144         catch (InterruptedException e) {
145             throw new GriffonException(e);
146         }
147 
148         if (ts[0!= null) {
149             if (ts[0instanceof AssertionError) {
150                 throw (AssertionErrorts[0];
151             else if (ts[0instanceof RuntimeException) {
152                 throw (RuntimeExceptionts[0];
153             else {
154                 throw new GriffonException(ts[0]);
155             }
156         }
157     }
158 }