/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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.dart.tools.ui.console; import com.google.dart.tools.deploy.Activator; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.internal.ui.views.console.ProcessConsole; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleListener; import org.eclipse.ui.console.IConsoleManager; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; /** * A class to manage opening and activating DartConsoleView classes in response to lifecycle events * from IConsole objects. */ @SuppressWarnings("restriction") public class DartConsoleManager implements IConsoleListener { private static DartConsoleManager manager; public static DartConsoleManager getManager() { return manager; } public static void initialize() { if (manager == null) { IConsoleManager replacementManager = new ReplacementConsoleManager(); setField(ConsolePlugin.getDefault(), "fConsoleManager", replacementManager); manager = new DartConsoleManager(); } } public static void shutdown() { if (manager != null) { manager.dispose(); manager = null; } } private static void setField(Object object, String fieldName, Object value) { try { Field field = object.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(object, value); } catch (Throwable e) { Activator.logError(e); } } private List<DartConsoleView> consoleViews = new ArrayList<DartConsoleView>(); private DartConsoleManager() { getConsoleManager().addConsoleListener(this); } @Override public void consolesAdded(IConsole[] consoles) { // If the new console is a process console, create a cooresponding view immediately - don't wait // for the first write to stdout. for (IConsole console : consoles) { if (console instanceof ProcessConsole) { warnOfContentChange(console); } } } @Override public void consolesRemoved(IConsole[] consoles) { } protected void consoleViewClosed(DartConsoleView view) { consoleViews.remove(view); } protected void consoleViewOpened(DartConsoleView view) { consoleViews.add(view); } protected void warnOfContentChange(final IConsole console) { if (console == null) { return; } if (consoleTerminated(console)) { return; } final Display display = Display.getDefault(); if (display.isDisposed()) { return; } Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (display.isDisposed()) { return; } boolean found = false; for (DartConsoleView view : consoleViews) { if (view == null) { continue; } if (console.equals(view.getConsole())) { found = true; view.warnOfContentChange(console); } } if (!found) { createConsole(console); } } }); } private boolean consoleTerminated(IConsole console) { if (console instanceof ProcessConsole) { IProcess process = ((ProcessConsole) console).getProcess(); if (process != null) { return process.isTerminated(); } } return false; } private void createConsole(IConsole console) { // There is no view open showing the given console, so: // Find a dead console and recycle it. DartConsoleView view = findDeadConsoleView(); if (view != null) { view.display(console); view.warnOfContentChange(console); } else { // Else create a new console. try { if (PlatformUI.getWorkbench() != null) { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null && window.getActivePage() != null) { view = (DartConsoleView) window.getActivePage().showView( DartConsoleView.VIEW_ID, createViewId(console), IWorkbenchPage.VIEW_VISIBLE); view.display(console); view.warnOfContentChange(console); } } } catch (PartInitException e) { Activator.logError(e); } } } private String createViewId(IConsole console) { return Integer.toString(System.identityHashCode(console)); } private void dispose() { if (getConsoleManager() != null) { getConsoleManager().removeConsoleListener(this); } } private DartConsoleView findDeadConsoleView() { for (DartConsoleView view : consoleViews) { if (view.isDead()) { return view; } } return null; } private IConsoleManager getConsoleManager() { return ConsolePlugin.getDefault().getConsoleManager(); } }