| /*=============================================================================# |
| # 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 ); |
| } |
| } |
| |
| } |