org.springframework.ide.eclipse.boot.launch.console.BootConsolePageParticipant.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.boot.launch.console.BootConsolePageParticipant.java

Source

/*******************************************************************************
 * 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;
    }

}