blob: 149cfa19eac4d16026b89a5b6b2c176127f53c72 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2005, 2020 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.nico.ui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchesListener;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.ecommons.collections.FastList;
import org.eclipse.statet.ecommons.ts.ui.workbench.WorkbenchToolRegistry;
import org.eclipse.statet.ecommons.ts.ui.workbench.WorkbenchToolRegistryListener;
import org.eclipse.statet.ecommons.ts.ui.workbench.WorkbenchToolSessionData;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.nico.core.runtime.ToolProcess;
import org.eclipse.statet.nico.ui.console.NIConsole;
public class ToolRegistry implements WorkbenchToolRegistry, IPageListener {
static boolean DEBUG = false;
/**
* Prevents to run system "Show Console View" jobs when own jobs are scheduled
*/
private static class JobListener implements IJobChangeListener {
private static final String OWN_SHOWCONSOLE_NAME = PageRegistry.SHOW_CONSOLE_JOB_NAME;
private static final String OTHER_SHOWCONSOLE_NAME = "Show Console View"; //$NON-NLS-1$
private final AtomicInteger fOwnJobs = new AtomicInteger(0);
@Override
public void scheduled(final IJobChangeEvent event) {
if (event.getJob().getName() == OWN_SHOWCONSOLE_NAME) {
fOwnJobs.incrementAndGet();
}
else {
checkJob(event.getJob());
}
}
@Override
public void aboutToRun(final IJobChangeEvent event) {
checkJob(event.getJob());
}
@Override
public void done(final IJobChangeEvent event) {
if (event.getJob().getName() == OWN_SHOWCONSOLE_NAME) {
fOwnJobs.decrementAndGet();
}
}
private void checkJob(final Job eventJob) {
if (fOwnJobs.get() > 0
&& eventJob.getName() == OTHER_SHOWCONSOLE_NAME) {
eventJob.cancel();
if (DEBUG) {
System.out.println("[tool registry] show job canceled"); //$NON-NLS-1$
}
}
}
@Override
public void sleeping(final IJobChangeEvent event) {
}
@Override
public void awake(final IJobChangeEvent event) {
}
@Override
public void running(final IJobChangeEvent event) {
}
}
private class LaunchesListener implements ILaunchesListener {
@Override
public void launchesAdded(final ILaunch[] launches) {
}
@Override
public void launchesChanged(final ILaunch[] launches) {
}
@Override
public void launchesRemoved(final ILaunch[] launches) {
final List<ToolProcess> list= new ArrayList<>();
for (final ILaunch launch : launches) {
final IProcess[] processes = launch.getProcesses();
for (final IProcess process : processes) {
if (process instanceof ToolProcess) {
list.add((ToolProcess) process);
}
}
}
if (list.isEmpty()) {
return;
}
final PageRegistry[] registries = getPageRegistries();
for (final PageRegistry reg : registries) {
reg.handleConsolesRemoved(list);
}
// Because debug plugin removes only ProcessConsoles, we have to do...
removeConsoles(list);
}
private void removeConsoles(final List<ToolProcess> processes) {
final List<IConsole> toRemove= new ArrayList<>();
final IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
final IConsole[] consoles = manager.getConsoles();
for (final IConsole console : consoles) {
if ((console instanceof NIConsole) &&
processes.contains(((NIConsole) console).getProcess()) ) {
toRemove.add(console);
}
}
manager.removeConsoles(toRemove.toArray(new IConsole[toRemove.size()]));
}
}
private final Map<IWorkbenchPage, PageRegistry> fPageRegistries= new HashMap<>();
private boolean isDisposed = false;
private LaunchesListener fLaunchesListener;
private JobListener fJobListener;
private final FastList<WorkbenchToolRegistryListener> fListenersWorkbench= new FastList<>(WorkbenchToolRegistryListener.class, FastList.IDENTITY);
public ToolRegistry() {
fLaunchesListener = new LaunchesListener();
fJobListener = new JobListener();
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(fLaunchesListener);
Job.getJobManager().addJobChangeListener(fJobListener);
}
public void dispose() {
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(fLaunchesListener);
synchronized (fPageRegistries) {
fLaunchesListener = null;
for (final IWorkbenchPage page : fPageRegistries.keySet()) {
page.getWorkbenchWindow().removePageListener(this);
final PageRegistry reg = fPageRegistries.get(page);
reg.dispose();
}
fPageRegistries.clear();
isDisposed = true;
}
Job.getJobManager().addJobChangeListener(fJobListener);
fJobListener = null;
if (DEBUG) {
System.out.println("[tool registry] registry closed."); //$NON-NLS-1$
}
}
@Override
public void pageOpened(final IWorkbenchPage page) {
}
@Override
public void pageActivated(final IWorkbenchPage page) {
}
@Override
public void pageClosed(final IWorkbenchPage page) {
PageRegistry reg;
synchronized (fPageRegistries) {
page.getWorkbenchWindow().removePageListener(this);
reg = fPageRegistries.remove(page);
}
reg.dispose();
}
private PageRegistry getPageRegistry(final IWorkbenchPage page) {
if (page == null) {
return null;
}
synchronized (fPageRegistries) {
PageRegistry reg = fPageRegistries.get(page);
if (reg == null) {
if (this.isDisposed) {
return null;
}
final IWorkbenchWindow window= page.getWorkbenchWindow();
if (window == null) {
return null;
}
window.addPageListener(this);
final WorkbenchToolRegistryListener[] listeners = fListenersWorkbench.toArray();
reg = new PageRegistry(page, listeners);
fPageRegistries.put(page, reg);
}
return reg;
}
}
private PageRegistry[] getPageRegistries() {
synchronized (fPageRegistries) {
final Collection<PageRegistry> collection = fPageRegistries.values();
return collection.toArray(new PageRegistry[collection.size()]);
}
}
@Override
public void addListener(final WorkbenchToolRegistryListener listener, final IWorkbenchPage page) {
if (page == null) {
fListenersWorkbench.add(listener);
}
final PageRegistry reg = getPageRegistry(page);
if (reg != null) {
reg.fListeners.add(listener);
}
}
@Override
public void removeListener(final WorkbenchToolRegistryListener listener) {
fListenersWorkbench.remove(listener);
synchronized (fPageRegistries) {
for (final PageRegistry reg : fPageRegistries.values()) {
reg.fListeners.remove(listener);
}
}
}
public void consoleActivated(final IConsoleView consoleView, final NIConsole console) {
final IWorkbenchPage page = consoleView.getViewSite().getPage();
final PageRegistry reg = getPageRegistry(page);
if (reg != null) {
reg.handleActiveConsoleChanged(console, consoleView);
}
}
@Override
public WorkbenchToolSessionData getActiveToolSession(final IWorkbenchPage page) {
if (page == null) {
return null;
}
final PageRegistry reg = getPageRegistry(page);
if (reg != null) {
return reg.createSessionInfo(null);
}
return null;
}
@Override
public IWorkbenchPage findWorkbenchPage(final Tool process) {
final IWorkbenchPage activePage = UIAccess.getActiveWorkbenchPage(false);
IWorkbenchPage page = null;
synchronized (fPageRegistries) {
for (final PageRegistry reg : fPageRegistries.values()) {
if (reg.getActiveProcess() == process) {
page = reg.getPage();
if (page == activePage) {
return page;
}
}
}
}
if (page != null) {
return page;
}
return activePage;
}
public IConsoleView getConsoleView(final NIConsole console, final IWorkbenchPage page) {
final PageRegistry reg = getPageRegistry(page);
if (reg != null) {
return reg.getConsoleView(console);
}
return null;
}
public void showConsole(final NIConsole console, final IWorkbenchPage page,
final boolean activate) {
final PageRegistry reg = getPageRegistry(page);
if (reg != null) {
reg.showConsole(console, activate);
}
}
public void showConsoleExplicitly(final NIConsole console, final IWorkbenchPage page,
final boolean pin) {
final PageRegistry reg = getPageRegistry(page);
if (reg != null) {
reg.showConsoleExplicitly(console, pin);
}
}
}