1 /******************************************************************************* 2 * Copyright (c) 2011 Google, Inc. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Google, Inc. - initial API and implementation 10 *******************************************************************************/ 11 package org.eclipse.wb.internal.core.utils.execution; 12 13 import org.eclipse.swt.widgets.Display; 14 import org.eclipse.wb.internal.core.DesignerPlugin; 15 import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils; 16 17 import java.beans.Beans; 18 19 /** 20 * Utilities for executing actions, such as {@link RunnableEx}. 21 * 22 * @author scheglov_ke 23 * @coverage core.util 24 */ 25 public class ExecutionUtils { 26 //////////////////////////////////////////////////////////////////////////// 27 // 28 // Constructor 29 // 30 //////////////////////////////////////////////////////////////////////////// 31 private ExecutionUtils() { 32 } 33 34 //////////////////////////////////////////////////////////////////////////// 35 // 36 // Sleep 37 // 38 //////////////////////////////////////////////////////////////////////////// 39 /** 40 * Sleeps given number of milliseconds, ignoring exceptions. 41 */ 42 public static void sleep(final int millis) { 43 runIgnore(new RunnableEx() { 44 @Override 45 public void run() throws Exception { 46 Thread.sleep(millis); 47 } 48 }); 49 } 50 51 /** 52 * Waits given number of milliseconds and runs events loop every 1 millisecond. At least one 53 * events loop will be executed. If current thread is not UI thread, then this method works just 54 * as {@link #sleep(int)}. 55 */ 56 public static void waitEventLoop(int millis) { 57 Display display = Display.getCurrent(); 58 if (display != null) { 59 long nanos = millis * 1000000L; 60 long start = System.nanoTime(); 61 do { 62 sleep(0); 63 while (display.readAndDispatch()) { 64 // do nothing 65 } 66 } while (System.nanoTime() - start < nanos); 67 } else { 68 sleep(millis); 69 } 70 } 71 72 //////////////////////////////////////////////////////////////////////////// 73 // 74 // void 75 // 76 //////////////////////////////////////////////////////////////////////////// 77 /** 78 * Runs given {@link RunnableEx} and ignores exceptions. 79 * 80 * @return <code>true</code> if execution was finished without exception. 81 */ 82 public static boolean runIgnore(RunnableEx runnable) { 83 try { 84 runnable.run(); 85 return true; 86 } catch (Throwable e) { 87 return false; 88 } 89 } 90 91 /** 92 * Runs given {@link RunnableEx} and logs exceptions using {@link DesignerPlugin#log(Throwable)}. 93 * 94 * @return <code>true</code> if execution was finished without exception. 95 */ 96 public static boolean runLog(RunnableEx runnable) { 97 try { 98 runnable.run(); 99 return true; 100 } catch (Throwable e) { 101 DesignerPlugin.log(e); 102 return false; 103 } 104 } 105 106 /** 107 * Runs given {@link RunnableEx} and re-throws exceptions using {@link RuntimeException}. 108 */ 109 public static void runRethrow(RunnableEx runnable) { 110 try { 111 runnable.run(); 112 } catch (Throwable e) { 113 throw ReflectionUtils.propagate(e); 114 } 115 } 116 117 /** 118 * Runs given {@link RunnableEx} and re-throws exceptions using {@link RuntimeException}. 119 */ 120 public static void runRethrow(RunnableEx runnable, String format, Object... args) { 121 try { 122 runnable.run(); 123 } catch (Throwable e) { 124 String message = String.format(format, args); 125 throw new RuntimeException(message, e); 126 } 127 } 128 129 /** 130 * Ensures that {@link Beans#isDesignTime()} returns <code>true</code> and runs given 131 * {@link RunnableEx}. 132 */ 133 public static void runDesignTime(RunnableEx runnable) throws Exception { 134 boolean old_designTime = Beans.isDesignTime(); 135 try { 136 Beans.setDesignTime(true); 137 runnable.run(); 138 } finally { 139 Beans.setDesignTime(old_designTime); 140 } 141 } 142 143 /** 144 * Ensures that {@link Beans#isDesignTime()} returns <code>true</code> and runs given 145 * {@link RunnableEx}. 146 */ 147 public static <T> T runDesignTime(RunnableObjectEx<T> runnable) throws Exception { 148 boolean old_designTime = Beans.isDesignTime(); 149 try { 150 Beans.setDesignTime(true); 151 return runnable.runObject(); 152 } finally { 153 Beans.setDesignTime(old_designTime); 154 } 155 } 156 157 //////////////////////////////////////////////////////////////////////////// 158 // 159 // UI 160 // 161 //////////////////////////////////////////////////////////////////////////// 162 /** 163 * Runs given {@link RunnableEx} inside of UI thread, using {@link Display#syncExec(Runnable)}. 164 * 165 * @return <code>true</code> if {@link RunnableEx} was executed without any {@link Exception}. 166 */ 167 public static boolean runLogUI(final RunnableEx runnable) { 168 final boolean[] success = new boolean[1]; 169 Display.getDefault().syncExec(new Runnable() { 170 @Override 171 public void run() { 172 success[0] = ExecutionUtils.runLog(runnable); 173 } 174 }); 175 return success[0]; 176 } 177 178 /** 179 * Runs given {@link RunnableEx} inside of UI thread, using {@link Display#syncExec(Runnable)}. 180 */ 181 public static void runRethrowUI(final RunnableEx runnable) { 182 Display.getDefault().syncExec(new Runnable() { 183 @Override 184 public void run() { 185 ExecutionUtils.runRethrow(runnable); 186 } 187 }); 188 } 189 190 /** 191 * Runs given {@link RunnableEx} within UI thread using {@link Display#asyncExec(Runnable)}. Logs 192 * a {@link Throwable} which may occur. 193 */ 194 public static void runAsync(final RunnableEx runnable) { 195 Display.getDefault().asyncExec(new Runnable() { 196 @Override 197 public void run() { 198 ExecutionUtils.runLog(runnable); 199 } 200 }); 201 } 202 203 /** 204 * Runs given {@link RunnableEx} inside of UI thread, using {@link Display#syncExec(Runnable)}. 205 */ 206 @SuppressWarnings("unchecked") 207 public static <T> T runObjectUI(final RunnableObjectEx<T> runnable) { 208 final Object[] result = new Object[1]; 209 runRethrowUI(new RunnableEx() { 210 @Override 211 public void run() throws Exception { 212 result[0] = runObject(runnable); 213 } 214 }); 215 return (T) result[0]; 216 } 217 218 /** 219 * Runs given {@link RunnableEx} as {@link #runLog(RunnableEx)}, but using 220 * {@link Display#asyncExec(Runnable)}. 221 */ 222 public static void runLogLater(final RunnableEx runnable) { 223 Display.getDefault().asyncExec(new Runnable() { 224 @Override 225 public void run() { 226 ExecutionUtils.runLog(runnable); 227 } 228 }); 229 } 230 231 //////////////////////////////////////////////////////////////////////////// 232 // 233 // Object 234 // 235 //////////////////////////////////////////////////////////////////////////// 236 /** 237 * Runs given {@link RunnableEx} and re-throws exceptions using {@link RuntimeException}. 238 * 239 * @return the {@link Object} returned by {@link RunnableEx#run()}. 240 */ 241 public static <T> T runObject(RunnableObjectEx<T> runnable) { 242 try { 243 return runnable.runObject(); 244 } catch (Throwable e) { 245 throw ReflectionUtils.propagate(e); 246 } 247 } 248 249 /** 250 * Runs given {@link RunnableEx} and re-throws exceptions using {@link RuntimeException}. 251 * 252 * @return the {@link Object} returned by {@link RunnableEx#run()}. 253 */ 254 public static <T> T runObject(RunnableObjectEx<T> runnable, String format, Object... args) { 255 try { 256 return runnable.runObject(); 257 } catch (Throwable e) { 258 String message = String.format(format, args); 259 throw new Error(message, e); 260 } 261 } 262 263 /** 264 * Runs given {@link RunnableEx} and ignores exceptions. 265 * 266 * @return the {@link Object} returned by {@link RunnableEx#run()} or <code>defaultValue</code> if 267 * exception happened. 268 */ 269 public static <T> T runObjectIgnore(RunnableObjectEx<T> runnable, T defaultValue) { 270 try { 271 return runnable.runObject(); 272 } catch (Throwable e) { 273 return defaultValue; 274 } 275 } 276 277 /** 278 * Runs given {@link RunnableEx} and logs exceptions using {@link DesignerPlugin#log(Throwable)}. 279 * 280 * @return the {@link Object} returned by {@link RunnableEx#run()} or <code>defaultValue</code> if 281 * exception was logged. 282 */ 283 public static <T> T runObjectLog(RunnableObjectEx<T> runnable, T defaultValue) { 284 try { 285 return runnable.runObject(); 286 } catch (Throwable e) { 287 DesignerPlugin.log(e); 288 return defaultValue; 289 } 290 } 291 292 } 293