blob: e9fc801d9f80987c9f16b840c6a31e412242d006 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2013, 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.r.console.core.util;
import java.util.Set;
import org.eclipse.osgi.util.NLS;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImSet;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.ts.core.SystemRunnable;
import org.eclipse.statet.jcommons.ts.core.Tool;
import org.eclipse.statet.r.console.core.RProcess;
import org.eclipse.statet.r.console.core.RProcessREnvironment;
import org.eclipse.statet.r.console.core.RWorkspace;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.tool.AbstractStatetRRunnable;
import org.eclipse.statet.r.nico.ICombinedRDataAdapter;
import org.eclipse.statet.rj.data.RReference;
import org.eclipse.statet.rj.ts.core.RToolService;
public class LoadReferenceRunnable extends AbstractStatetRRunnable implements SystemRunnable {
public static RProcess findRProcess(CombinedRElement element) {
while (element != null) {
if (element instanceof RProcessREnvironment) {
return ((RProcessREnvironment) element).getSource();
}
element= element.getModelParent();
}
return null;
}
private static final ImSet<String> LOAD_PKG_EXCLUDE_LIST= ImCollections.newSet(
System.getProperty("org.eclipse.statet.r.console.namespaces.load.exclude", "") //$NON-NLS-1$ //$NON-NLS-2$
.split(",") ); //$NON-NLS-1$
public static boolean isAccessAllowed(final RElementName name, final RWorkspace rWorkspace) {
final Set<String> excludePkgs= LOAD_PKG_EXCLUDE_LIST;
if (excludePkgs.isEmpty()) {
return true;
}
final String pkgName;
if (RElementName.isPackageFacetScopeType(name.getType())) {
pkgName= name.getSegmentName();
}
else if (name.getScope() != null
&& RElementName.isPackageFacetScopeType(name.getScope().getType()) ) {
pkgName= name.getScope().getSegmentName();
}
else {
return true;
}
return (!(excludePkgs.contains("*") || excludePkgs.contains(pkgName)) //$NON-NLS-1$
|| rWorkspace.isNamespaceLoaded(pkgName) );
}
private final RReference reference;
private final RElementName name;
private final RProcess process;
private final int stamp;
private int loadOptions;
private CombinedRElement resolvedElement;
private boolean cancel;
private int state;
private Runnable finishRunnable;
public LoadReferenceRunnable(final RReference reference, final RProcess tool,
final int stamp, final String cause) {
super("r/workspace/loadElements", //$NON-NLS-1$
NLS.bind("Load elements of {0} (requested for {1})",
((CombinedRElement) reference).getElementName().getDisplayName(),
cause ));
this.reference= reference;
this.name= null;
this.process= tool;
this.stamp= stamp;
}
public LoadReferenceRunnable(final RElementName name, final RProcess tool,
final int stamp, final String cause) {
super("r/workspace/loadElements", //$NON-NLS-1$
NLS.bind("Load elements of {0} (requested for {1})",
name.getDisplayName(),
cause ));
this.reference= null;
this.name= name;
this.process= tool;
this.stamp= stamp;
}
public final RProcess getTool() {
return this.process;
}
public int getLoadOptions() {
return this.loadOptions;
}
public void setLoadOptions(final int options) {
this.loadOptions= options;
}
public int getRequiredStamp() {
return this.stamp;
}
public void cancel() {
this.cancel= true;
}
public CombinedRElement getResolvedElement() {
return this.resolvedElement;
}
public boolean isStarted() {
return (this.state == STARTING);
}
public boolean isFinished() {
return ((this.state & MASK_EVENT_GROUP) == FINISHING_EVENT_GROUP);
}
public void setFinishRunnable(final Runnable runnable) {
this.finishRunnable= runnable;
}
@Override
public boolean canRunIn(final Tool tool) {
return (tool == this.process);
}
@Override
public boolean changed(final int event, final Tool tool) {
Runnable runnable= null;
switch (event) {
case REMOVING_FROM:
if (this.cancel) {
synchronized (this) {
this.state= event;
LoadReferenceRunnable.this.notifyAll();
return true;
}
}
return false;
case MOVING_FROM:
return false;
case BEING_ABANDONED:
case FINISHING_OK:
case FINISHING_ERROR:
case FINISHING_CANCEL:
synchronized (this) {
this.state= event;
runnable= this.finishRunnable;
LoadReferenceRunnable.this.notifyAll();
}
break;
default:
break;
}
if (runnable != null) {
runnable.run();
}
return true;
}
@Override
public void run(final RToolService service,
final ProgressMonitor m) throws StatusException {
final ICombinedRDataAdapter r= (ICombinedRDataAdapter) service;
if (this.stamp != 0 && this.stamp != r.getChangeStamp()) {
return;
}
final int loadOptions;
synchronized (this) {
this.state= STARTING;
loadOptions= this.loadOptions;
}
final RWorkspace workspace= r.getWorkspaceData();
if (this.reference != null) {
this.resolvedElement= workspace.resolve(this.reference, RWorkspace.RESOLVE_UPTODATE,
loadOptions, m );
}
else {
this.resolvedElement= workspace.resolve(this.name, RWorkspace.RESOLVE_UPTODATE,
loadOptions, m );
}
}
}