blob: 46ed276a125fd27f37555a1b7a172770a021e509 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2015, 2019 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.redocs.r.ui.processing;
import java.util.concurrent.Callable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.Image;
import org.eclipse.statet.jcommons.status.CancelStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.jcommons.ts.core.ToolRunnable;
import org.eclipse.statet.jcommons.ts.core.ToolService;
import org.eclipse.statet.ecommons.ts.ui.ToolRunnableDecorator;
import org.eclipse.statet.docmlet.base.ui.DocmlBaseUI;
import org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolOperationContext;
import org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolProcess;
import org.eclipse.statet.internal.redocs.r.Messages;
import org.eclipse.statet.nico.ui.NicoUI;
import org.eclipse.statet.nico.ui.NicoUITools;
import org.eclipse.statet.r.console.core.IRBasicAdapter;
import org.eclipse.statet.r.console.core.RConsoleTool;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.rj.services.RServiceControlExtension;
public class RConsoleOperationContext extends DocProcessingToolOperationContext {
private class RRunnable implements ToolRunnable, ToolRunnableDecorator {
public RRunnable() {
}
@Override
public String getTypeId() {
return "r/redocs/RConsoleOperation"; //$NON-NLS-1$
}
@Override
public boolean canRunIn(final Tool tool) {
return (tool.isProvidingFeatureSet(RConsoleTool.R_BASIC_FEATURESET_ID));
}
@Override
public Image getImage() {
return RConsoleOperationContext.this.toolProcess.getImage();
}
@Override
public String getLabel() {
return NLS.bind(Messages.ProcessingOperationContext_RConsole_RTask_label,
RConsoleOperationContext.this.toolProcess.getLabel() );
}
@Override
public boolean changed(final int event, final Tool tool) {
switch (event) {
case REMOVING_FROM:
case BEING_ABANDONED:
RConsoleOperationContext.this.toolProcess.log(new CancelStatus(DocmlBaseUI.BUNDLE_ID,
Messages.ProcessingOperationContext_RConsole_RTask_Canceled_label) );
cleanR();
cancel();
return true;
default:
return true;
}
}
@Override
public void run(final ToolService service, final ProgressMonitor m) throws StatusException {
initR((IRBasicAdapter) service, m);
Callable<Boolean> cancel= null;
if (service instanceof RServiceControlExtension) {
cancel= new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
RConsoleOperationContext.this.toolProcess.terminate();
return Boolean.FALSE;
}
};
((RServiceControlExtension) service).addCancelHandler(cancel);
}
try {
runInContext();
}
finally {
if (cancel != null) {
((RServiceControlExtension) service).removeCancelHandler(cancel);
cancel= null;
}
cleanR();
}
}
}
public static final String ID= "RConsole"; //$NON-NLS-1$
private DocProcessingToolProcess toolProcess;
private RProcess rProcess;
private RRunnable rRunnable;
private IRBasicAdapter rService;
private ProgressMonitor rMonitor;
public RConsoleOperationContext() {
}
@Override
public String getId() {
return ID;
}
@Override
public String getLabel() {
return Messages.ProcessingOperationContext_RConsole_label;
}
@Override
protected void start(final DocProcessingToolProcess toolProcess,
final SubMonitor m) throws CoreException {
m.beginTask("Starting doc operation(s) in R console...", 10);
if (this.toolProcess == null) {
this.toolProcess= toolProcess;
this.rProcess= getRProcess();
}
m.setTaskName("Waiting for R console...");
this.rRunnable= new RRunnable();
final Status submitStatus= this.rProcess.getQueue().add(this.rRunnable);
this.toolProcess.check(submitStatus);
}
private RProcess getRProcess() throws CoreException {
final Tool tool= NicoUI.getToolRegistry().getActiveToolSession(
this.toolProcess.getConfig().getWorkbenchPage() ).getTool();
NicoUITools.accessTool(RConsoleTool.TYPE, tool);
return (RProcess)tool;
}
@Override
public void canceling(final boolean running) {
if (this.rProcess == null) {
return;
}
if (!running) {
final RRunnable runnable= this.rRunnable;
if (runnable != null) {
this.rProcess.getQueue().remove(runnable);
}
}
final ProgressMonitor m= this.rMonitor;
if (m != null) {
m.setCanceled(true);
}
}
private void initR(final IRBasicAdapter service, final ProgressMonitor m) {
this.rService= service;
this.rMonitor= m;
}
private void cleanR() {
this.rRunnable= null;
this.rService= null;
this.rMonitor= null;
}
public IRBasicAdapter getRService() {
return this.rService;
}
public ProgressMonitor getRMonitor() {
return this.rMonitor;
}
}