| /* |
| * Copyright 2008 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.dev; |
| |
| import com.google.gwt.core.ext.TreeLogger; |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.dev.javac.CompilationProblemReporter; |
| import com.google.gwt.dev.shell.log.SwingLoggerPanel; |
| import com.google.gwt.dev.util.log.PrintWriterTreeLogger; |
| |
| /** |
| * Used to run compiler tasks with the appropriate logger. |
| */ |
| public class CompileTaskRunner { |
| |
| /** |
| * A task to run with a logger based on options. |
| */ |
| public interface CompileTask { |
| boolean run(TreeLogger logger) throws UnableToCompleteException; |
| } |
| |
| /** |
| * Runs the main action with an appropriate logger. If a gui-based TreeLogger |
| * is used, this method will not return until its window is closed by the |
| * user. |
| */ |
| public static boolean runWithAppropriateLogger(CompileTaskOptions options, |
| final CompileTask task) { |
| // Set any platform specific system properties. |
| BootStrapPlatform.applyPlatformHacks(); |
| |
| // TODO(jat): add support for GUI logger back |
| if (false && options.isUseGuiLogger()) { |
| // Initialize a tree logger window. |
| SwingLoggerPanel loggerWindow = new SwingLoggerPanel( |
| options.getLogLevel(), null); |
| |
| // Eager AWT initialization for OS X to ensure safe coexistence with SWT. |
| BootStrapPlatform.initGui(); |
| |
| final TreeLogger logger = loggerWindow.getLogger(); |
| final boolean[] success = new boolean[1]; |
| |
| // Compiler will be spawned onto a second thread, UI thread for tree |
| // logger will remain on the main. |
| Thread compilerThread = new Thread(new Runnable() { |
| public void run() { |
| success[0] = doRun(logger, task); |
| } |
| }); |
| |
| compilerThread.setName("GWTCompiler Thread"); |
| compilerThread.start(); |
| // TODO(jat): create an app frame for loggerWindow |
| |
| // Even if the tree logger window is closed, we wait for the compiler |
| // to finish. |
| waitForThreadToTerminate(compilerThread); |
| |
| return success[0]; |
| } else { |
| // Compile tasks without -treeLogger should run headless. |
| if (System.getProperty("java.awt.headless") == null) { |
| System.setProperty("java.awt.headless", "true"); |
| } |
| PrintWriterTreeLogger logger = new PrintWriterTreeLogger(); |
| logger.setMaxDetail(options.getLogLevel()); |
| return doRun(logger, task); |
| } |
| } |
| |
| private static boolean doRun(TreeLogger logger, CompileTask task) { |
| try { |
| return task.run(logger); |
| } catch (UnableToCompleteException e) { |
| // Assume logged. |
| } catch (Throwable e) { |
| CompilationProblemReporter.logAndTranslateException(logger, e); |
| } |
| return false; |
| } |
| |
| /** |
| * Waits for a thread to terminate before it returns. This method is a |
| * non-cancellable task, in that it will defer thread interruption until it is |
| * done. |
| * |
| * @param godot the thread that is being waited on. |
| */ |
| private static void waitForThreadToTerminate(final Thread godot) { |
| // Goetz pattern for non-cancellable tasks. |
| // http://www-128.ibm.com/developerworks/java/library/j-jtp05236.html |
| boolean isInterrupted = false; |
| try { |
| while (true) { |
| try { |
| godot.join(); |
| return; |
| } catch (InterruptedException e) { |
| isInterrupted = true; |
| } |
| } |
| } finally { |
| if (isInterrupted) { |
| Thread.currentThread().interrupt(); |
| } |
| } |
| } |
| } |