| /*=============================================================================# |
| # Copyright (c) 2008, 2017 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.redocs.tex.r.ui.processing; |
| |
| import static org.eclipse.statet.docmlet.base.ui.processing.DocProcessingOperation.NO_SETTINGS; |
| import static org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolConfig.StepConfig.RUN_DEFAULT; |
| import static org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolConfig.StepConfig.RUN_EXPLICITE; |
| import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.BUILDTEX_TYPE_ECLIPSE; |
| import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.BUILDTEX_TYPE_RCONSOLE; |
| import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.SWEAVE_TYPE_RCMD; |
| import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.SWEAVE_TYPE_RCONSOLE; |
| import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.VARNAME_LATEX_FILE; |
| import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.VARNAME_OUTPUT_FILE; |
| import static org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.VARNAME_SWEAVE_FILE; |
| |
| import java.util.concurrent.Callable; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceRuleFactory; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.debug.core.DebugException; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.core.model.ILaunchConfigurationDelegate; |
| import org.eclipse.debug.core.model.IProcess; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.texlipse.TexPathConfig; |
| import org.eclipse.texlipse.Texlipse; |
| import org.eclipse.texlipse.builder.AbstractBuilder; |
| import org.eclipse.texlipse.builder.Builder; |
| import org.eclipse.texlipse.builder.TexlipseBuilder; |
| import org.eclipse.texlipse.viewer.ViewerConfiguration; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| |
| import org.eclipse.statet.ecommons.debug.core.util.LaunchUtils; |
| import org.eclipse.statet.ecommons.io.FileUtil; |
| import org.eclipse.statet.ecommons.io.FileValidator; |
| import org.eclipse.statet.ecommons.ts.core.Tool; |
| import org.eclipse.statet.ecommons.ts.core.ToolRunnable; |
| import org.eclipse.statet.ecommons.ts.core.ToolService; |
| import org.eclipse.statet.ecommons.variables.core.VariableText; |
| import org.eclipse.statet.ecommons.variables.core.VariableText.LocationProcessor; |
| |
| import org.eclipse.statet.docmlet.base.ui.processing.DocProcessingToolProcess; |
| import org.eclipse.statet.docmlet.base.ui.processing.operations.OpenUsingEclipseOperation; |
| import org.eclipse.statet.internal.redocs.tex.r.ui.processing.TexRweaveLaunchDelegate.Config; |
| import org.eclipse.statet.nico.core.runtime.IRequireSynch; |
| import org.eclipse.statet.nico.core.runtime.ToolProcess; |
| import org.eclipse.statet.nico.core.runtime.ToolWorkspace; |
| 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.core.RUtil; |
| import org.eclipse.statet.redocs.tex.r.ui.TexRweaveUI; |
| import org.eclipse.statet.rj.services.RServiceControlExtension; |
| |
| |
| class TexRweaveProcessToolProcess extends DocProcessingToolProcess { |
| |
| |
| private static final int TICKS_PREPARER= 5; |
| private static final int TICKS_RWEAVE= 30; |
| private static final int TICKS_TEX= 30; |
| private static final int TICKS_OPEN_TEX= 5; |
| private static final int TICKS_OPEN_OUTPUT= 20; |
| private static final int TICKS_REST= 10; |
| |
| |
| public static final ImList<String> SWEAVE_FOLDER_VARNAMES= ImCollections.newList( |
| VARNAME_SWEAVE_FILE ); |
| public static final ImList<String> SWEAVE_COMMAND_VARNAMES= ImCollections.newList( |
| VARNAME_SWEAVE_FILE, VARNAME_LATEX_FILE, VARNAME_OUTPUT_FILE ); |
| public static final ImList<String> OUTPUT_DIR_VARNAMES= ImCollections.newList( |
| VARNAME_SWEAVE_FILE, VARNAME_LATEX_FILE ); |
| public static final ImList<String> TEX_COMMAND_VARNAMES= ImCollections.newList( |
| VARNAME_SWEAVE_FILE, VARNAME_LATEX_FILE, VARNAME_OUTPUT_FILE ); |
| |
| |
| private class R implements ToolRunnable { |
| |
| |
| public static final int TASK_FINISHED= 1; |
| public static final int TASK_PREPARE_TEX= 2; |
| |
| private int task= 0; |
| |
| |
| R() { |
| } |
| |
| @Override |
| public String getTypeId() { |
| return "r/sweave/commands"; //$NON-NLS-1$ |
| } |
| |
| @Override |
| public boolean canRunIn(final Tool tool) { |
| return (tool.isProvidingFeatureSet(RConsoleTool.R_BASIC_FEATURESET_ID)); |
| } |
| |
| @Override |
| public String getLabel() { |
| return NLS.bind(Messages.RweaveTexProcessing_Sweave_Task_label, getConfig().getSourceFile().getName()); |
| } |
| |
| @Override |
| public boolean changed(final int event, final Tool tool) { |
| switch (event) { |
| case REMOVING_FROM: |
| case BEING_ABANDONED: |
| getStatus().add(new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, -1, |
| Messages.RweaveTexProcessing_Sweave_Task_info_Canceled_message, null)); |
| continueAfterR(); |
| break; |
| // finishing handled in run |
| } |
| return true; |
| } |
| |
| @Override |
| public void run(final ToolService service, |
| final IProgressMonitor monitor) throws CoreException { |
| final IRBasicAdapter r= (IRBasicAdapter) service; |
| TexRweaveProcessToolProcess.this.fProgress2= monitor; |
| Callable<Boolean> cancel= null; |
| if (r instanceof RServiceControlExtension) { |
| cancel= new Callable<Boolean>() { |
| @Override |
| public Boolean call() throws Exception { |
| terminate(); |
| return Boolean.FALSE; |
| } |
| }; |
| ((RServiceControlExtension) r).addCancelHandler(cancel); |
| } |
| try { |
| if (checkExit(0)) { |
| return; |
| } |
| |
| final ToolWorkspace workspace= r.getWorkspaceData(); |
| if (TexRweaveProcessToolProcess.this.fWorkingFolder == null) { |
| r.refreshWorkspaceData(0, monitor); |
| updatePathInformations(r.getWorkspaceData()); |
| } |
| else { |
| String path= workspace.toToolPath(TexRweaveProcessToolProcess.this.fWorkingFolder); |
| path= RUtil.escapeBackslash(path); |
| r.submitToConsole("setwd(\""+path+"\")", monitor); //$NON-NLS-1$ //$NON-NLS-2$ |
| r.refreshWorkspaceData(0, monitor); |
| if (!TexRweaveProcessToolProcess.this.fWorkingFolder.equals(workspace.getWorkspaceDir())) { |
| getStatus().add(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, |
| "Failed to set the R working directory." )); |
| } |
| } |
| |
| if (checkExit(0)) { |
| return; |
| } |
| |
| final LocationProcessor processor= new LocationProcessor() { |
| @Override |
| public String process(String path) throws CoreException { |
| final IFileStore store= FileUtil.getFileStore(path); |
| path= workspace.toToolPath(store); |
| path= RUtil.escapeBackslash(path); |
| return path; |
| } |
| }; |
| |
| if (getConfig().weave.isRun() && TexRweaveProcessToolProcess.this.fSweaveType == SWEAVE_TYPE_RCONSOLE) { |
| monitor.subTask("Sweave"); //$NON-NLS-1$ |
| final SubMonitor progress= TexRweaveProcessToolProcess.this.fProgress.newChild(TICKS_RWEAVE); |
| progress.beginTask(Messages.RweaveTexProcessing_Sweave_InConsole_label, 100); |
| |
| try { |
| TexRweaveProcessToolProcess.this.fSweaveRCommands.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString()); |
| TexRweaveProcessToolProcess.this.fSweaveRCommands.set(VARNAME_LATEX_FILE, TexRweaveProcessToolProcess.this.fTexFile.getFullPath().toString()); |
| TexRweaveProcessToolProcess.this.fSweaveRCommands.set(VARNAME_OUTPUT_FILE, TexRweaveProcessToolProcess.this.fTexPathConfig.getOutputFile().getFullPath().toString()); |
| TexRweaveProcessToolProcess.this.fSweaveRCommands.performFinalStringSubstitution(processor); |
| } |
| catch (final NullPointerException e) { |
| throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, |
| Messages.RweaveTexProcessing_Sweave_error_ResourceVariable_message)); |
| } |
| catch (final CoreException e) { |
| throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, |
| Messages.RweaveTexProcessing_Sweave_error_ResourceVariable_message + ' ' + e.getLocalizedMessage())); |
| } |
| final String[] commands= RUtil.LINE_SEPARATOR_PATTERN.split(TexRweaveProcessToolProcess.this.fSweaveRCommands.getText()); |
| for (int i= 0; i < commands.length; i++) { |
| r.submitToConsole(commands[i], monitor); |
| } |
| if (r instanceof IRequireSynch) { |
| ((IRequireSynch) r).synch(monitor); |
| } |
| } |
| |
| if (getConfig().produce.isRun() && TexRweaveProcessToolProcess.this.fTexType == BUILDTEX_TYPE_RCONSOLE) { |
| monitor.subTask("LaTeX"); //$NON-NLS-1$ |
| if (checkExit(0)) { |
| return; |
| } |
| |
| waitTask(TASK_PREPARE_TEX); |
| if (checkExit(0) || this.task < 0) { |
| return; |
| } |
| |
| final SubMonitor progress= TexRweaveProcessToolProcess.this.fProgress.newChild(TICKS_TEX); |
| progress.beginTask(Messages.RweaveTexProcessing_Tex_label, 100); |
| |
| try { |
| TexRweaveProcessToolProcess.this.fTexRCommands.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString()); |
| TexRweaveProcessToolProcess.this.fTexRCommands.set(VARNAME_LATEX_FILE, TexRweaveProcessToolProcess.this.fTexFile.getFullPath().toString()); |
| TexRweaveProcessToolProcess.this.fTexRCommands.set(VARNAME_OUTPUT_FILE, TexRweaveProcessToolProcess.this.fTexPathConfig.getOutputFile().getFullPath().toString()); |
| TexRweaveProcessToolProcess.this.fTexRCommands.performFinalStringSubstitution(processor); |
| progress.setWorkRemaining(90); |
| } |
| catch (final NullPointerException e) { |
| throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, |
| Messages.RweaveTexProcessing_Tex_error_ResourceVariable_message)); |
| } |
| catch (final CoreException e) { |
| throw new CoreException(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, |
| Messages.RweaveTexProcessing_Tex_error_ResourceVariable_message + ' ' + e.getLocalizedMessage())); |
| } |
| |
| Texlipse.getViewerManager().closeDocInViewer(TexRweaveProcessToolProcess.this.fTexPathConfig); |
| |
| final String[] commands= RUtil.LINE_SEPARATOR_PATTERN.split(TexRweaveProcessToolProcess.this.fTexRCommands.getText()); |
| for (int i= 0; i < commands.length; i++) { |
| r.submitToConsole(commands[i], monitor); |
| progress.setWorkRemaining(90-80/commands.length*(i+1)); |
| } |
| if (r instanceof IRequireSynch) { |
| ((IRequireSynch) r).synch(monitor); |
| } |
| } |
| } |
| catch (final CoreException e) { |
| getStatus().add(e.getStatus()); |
| throw e; |
| } |
| finally { |
| if (cancel != null) { |
| ((RServiceControlExtension) r).removeCancelHandler(cancel); |
| cancel= null; |
| } |
| continueAfterR(); |
| TexRweaveProcessToolProcess.this.fProgress2= null; |
| } |
| |
| } |
| |
| private void updatePathInformations(final ToolWorkspace workspace) { |
| final IFileStore wd= workspace.getWorkspaceDir(); |
| final IStatus status= setWorkingDir(wd, null, true); |
| if (status.getSeverity() > IStatus.OK) { |
| getStatus().add(status); |
| } |
| } |
| |
| private synchronized void waitTask(final int task) { |
| this.task= task; |
| while (this.task == task) { |
| notifyAll(); |
| try { |
| this.wait(); |
| } |
| catch (final InterruptedException e) { |
| } |
| } |
| } |
| |
| private synchronized void continueAfterR() { |
| this.task= TASK_FINISHED; |
| notifyAll(); |
| } |
| |
| } |
| |
| private SubMonitor fProgress; |
| private IProgressMonitor fProgress2; |
| |
| private IContainer fWorkingFolderInWorkspace; |
| private IFileStore fWorkingFolder; |
| private String fBaseFileName; |
| private String fTexFileExtension; |
| |
| private int fSweaveType; |
| private VariableText fSweaveRCommands; |
| private ILaunchConfiguration fSweaveConfig; |
| |
| private String fOutputFormat; |
| private VariableText fOutputDir; |
| private boolean fOutputInitialized; |
| |
| private IFile fTexFile; |
| int fTexOpenEditor= 0; |
| private int fTexType; |
| private Builder fTexBuilder; |
| private VariableText fTexRCommands; |
| private TexPathConfig fTexPathConfig; |
| |
| ViewerConfiguration fPreviewConfig; |
| |
| |
| public TexRweaveProcessToolProcess(final ILaunch launch, final TexRweaveLaunchDelegate.Config config) { |
| super(launch, config); |
| } |
| |
| |
| @Override |
| public TexRweaveLaunchDelegate.Config getConfig() { |
| return (TexRweaveLaunchDelegate.Config) super.getConfig(); |
| } |
| |
| public void setWorkingDir(final VariableText wd) throws CoreException { |
| wd.performInitialStringSubstitution(true); |
| wd.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString()); |
| wd.performFinalStringSubstitution(null); |
| |
| final FileValidator validator= new FileValidator(false); |
| validator.setResourceLabel("Sweave Working / Output Folder"); |
| validator.setOnFile(IStatus.ERROR); |
| validator.setOnExisting(IStatus.OK); |
| validator.setOnNotExisting(IStatus.ERROR); |
| validator.setRequireWorkspace(true, true); |
| { final IStatus status= validator.validate(wd.getText()); |
| if (!status.isOK()) { |
| throw new CoreException(status); |
| } |
| } |
| { final IStatus status= setWorkingDir(null, (IContainer) validator.getWorkspaceResource(), true); |
| if (!status.isOK()) { |
| throw new CoreException(status); |
| } |
| } |
| } |
| |
| public void setSweave(final VariableText rCommands) throws CoreException { |
| if (this.fSweaveType > 0 || rCommands == null) { |
| throw new IllegalArgumentException(); |
| } |
| this.fSweaveType= SWEAVE_TYPE_RCONSOLE; |
| this.fSweaveRCommands= rCommands; |
| this.fSweaveRCommands.performInitialStringSubstitution(true); |
| } |
| |
| public void setSweave(final ILaunchConfiguration rCmd) { |
| if (this.fSweaveType > 0 || rCmd == null) { |
| throw new IllegalArgumentException(); |
| } |
| this.fSweaveType= SWEAVE_TYPE_RCMD; |
| this.fSweaveConfig= rCmd; |
| } |
| |
| public void setOutput(final VariableText directory, final String format) throws CoreException { |
| this.fOutputDir= directory; |
| this.fOutputDir.performInitialStringSubstitution(true); |
| this.fOutputFormat= format; |
| |
| if (this.fWorkingFolder != null && !this.fOutputInitialized) { |
| final IStatus status= initOutputDir(); |
| if (!status.isOK()) { |
| throw new CoreException(status); |
| } |
| } |
| } |
| |
| public void setBuildTex(final VariableText commands) throws CoreException { |
| if (this.fTexType > 0 || commands == null) { |
| throw new IllegalArgumentException(); |
| } |
| this.fTexType= BUILDTEX_TYPE_RCONSOLE; |
| this.fTexRCommands= commands; |
| this.fTexRCommands.performInitialStringSubstitution(true); |
| } |
| |
| public void setBuildTex(final Builder texBuilder) { |
| if (this.fTexType > 0 || texBuilder == null) { |
| throw new IllegalArgumentException(); |
| } |
| this.fTexType= BUILDTEX_TYPE_ECLIPSE; |
| this.fTexBuilder= texBuilder; |
| } |
| |
| |
| public IStatus setWorkingDir(final IFileStore efsFolder, final IContainer workspaceFolder, final boolean synch) { |
| this.fWorkingFolder= efsFolder; |
| this.fWorkingFolderInWorkspace= workspaceFolder; |
| if (synch) { |
| if (this.fWorkingFolder == null && this.fWorkingFolderInWorkspace != null) { |
| this.fWorkingFolder= EFS.getLocalFileSystem().getStore(this.fWorkingFolderInWorkspace.getLocation()); |
| } |
| else if (this.fWorkingFolder != null && this.fWorkingFolderInWorkspace == null) { |
| final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); |
| final IContainer[] found= root.findContainersForLocationURI(this.fWorkingFolder.toURI()); |
| for (int i= 0; i < found.length; i++) { |
| if (found[i].getType() == IResource.PROJECT || found[i].getType() == IResource.FOLDER) { |
| this.fWorkingFolderInWorkspace= found[i]; |
| break; |
| } |
| } |
| } |
| } |
| if (this.fWorkingFolderInWorkspace == null) { |
| doSetExitValue(11); |
| return new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1, |
| Messages.RweaveTexProcessing_Tex_error_MustBeInWorkspace_message, null); |
| } |
| |
| if (this.fBaseFileName == null) { |
| this.fBaseFileName= getConfig().getSourceFile().getName(); |
| final int idx= this.fBaseFileName.lastIndexOf('.'); |
| if (idx >= 0) { |
| this.fBaseFileName= this.fBaseFileName.substring(0, idx); |
| } |
| } |
| |
| if (this.fTexFileExtension == null) { |
| this.fTexFileExtension= "tex"; //$NON-NLS-1$ |
| } |
| this.fTexFile= this.fWorkingFolderInWorkspace.getFile(new Path(this.fBaseFileName + '.' + this.fTexFileExtension)); |
| |
| if (this.fOutputDir != null && !this.fOutputInitialized) { |
| return initOutputDir(); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| private IStatus initOutputDir() { |
| this.fOutputInitialized= true; |
| final String texFilePath= this.fTexFile.getFullPath().toString(); |
| this.fOutputDir.set(VARNAME_SWEAVE_FILE, getConfig().getSourceFile().getFullPath().toString()); |
| this.fOutputDir.set(VARNAME_LATEX_FILE, texFilePath); |
| |
| // 21x |
| if (this.fOutputFormat == null) { |
| return new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1, |
| Messages.RweaveTexProcessing_Tex_error_BuilderNotConfigured_message, null ); |
| } |
| final IContainer outputDir; |
| try { |
| outputDir= TexPathConfig.resolveDirectory(this.fOutputDir.getText(), this.fTexFile, getConfig().getSourceFile()); |
| } |
| catch (final CoreException e) { |
| return new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1, |
| Messages.RweaveTexProcessing_Tex_error_OutputDir_message, e ); |
| } |
| this.fTexPathConfig= new TexPathConfig(this.fTexFile, outputDir, this.fOutputFormat); |
| |
| return Status.OK_STATUS; |
| } |
| |
| public IFileStore getWorkingDirectory() { |
| return this.fWorkingFolder; |
| } |
| |
| |
| @Override |
| protected void runProcessing(final SubMonitor m) { |
| this.fProgress= m; |
| |
| if (checkExit(0)) { |
| return; |
| } |
| |
| doWeave(); |
| if (checkExit(0)) { |
| return; |
| } |
| |
| if (!this.fOutputInitialized) { |
| final IStatus status= initOutputDir(); |
| if (!status.isOK()) { |
| getStatus().add(status); |
| } |
| } |
| if (checkExit(0)) { |
| return; |
| } |
| |
| if (getConfig().produce.isRun() && this.fTexType == BUILDTEX_TYPE_RCONSOLE) { |
| finallyTex(this.fProgress.newChild(1)); |
| } |
| else { |
| doPrepareTex(); |
| if (checkExit(0)) { |
| return; |
| } |
| |
| doProcessTex(); |
| if (checkExit(0)) { |
| return; |
| } |
| } |
| |
| doOpenOutput(); |
| |
| this.fProgress.done(); |
| } |
| |
| @Override |
| protected int calculateTicks() { |
| final Config config= getConfig(); |
| int sum= 0; |
| if (config.weave.isRun()) { |
| sum += TICKS_RWEAVE; |
| } |
| else { |
| sum += TICKS_RWEAVE/10; |
| } |
| if (this.fTexOpenEditor >= TexTab.OPEN_ALWAYS) { |
| sum += TICKS_OPEN_TEX; |
| } |
| if (config.produce.isRun()) { |
| sum += TICKS_TEX; |
| } |
| if (config.preview.isRun()) { |
| sum += TICKS_OPEN_OUTPUT; |
| } |
| sum += TICKS_REST; |
| |
| return sum; |
| } |
| |
| |
| @Override |
| protected void runFinished() { |
| super.runFinished(); |
| |
| this.fProgress= null; |
| |
| if (getStatus().getSeverity() > IStatus.OK) { |
| if (getStatus().getSeverity() == IStatus.ERROR) { |
| StatusManager.getManager().handle(getStatus(), StatusManager.LOG | StatusManager.SHOW); |
| return; |
| } |
| StatusManager.getManager().handle(getStatus(), StatusManager.LOG); |
| } |
| } |
| |
| |
| private void doWeave() { // 1xx |
| final Config config= getConfig(); |
| if (this.fSweaveType == SWEAVE_TYPE_RCONSOLE || this.fTexType == BUILDTEX_TYPE_RCONSOLE) { // 11x |
| if (!(config.weave.isRun() || config.produce.isRun()) && this.fWorkingFolder != null) { |
| return; |
| } |
| try { |
| // RCodeLaunchRegistry.runRCodeDirect(RUtil.LINE_SEPARATOR_PATTERN.split(fSweaveCommands), false); |
| final ToolProcess rProcess= NicoUI.getToolRegistry().getActiveToolSession( |
| getConfig().getWorkbenchPage() ).getProcess(); |
| if (rProcess == null) { |
| NicoUITools.accessTool(RConsoleTool.TYPE, rProcess); // throws CoreException |
| } |
| |
| final R rTask= new R(); |
| if (config.weave.isRun() || config.produce.isRun()) { |
| this.fProgress.worked(TICKS_PREPARER); |
| |
| final IStatus submitStatus= rProcess.getQueue().add(rTask); |
| if (submitStatus.getSeverity() > IStatus.OK) { |
| getStatus().add(submitStatus); |
| if (checkExit(112)) { |
| return; |
| } |
| } |
| RTASK: while (true) { |
| synchronized (rTask) { |
| boolean ok= false; |
| try { |
| rTask.notifyAll(); |
| if (rTask.task != R.TASK_FINISHED && checkExit(0)) { |
| rTask.task= -1; |
| // removing runnable sets the cancel status |
| rProcess.getQueue().remove(rTask); |
| } |
| switch (rTask.task) { |
| case R.TASK_FINISHED: |
| ok= true; |
| break RTASK; |
| case R.TASK_PREPARE_TEX: |
| doPrepareTex(); |
| ok= true; |
| rTask.task= 0; |
| break; |
| default: |
| ok= true; |
| } |
| rTask.wait(100); |
| } |
| catch (final InterruptedException e) { |
| // continue loop, monitor is checked |
| } |
| finally { |
| if (!ok) { |
| rTask.task= -1; |
| } |
| } |
| } |
| } |
| if (checkExit(113)) { |
| return; |
| } |
| } |
| else if (this.fWorkingFolder == null) { // we need the working directory |
| final SubMonitor m= this.fProgress.newChild(TICKS_RWEAVE/10); |
| rTask.updatePathInformations(rProcess.getWorkspaceData()); |
| m.done(); |
| } |
| } |
| catch (final CoreException e) { |
| abort(e, 110); |
| return; |
| } |
| } |
| else if (this.fSweaveConfig != null) { // 12x |
| if (!config.weave.isRun() && this.fWorkingFolder != null) { |
| return; |
| } |
| try { |
| if (config.weave.isRun()) { |
| final SubMonitor monitor= this.fProgress.newChild(TICKS_RWEAVE); |
| monitor.beginTask(Messages.RweaveTexProcessing_Sweave_RCmd_label, 100); |
| final ILaunchConfigurationDelegate delegate= LaunchUtils.getLaunchConfigurationDelegate( |
| this.fSweaveConfig, ILaunchManager.RUN_MODE, getStatus() ); |
| delegate.launch(this.fSweaveConfig, ILaunchManager.RUN_MODE, getLaunch(), monitor.newChild(75)); |
| final IProcess[] processes= getLaunch().getProcesses(); |
| if (processes.length == 0) { |
| throw new IllegalStateException(); |
| } |
| final IProcess sweaveProcess= processes[processes.length-1]; |
| if (!sweaveProcess.isTerminated()) { |
| throw new IllegalStateException(); |
| } |
| final int exitValue= sweaveProcess.getExitValue(); |
| if (exitValue != 0) { |
| abort(IStatus.CANCEL, NLS.bind(Messages.RweaveTexProcessing_Sweave_RCmd_error_Found_message, exitValue), null, |
| 121); |
| return; |
| } |
| monitor.done(); |
| } |
| } |
| catch (final CoreException e) { |
| abort(e, 120); |
| return; |
| } |
| } |
| } |
| |
| private void doPrepareTex() { |
| final Config config= getConfig(); |
| final ISchedulingRule rule= beginSchedulingRule(this.fTexFile.getParent(), this.fProgress.newChild(1)); |
| try { |
| if ((config.weave.isRun() || config.produce.isRun()) && this.fTexFile.exists() && this.fTexFile.getType() == IResource.FILE) { |
| try { |
| this.fTexFile.deleteMarkers(TexlipseBuilder.MARKER_TYPE, true, IResource.DEPTH_INFINITE); |
| this.fTexFile.deleteMarkers(TexlipseBuilder.LAYOUT_WARNING_TYPE, true, IResource.DEPTH_INFINITE); |
| } |
| catch (final CoreException e) {} |
| } |
| this.fProgress.worked(1); |
| refreshDir(this.fTexFile, this.fProgress.newChild(1)); |
| if (checkExit(195)) { |
| return; |
| } |
| |
| final boolean exists= this.fTexFile.exists() && this.fTexFile.getType() == IResource.FILE; |
| if (config.produce.isRun() && !exists) { |
| doSetExitValue(199); |
| getStatus().add(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, -1, |
| NLS.bind(Messages.RweaveTexProcessing_Tex_error_NotFound_message, this.fTexFile.getFullPath().toString()), null)); |
| return; |
| } |
| |
| if ((config.weave.isRun() || getConfig().produce.isRun()) && exists && this.fTexOpenEditor == TexTab.OPEN_ALWAYS) { |
| final OpenUsingEclipseOperation operation= new OpenUsingEclipseOperation(this.fTexFile); |
| try { |
| operation.init(config.produce, NO_SETTINGS, this.fProgress.newChild(1)); |
| operation.setFailSeverity(IStatus.WARNING); |
| operation.run(this, this.fProgress.newChild(TICKS_OPEN_TEX - 1)); |
| } |
| catch (final CoreException e) {} |
| } |
| } |
| finally { |
| endSchedulingRule(rule); |
| } |
| } |
| |
| private void doProcessTex() { // 2xx |
| if (getConfig().produce.isRun() && this.fTexType == TexRweaveLaunchDelegate.BUILDTEX_TYPE_ECLIPSE) { |
| final SubMonitor m1= this.fProgress.newChild(TICKS_TEX); |
| this.fProgress.beginTask(Messages.RweaveTexProcessing_Tex_label, 100); |
| Texlipse.getViewerManager().closeDocInViewer(this.fTexPathConfig); |
| try { |
| this.fTexBuilder.reset(m1.newChild(60, SubMonitor.SUPPRESS_SUBTASK)); |
| this.fTexBuilder.build(this.fTexPathConfig); |
| AbstractBuilder.checkOutput(this.fTexPathConfig, m1.newChild(10)); |
| } |
| catch (final OperationCanceledException e) { |
| abort(IStatus.CANCEL, Messages.RweaveTexProcessing_info_Canceled_message, e, |
| 211); |
| return; |
| } |
| catch (final CoreException e) { |
| abort(e, 210); |
| return; |
| } |
| finally { |
| finallyTex(m1); |
| } |
| m1.done(); |
| } |
| |
| if (getStatus().getSeverity() < IStatus.ERROR) { |
| try { // 28x |
| if (getConfig().produce.isRun() && this.fTexOpenEditor > TexTab.OPEN_ALWAYS && this.fTexFile.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_ZERO) >= this.fTexOpenEditor) { |
| final OpenUsingEclipseOperation operation= new OpenUsingEclipseOperation(this.fTexFile); |
| try { |
| operation.init(getConfig().produce, NO_SETTINGS, this.fProgress.newChild(1)); |
| operation.setFailSeverity(IStatus.WARNING); |
| operation.run(this, this.fProgress.newChild(TICKS_OPEN_TEX - 1)); |
| } |
| catch (final CoreException e) {} |
| } |
| } |
| catch (final CoreException e) { |
| abort(e, 280); |
| return; |
| } |
| } |
| } |
| |
| private void finallyTex(final SubMonitor m) { |
| refreshDir(this.fTexPathConfig.getOutputFile(), m.isCanceled() ? null : m.newChild(5)); |
| if (!this.fWorkingFolderInWorkspace.equals(this.fTexPathConfig.getOutputFile().getParent())) { |
| final Job job= new Job("Refresh after TeX build") { |
| @Override |
| protected IStatus run(final IProgressMonitor monitor) { |
| return refreshDir(TexRweaveProcessToolProcess.this.fWorkingFolderInWorkspace, m.isCanceled() ? null : m.newChild(5)); |
| } |
| }; |
| job.setSystem(true); |
| final IResourceRuleFactory ruleFactory= this.fWorkingFolderInWorkspace.getWorkspace().getRuleFactory(); |
| job.setRule(ruleFactory.refreshRule(this.fWorkingFolderInWorkspace)); |
| } |
| } |
| |
| private void doOpenOutput() { // 3xx |
| final Config config= getConfig(); |
| if (config.preview.isRun()) { |
| final SubMonitor m1= this.fProgress.newChild(TICKS_OPEN_OUTPUT); |
| m1.setWorkRemaining(100); |
| if (!this.fTexPathConfig.getOutputFile().exists()) { |
| abort((config.preview.getRun() == RUN_EXPLICITE) ? IStatus.ERROR : IStatus.INFO, |
| NLS.bind(Messages.RweaveTexProcessing_Output_error_NotFound_message, this.fTexPathConfig.getOutputFile().getFullPath().toString()), null, |
| 301); |
| return; |
| } |
| try { |
| if (config.preview.getRun() == RUN_DEFAULT && this.fTexFile.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_ZERO) >= IMarker.SEVERITY_ERROR) { |
| abort(IStatus.CANCEL, Messages.RweaveTexProcessing_Output_info_SkipBecauseTex_message, null, |
| 302); |
| return; |
| } |
| } |
| catch (final CoreException e) { |
| abort(e, 303); |
| return; |
| } |
| m1.worked(10); |
| if (this.fPreviewConfig != null) { |
| Texlipse.getViewerManager().openDocInViewer(this.fTexPathConfig, this.fPreviewConfig); |
| } |
| else { |
| final OpenUsingEclipseOperation operation= new OpenUsingEclipseOperation( |
| this.fTexPathConfig.getOutputFile() ); |
| try { |
| operation.init(getConfig().preview, NO_SETTINGS, m1); |
| operation.run(this, m1); |
| } |
| catch (final CoreException e) { |
| abort(e, 304); |
| } |
| } |
| m1.done(); |
| // final ILaunchConfigurationDelegate delegate= getRunDelegate(fPreviewConfig); |
| // delegate.launch(fPreviewConfig, ILaunchManager.RUN_MODE, fLaunch, new SubProgressMonitor(fMonitor, 10)); |
| } |
| } |
| |
| private boolean checkExit(final int code) { |
| if (getStatus().getSeverity() >= IStatus.ERROR) { |
| if (code != 0 && doGetExitValue() == 0) { |
| doSetExitValue(code); |
| } |
| return true; |
| } |
| if (this.fProgress.isCanceled()) { |
| final IProgressMonitor p2= this.fProgress2; |
| if (p2 != null && !p2.isCanceled()) { |
| p2.setCanceled(true); |
| } |
| if (getStatus().getSeverity() < IStatus.CANCEL) { |
| getStatus().add(new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, Messages.RweaveTexProcessing_info_Canceled_message)); |
| } |
| return true; |
| } |
| else { |
| final IProgressMonitor p2= this.fProgress2; |
| if (p2 != null && p2.isCanceled()) { |
| this.fProgress.setCanceled(true); |
| if (getStatus().getSeverity() < IStatus.CANCEL) { |
| getStatus().add(new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, Messages.RweaveTexProcessing_info_Canceled_message)); |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private void abort(final CoreException e, final int exitCode) { |
| final IStatus status= e.getStatus(); |
| if (status.getSeverity() == IStatus.CANCEL) { |
| getStatus().add(status); |
| } |
| else { |
| abort(status.getSeverity(), status.getMessage(), e, exitCode); |
| } |
| } |
| |
| private void abort(final int severity, final String message, final Throwable cause, final int exitValue) { |
| getStatus().add(new Status(severity, TexRweaveUI.BUNDLE_ID, -1, message, cause)); |
| doSetExitValue(exitValue); |
| } |
| |
| |
| private IStatus refreshDir(final IResource resource, final IProgressMonitor monitor) { |
| try { |
| resource.refreshLocal(IResource.DEPTH_ONE, monitor); |
| return Status.OK_STATUS; |
| } |
| catch (final OperationCanceledException e) { |
| return new Status(IStatus.CANCEL, TexRweaveUI.BUNDLE_ID, -1, |
| Messages.RweaveTexProcessing_info_Canceled_message, e); |
| } |
| catch (final CoreException e) { |
| return e.getStatus(); |
| } |
| } |
| |
| |
| @Override |
| public void terminate() throws DebugException { |
| { final IProgressMonitor monitor= this.fProgress2; |
| if (monitor != null) { |
| monitor.setCanceled(true); |
| } |
| } |
| |
| super.terminate(); |
| } |
| |
| } |