blob: 25d01bdce5a3ef016366173793911840e937d14e [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2017, 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.r.apps.ui.launching;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.PARAMETER;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.RETURN_TYPE;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.TYPE_ARGUMENT;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.TYPE_BOUND;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.variables.IStringVariable;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.ecommons.io.FileValidator;
import org.eclipse.statet.ecommons.resources.core.variables.ResourceVariableResolver;
import org.eclipse.statet.ecommons.resources.core.variables.ResourceVariables;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.workspace.ResourceVariableUtil;
import org.eclipse.statet.ecommons.variables.core.VariableText2;
import org.eclipse.statet.ecommons.variables.core.VariableText2.Severities;
import org.eclipse.statet.ecommons.variables.core.VariableUtils;
import org.eclipse.statet.internal.r.apps.core.shiny.RShinyResourceTester;
import org.eclipse.statet.internal.r.apps.ui.Messages;
import org.eclipse.statet.internal.r.apps.ui.RAppUIPlugin;
@NonNullByDefault({ PARAMETER, RETURN_TYPE, TYPE_BOUND, TYPE_ARGUMENT })
public class AppControlLaunchConfig {
protected static CoreException createMissingConfigAttr(final String attrName) {
return new CoreException(new Status(IStatus.ERROR, RAppUIPlugin.BUNDLE_ID,
NLS.bind("Invalid configuration: configuration attribute ''{0}'' is missing.", attrName) ));
}
protected static CoreException createValidationFailed(final FileValidator validator) {
final IStatus status= validator.getStatus();
return new CoreException(new Status(IStatus.ERROR, RAppUIPlugin.BUNDLE_ID,
status.getMessage() ));
}
private ResourceVariableUtil selectedResourceUtil;
private IResource appFolder;
private ResourceVariableUtil appFolderrUtil;
private Map<String, IStringVariable> globalVariables;
private String appHost;
private int appPort;
private String startCode;
private String stopCode;
private String viewerId;
private String variablesCode;
private int variablesViewAction;
private int stopBlocking;
public AppControlLaunchConfig() {
}
public Map<String, IStringVariable> getVariables() {
if (this.globalVariables == null) {
this.globalVariables= new HashMap<>();
}
return this.globalVariables;
}
public void initSource(final ILaunchConfiguration configuration,
final SubMonitor m) throws CoreException {
final FileValidator validator= new FileValidator(true);
validator.setResourceLabel("app resource");
validator.setRequireWorkspace(true, true);
IPath explicitePath= null;
{ final String path= configuration.getAttribute(AppControlConfigs.SOURCE_PATH_ATTR_NAME,
(String) null );
if (path != null) {
explicitePath= Path.fromPortableString(path);
}
}
if (explicitePath != null) {
validator.setExplicit(explicitePath);
}
else {
UIAccess.getDisplay().syncExec(() -> {
final ResourceVariableUtil util= new ResourceVariableUtil();
util.getResource();
AppControlLaunchConfig.this.selectedResourceUtil= util;
});
if (this.selectedResourceUtil.getResource() == null) {
throw new CoreException(new Status(IStatus.ERROR, RAppUIPlugin.BUNDLE_ID,
"No resource selected in the active Workbench window." ));
}
validator.setExplicit(this.selectedResourceUtil.getResource());
}
if (validator.getStatus().getSeverity() == IStatus.ERROR) {
throw createValidationFailed(validator);
}
setSelectedResource(validator.getWorkspaceResource());
final IResource appFolder;
if (explicitePath != null) {
appFolder= this.selectedResourceUtil.getResource();
}
else {
appFolder= RShinyResourceTester.getAppContainer(
this.selectedResourceUtil.getResource() );
if (appFolder == null) {
throw new CoreException(new Status(IStatus.ERROR, RAppUIPlugin.BUNDLE_ID,
NLS.bind("Could not find app folder for ''{0}''.",
this.selectedResourceUtil.getResource() )));
}
}
initAppFolder(appFolder);
}
protected void setSelectedResource(final IResource resource) {
if (this.selectedResourceUtil == null) {
UIAccess.getDisplay().syncExec(() -> {
final ResourceVariableUtil util= new ResourceVariableUtil(resource);
AppControlLaunchConfig.this.selectedResourceUtil= util;
});
}
}
private void initAppFolder(final IResource resource) {
this.appFolder= resource;
this.appFolderrUtil= new ResourceVariableUtil(this.selectedResourceUtil, resource);
{ final Map<String, IStringVariable> variables= getVariables();
VariableUtils.add(variables,
ResourceVariables.getSingleResourceVariables(),
new ResourceVariableResolver(this.appFolderrUtil) );
}
}
public IResource getAppFolder() {
return this.appFolder;
}
public IWorkbenchPage getWorkbenchPage() {
return this.appFolderrUtil.getWorkbenchPage();
}
public void initAddress(final ILaunchConfiguration configuration,
final SubMonitor m) throws CoreException {
this.appHost= configuration.getAttribute(AppControlConfigs.APP_HOST_ATTR_NAME, ""); //$NON-NLS-1$
this.appPort= configuration.getAttribute(AppControlConfigs.APP_PORT_ATTR_NAME, 0);
final Map<String, IStringVariable> variables= getVariables();
VariableUtils.add(variables, AppControlConfigs.APP_HOST_VAR);
VariableUtils.add(variables, AppControlConfigs.APP_PORT_VAR);
}
public String getAppHost() {
return this.appHost;
}
public int getAppPort() {
return this.appPort;
}
public void initOperation(final ILaunchConfiguration configuration,
final SubMonitor m) throws CoreException {
this.stopBlocking= configuration.getAttribute(AppControlConfigs.START_STOP_BLOCKING_TASKS_MODE_ATTR_NAME, 0);
{ final String code= configuration.getAttribute(AppControlConfigs.START_R_SNIPPET_CODE_ATTR_NAME, ""); //$NON-NLS-1$
if (code.isEmpty()) {
throw new CoreException(new Status(IStatus.ERROR, RAppUIPlugin.BUNDLE_ID,
Messages.Operation_StartApp_RCode_error_SpecMissing_message ));
}
try {
final VariableText2 variableResolver= new VariableText2(getVariables());
variableResolver.validate(code, Severities.CHECK_SYNTAX, null);
this.startCode= code;
}
catch (final CoreException e) {
throw new CoreException(new Status(IStatus.ERROR, RAppUIPlugin.BUNDLE_ID,
NLS.bind(Messages.Operation_StartApp_RCode_error_SpecInvalid_message,
e.getMessage() )));
}
}
{ final String code= configuration.getAttribute(AppControlConfigs.STOP_R_SNIPPET_CODE_ATTR_NAME, ""); //$NON-NLS-1$
this.stopCode= (!code.isEmpty()) ? code : null;
}
this.viewerId= configuration.getAttribute(AppControlConfigs.VIEWER_ID_ATTR_NAME, (String) null);
{ String code= configuration.getAttribute(AppControlConfigs.VARIABLES_CODE_ATTR_NAME, ""); //$NON-NLS-1$
if (code.isEmpty()) {
code= null;
}
this.variablesCode= code;
final String viewAction= configuration.getAttribute(AppControlConfigs.VARIABLES_VIEWER_ACTION_ATTR_NAME, ""); //$NON-NLS-1$
int viewActionMode= 0;
if (viewAction.equals(AppControlConfigs.SHOW_ACTION_ID)) {
viewActionMode= IWorkbenchPage.VIEW_VISIBLE;
}
this.variablesViewAction= viewActionMode;
}
}
public int getStopBlocking() {
return this.stopBlocking;
}
public String getStartCode() {
return this.startCode;
}
public String getStopCode() {
return this.stopCode;
}
public @Nullable String getViewerId() {
return this.viewerId;
}
public @Nullable String getVariablesCode() {
return this.variablesCode;
}
public int getVariablesViewAction() {
return this.variablesViewAction;
}
}