blob: cb8599e4dd7854b8ffa0e5e67dc646e438b2d96f [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2007, 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.internal.r.core.sourcemodel;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.internal.r.core.RProjectNature;
import org.eclipse.statet.ltk.core.WorkingContext;
import org.eclipse.statet.ltk.model.core.build.SourceUnitModelContainer;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.ltk.model.core.impl.AbstractModelManager;
import org.eclipse.statet.r.core.RProject;
import org.eclipse.statet.r.core.model.RChunkElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RFrame;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RModelManager;
import org.eclipse.statet.r.core.model.RSourceUnit;
import org.eclipse.statet.r.core.model.RSourceUnitModelInfo;
import org.eclipse.statet.r.core.model.build.RSourceUnitModelContainer;
import org.eclipse.statet.r.core.rsource.ast.SourceComponent;
@NonNullByDefault
public class RModelManagerImpl extends AbstractModelManager implements RModelManager {
private static class RContextItem extends ContextItem {
public final HashMap<String, SourceUnit> worksheets;
public RContextItem(final WorkingContext context) {
super(context);
this.worksheets= new HashMap<>();
}
}
private final RReconciler reconciler= new RReconciler(this);
private final RModelEventJob eventJob= new RModelEventJob(this);
private final RModelIndex index= new RModelIndex(this);
public RModelManagerImpl() {
super(RModel.R_TYPE_ID);
}
public void dispose() {
this.eventJob.dispose();
this.index.dispose();
}
public RModelEventJob getEventJob() {
return this.eventJob;
}
public RModelIndex getIndex() {
return this.index;
}
@Override
protected ContextItem doCreateContextItem(final WorkingContext context) {
return new RContextItem(context);
}
@Override
public void registerDependentUnit(final SourceUnit copy) {
assert (copy.getModelTypeId().equals(RModel.R_TYPE_ID) ?
copy.getElementType() == RSourceUnit.R_OTHER_SU : true);
final RContextItem contextItem= (RContextItem)getContextItemCreate(copy.getWorkingContext());
synchronized (contextItem) {
final String key= copy.getId() + '+' + copy.getModelTypeId();
contextItem.worksheets.put(key, copy);
}
}
@Override
public void deregisterDependentUnit(final SourceUnit copy) {
final RContextItem contextItem= (RContextItem)getContextItemCreate(copy.getWorkingContext());
synchronized (contextItem) {
contextItem.worksheets.remove(copy.getId() + '+' + copy.getModelTypeId());
}
}
public @Nullable SourceUnit getWorksheetCopy(final String type, final String id, final WorkingContext context) {
final RContextItem contextItem= (RContextItem)getContextItem(context);
if (contextItem != null) {
synchronized (contextItem) {
return contextItem.worksheets.get(id + '+' + type);
}
}
return null;
}
@Override
public void reconcile(final SourceUnitModelContainer<?, ?> adapter,
final int level, final IProgressMonitor monitor) {
if (adapter instanceof RSourceUnitModelContainer) {
this.reconciler.reconcile((RSourceUnitModelContainer) adapter, level, monitor);
}
}
@Override
public RSourceUnitModelInfo reconcile(final RSourceUnit sourceUnit, final SourceUnitModelInfo modelInfo,
final List<? extends RChunkElement> chunks, final List<? extends SourceComponent> inlineNodes,
final int level, final IProgressMonitor monitor) {
if (sourceUnit == null) {
throw new NullPointerException("sourceUnit"); //$NON-NLS-1$
}
return this.reconciler.reconcile(sourceUnit, modelInfo, chunks, inlineNodes, level, monitor);
}
@Override
public @Nullable RFrame getProjectFrame(final RProject rProject) throws CoreException {
return this.index.getProjectFrame(rProject);
}
@Override
public Set<String> getPkgNames() {
return this.index.getPkgNames();
}
@Override
public @Nullable RFrame getPkgProjectFrame(final String pkgName) throws CoreException {
if (pkgName == null) {
throw new NullPointerException("pkgName"); //$NON-NLS-1$
}
final String projectName= this.index.getPkgProject(pkgName);
if (projectName != null) {
final IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
final RProjectNature rProject= RProjectNature.getRProject(project);
if (rProject != null) {
return getProjectFrame(rProject);
}
}
return null;
}
@Override
public @Nullable List<SourceUnit> findReferencingSourceUnits(final RProject rProject, final RElementName name,
final IProgressMonitor monitor) throws CoreException {
return this.index.findReferencingSourceUnits(rProject, name, monitor);
}
}