001 /*
002 * SPDX-License-Identifier: Apache-2.0
003 *
004 * Copyright 2008-2018 the original author or authors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package griffon.pivot.test;
019
020 import griffon.core.GriffonApplication;
021 import griffon.exceptions.GriffonException;
022 import org.apache.pivot.wtk.Component;
023 import org.apache.pivot.wtk.Window;
024 import org.codehaus.griffon.runtime.pivot.TestDesktopPivotApplication;
025
026 import javax.annotation.Nonnull;
027 import java.awt.EventQueue;
028 import java.lang.reflect.InvocationTargetException;
029 import java.util.concurrent.CountDownLatch;
030
031 import static griffon.pivot.support.PivotUtils.findComponentByName;
032 import static griffon.util.GriffonNameUtils.requireNonBlank;
033 import static java.util.Objects.requireNonNull;
034
035 /**
036 * @author Andres Almiray
037 * @since 2.0.0
038 */
039 public class GriffonPivotFuncRule extends GriffonPivotRule {
040 private static final String ERROR_RUNNABLE_NULL = "Argument 'runnable' must not be null";
041
042 private Window window;
043
044 public GriffonPivotFuncRule() {
045 }
046
047 public GriffonPivotFuncRule(@Nonnull String[] startupArgs) {
048 super(startupArgs);
049 }
050
051 @Override
052 @SuppressWarnings("ConstantConditions")
053 protected void before(@Nonnull GriffonApplication application, @Nonnull Object target) throws Throwable {
054 application.startup();
055 application.ready();
056 TestDesktopPivotApplication.getReadyLatch().await();
057
058 window = (Window) application.getWindowManager().getStartingWindow();
059 }
060
061 @Nonnull
062 public Window getWindow() {
063 return window;
064 }
065
066 @Nonnull
067 public <T> T find(@Nonnull String name, Class<T> type) {
068 requireNonBlank(name, "Argument 'name' must not be blank");
069 requireNonNull(type, "Argument 'type' must not be null");
070
071 Component component = findComponentByName(name, window);
072 if (component != null) {
073 if (type.isAssignableFrom(component.getClass())) {
074 return type.cast(component);
075 }
076 throw new IllegalArgumentException("Could not find a component name '"
077 + name + "' with type " + type.getName()
078 + "; found type " + component.getClass().getName() + " instead");
079 }
080
081 throw new IllegalArgumentException("Could not find a component name '" + name + "' with type " + type.getName());
082 }
083
084 public void runInsideUISync(@Nonnull final Runnable runnable) {
085 requireNonNull(runnable, ERROR_RUNNABLE_NULL);
086 Throwable t = null;
087 final CountDownLatch latch = new CountDownLatch(1);
088 final Runnable worker = () -> {
089 try {
090 runnable.run();
091 } finally {
092 latch.countDown();
093 }
094 };
095 try {
096 EventQueue.invokeAndWait(worker);
097 } catch (InterruptedException e) {
098 latch.countDown();
099 t = e;
100 } catch (InvocationTargetException e) {
101 latch.countDown();
102 t = e.getTargetException();
103 }
104
105 try {
106 latch.await();
107 } catch (InterruptedException e) {
108 throw new GriffonException(e);
109 }
110
111 if (t != null) {
112 if (t instanceof AssertionError) {
113 throw (AssertionError) t;
114 } else if (t instanceof RuntimeException) {
115 throw (RuntimeException) t;
116 } else {
117 throw new GriffonException(t);
118 }
119 }
120 }
121
122 public void runInsideUIAsync(@Nonnull final Runnable runnable) {
123 requireNonNull(runnable, ERROR_RUNNABLE_NULL);
124 final Throwable[] ts = new Throwable[1];
125 final CountDownLatch latch = new CountDownLatch(1);
126 final Runnable worker = () -> {
127 try {
128 runnable.run();
129 } catch (Throwable t) {
130 ts[0] = t;
131 } finally {
132 latch.countDown();
133 }
134 };
135
136 EventQueue.invokeLater(worker);
137
138 try {
139 latch.await();
140 } catch (InterruptedException e) {
141 throw new GriffonException(e);
142 }
143
144 if (ts[0] != null) {
145 if (ts[0] instanceof AssertionError) {
146 throw (AssertionError) ts[0];
147 } else if (ts[0] instanceof RuntimeException) {
148 throw (RuntimeException) ts[0];
149 } else {
150 throw new GriffonException(ts[0]);
151 }
152 }
153 }
154 }
|