/*******************************************************************************
* Copyright (c) 2012, 2015 Pivotal Software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of 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.
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
***********************************************************************************/
package org.springframework.ide.eclipse.boot.launch.console;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.SubContributionManager;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsolePageParticipant;
import org.eclipse.ui.part.IPageBookViewPage;
import org.springframework.ide.eclipse.boot.core.BootActivator;
import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate;
import org.springframework.ide.eclipse.boot.launch.devtools.BootDevtoolsClientLaunchConfigurationDelegate;
import org.springframework.ide.eclipse.boot.launch.util.BootLaunchUtils;
import org.springframework.ide.eclipse.boot.ui.BootUIImages;
import org.springframework.ide.eclipse.boot.util.ProcessListenerAdapter;
import org.springframework.ide.eclipse.boot.util.ProcessTracker;
import org.springsource.ide.eclipse.commons.frameworks.core.ExceptionUtil;
/**
* @author Kris De Volder
*/
@SuppressWarnings("restriction")
public class BootConsolePageParticipant implements IConsolePageParticipant {
private class TerminateProcessAction extends Action {
@Override
public void run() {
try {
final IProcess process = console.getProcess();
if (process!=null && process.canTerminate()) {
Job job = new Job("Terminate process") {
protected IStatus run(IProgressMonitor monitor) {
try {
BootLaunchUtils.terminate(process.getLaunch());
return Status.OK_STATUS;
} catch (Exception e) {
return ExceptionUtil.status(e);
}
}
};
job.schedule();
}
} catch (Exception e) {
BootActivator.log(e);
}
}
}
private ProcessConsole console;
private ProcessTracker processTracker;
private TerminateProcessAction terminateAction;
public void activated() {
// ignore
}
public void deactivated() {
// ignore
}
public void dispose() {
if (processTracker!=null) {
processTracker.dispose();
processTracker = null;
}
}
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
return null;
}
public void init(IPageBookViewPage page, IConsole console) {
this.console = (ProcessConsole)console;
//TODO: This code works assuming that our IConsolePageParticipant is called after the
// ProcessConsolePageParticipant (which creates the action we are replacing
//When testing this that was always the case... but it may not be guaranteed.
if (isDevtoolsClient(this.console) || isBootApp(this.console)) {
terminateAction = new TerminateProcessAction();
try {
terminateAction.setImageDescriptor(BootUIImages.descriptor("icons/stop.gif"));
terminateAction.setDisabledImageDescriptor(BootUIImages.descriptor("icons/stop_disabled.gif"));
} catch (Exception e) {
BootActivator.log(e);
}
IToolBarManager toolbar = page.getSite().getActionBars().getToolBarManager();
IContributionItem replace = findReplacementItem(toolbar);
if (replace!=null) {
toolbar.appendToGroup(IConsoleConstants.LAUNCH_GROUP, terminateAction);
toolbar.remove(replace);
}
boolean enabled = getConsoleProcess().canTerminate();
terminateAction.setEnabled(enabled);
if (enabled) {
this.processTracker = new ProcessTracker(new ProcessListenerAdapter() {
@Override
public void processTerminated(ProcessTracker tracker, IProcess terminated) {
if (getConsoleProcess().equals(terminated)) {
terminateAction.setEnabled(false);
//after process is terminated... it can't come back to life so... can stop listening now.
tracker.dispose();
}
}
});
}
}
}
private boolean isDevtoolsClient(ProcessConsole console) {
return isLaunchType(console, BootDevtoolsClientLaunchConfigurationDelegate.TYPE_ID);
}
private IProcess getConsoleProcess() {
if (console!=null) {
return console.getProcess();
}
return null;
}
private boolean isBootApp(ProcessConsole console) {
return isLaunchType(console, BootLaunchConfigurationDelegate.TYPE_ID);
}
private IContributionItem findReplacementItem(IToolBarManager toolbar) {
SubContributionManager contributions = (SubContributionManager) toolbar;
for (IContributionItem item : contributions.getItems()) {
if (item instanceof ActionContributionItem) {
ActionContributionItem actionItem = (ActionContributionItem) item;
IAction replaceAction = actionItem.getAction();
if (replaceAction.getClass().getName().equals("org.eclipse.debug.internal.ui.views.console.ConsoleTerminateAction")) {
return item;
}
}
}
return null;
}
private static boolean isLaunchType(ProcessConsole console, String typeId) {
return isLaunchType(console.getProcess(), typeId);
}
private static boolean isLaunchType(IProcess process, String launchTypeId) {
try {
if (process!=null) {
ILaunch launch = process.getLaunch();
if (launch!=null) {
ILaunchConfiguration conf = launch.getLaunchConfiguration();
if (conf!=null) {
return launchTypeId.equals(conf.getType().getIdentifier());
}
}
}
} catch (Exception e) {
BootActivator.log(e);
}
return false;
}
}