blob: 9f32e8c0b1c484557059220c11049f941b30a20f [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2021 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.rj.example.rcpdemo;
import java.io.File;
import java.util.List;
import java.util.NoSuchElementException;
import javax.security.auth.login.LoginException;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.statet.jcommons.rmi.RMIRegistry;
import org.eclipse.statet.jcommons.rmi.RMIRegistryManager;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.NullProgressMonitor;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.internal.rj.example.rcpdemo.Activator;
import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.rsetups.RSetup;
import org.eclipse.statet.rj.rsetups.RSetupUtil;
import org.eclipse.statet.rj.server.RjsComConfig;
import org.eclipse.statet.rj.server.client.RClientGraphicFactory;
import org.eclipse.statet.rj.server.util.RJContext;
import org.eclipse.statet.rj.servi.RServi;
import org.eclipse.statet.rj.servi.RServiUtils;
import org.eclipse.statet.rj.servi.node.RServiImpl;
import org.eclipse.statet.rj.servi.node.RServiNodeConfig;
import org.eclipse.statet.rj.servi.node.RServiNodeFactory;
import org.eclipse.statet.rj.servi.node.RServiNodeManager;
public class RServiManager {
private static final int LOCAL_INST= 1;
private static final int LOCAL_RSETUP= 2;
private static final int POOL= 3;
private static class Config {
private int mode;
private String address;
}
private final String name;
private Config config= new Config();
private RServiNodeManager localR;
private final ISchedulingRule schedulingRule= new ISchedulingRule() {
@Override
public boolean contains(final ISchedulingRule rule) {
return (rule == this);
}
@Override
public boolean isConflicting(final ISchedulingRule rule) {
// if concurrent remote instances are desired, return false here
return (rule == this);
}
};
public RServiManager(final String appId, final RClientGraphicFactory graphicFactory) {
this.name= appId;
RjsComConfig.setProperty("rj.servi.graphicFactory", graphicFactory);
// RjsComConfig.setProperty("rj.servi.comClientGraphicActionsFactory",
// new MyClientGraphicActionsFactory() );
}
public ISchedulingRule getSchedulingRule() {
return this.schedulingRule;
}
public void setLocalInst(final String rHome) throws StatusException {
final Config config= new Config();
config.mode= LOCAL_INST;
config.address= rHome;
this.config= config;
final RServiNodeConfig rConfig= new RServiNodeConfig();
rConfig.setRHome(rHome);
rConfig.setEnableVerbose(true);
startLocal(rConfig);
}
public void setRSetup(final String setupId) throws StatusException {
final Config config= new Config();
config.mode= LOCAL_RSETUP;
config.address= setupId;
this.config= config;
final RSetup setup= RSetupUtil.loadSetup(setupId, null);
if (setup == null) {
throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
"No R setup with specified id found." ));
}
final RServiNodeConfig rConfig= new RServiNodeConfig();
rConfig.setRHome(setup.getRHome());
setLibs(setup.getRLibsSite(), rConfig, "R_LIBS_SITE");
setLibs(setup.getRLibs(), rConfig, "R_LIBS");
setLibs(setup.getRLibsUser(), rConfig, "R_LIBS_USER");
rConfig.setEnableVerbose(true);
startLocal(rConfig);
}
public void setPool(final String poolAddress) {
final Config config= new Config();
config.mode= POOL;
config.address= poolAddress;
this.config= config;
}
private void setLibs(final List<String> locations, final RServiNodeConfig rConfig, final String varName) {
if (locations != null && locations.size() > 0) {
final StringBuilder sb= new StringBuilder(locations.get(0));
for (int i= 0; i < locations.size(); i++) {
sb.append(File.pathSeparatorChar);
sb.append(locations.get(i));
}
rConfig.getEnvironmentVariables().put(varName, sb.toString());
}
}
private void startLocal(final RServiNodeConfig rConfig) throws StatusException {
startLocal(rConfig, new NullProgressMonitor()); // TODO real monitor, e.g. in a Job
}
private void startLocal(final RServiNodeConfig rConfig,
final ProgressMonitor m) throws StatusException {
if (rConfig == null) {
throw new NullPointerException("rConfig");
}
if (m == null) {
throw new NullPointerException("monitor");
}
try {
final RJContext context= new RJContext();
if (System.getSecurityManager() == null) {
if (System.getProperty("java.security.policy") == null) {
final String policyFile= context.getServerPolicyFilePath();
System.setProperty("java.security.policy", policyFile);
}
System.setSecurityManager(new SecurityManager());
}
final RMIRegistry registry= RMIRegistryManager.INSTANCE.getEmbeddedPrivateRegistry(m);
final RServiNodeFactory nodeFactory= RServiImpl.createLocalNodeFactory(this.name, context);
nodeFactory.setRegistry(registry);
nodeFactory.setConfig(rConfig);
final RServiNodeManager newLocalR= RServiImpl.createNodeManager(this.name, registry, nodeFactory);
newLocalR.start();
if (this.localR != null) {
this.localR.stop();
this.localR= null;
}
this.localR= newLocalR;
}
catch (final RjException e) {
throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
"Local R instance could not created.", e ));
}
}
public RServi getRServi(final String task) throws StatusException {
final Config config= this.config;
final String key= this.name + "-" + task;
try {
switch (config.mode) {
case LOCAL_INST:
case LOCAL_RSETUP:
return RServiUtils.getRServi(this.localR, key);
case POOL:
return RServiUtils.getRServi(config.address, key);
default:
throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
"R is not configured, please check the configuration." ));
}
}
catch (final StatusException e) {
throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
"R not available, please check the configuration.", e ));
}
catch (final LoginException e) {
throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
"R not available, please check the configuration.", e ));
}
catch (final NoSuchElementException e) {
throw new StatusException(new ErrorStatus(Activator.BUNDLE_ID,
"R currently not available, please try again later.", e ));
}
}
}