blob: e395cbde6980abb0131676947affe38b356393e7 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2007, 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.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.internal.r.core.RProjectNature;
import org.eclipse.statet.ltk.core.LTK;
import org.eclipse.statet.ltk.core.WorkingContext;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.ltk.model.core.impl.AbstractModelManager;
import org.eclipse.statet.ltk.model.core.impl.SourceUnitModelContainer;
import org.eclipse.statet.r.core.RProject;
import org.eclipse.statet.r.core.model.IRFrame;
import org.eclipse.statet.r.core.model.IRModelInfo;
import org.eclipse.statet.r.core.model.IRModelManager;
import org.eclipse.statet.r.core.model.IRSourceUnit;
import org.eclipse.statet.r.core.model.RChunkElement;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.model.RSuModelContainer;
import org.eclipse.statet.r.core.rsource.ast.SourceComponent;
public class RModelManager extends AbstractModelManager implements IRModelManager {
private static class RContextItem extends ContextItem {
public final HashMap<String, ISourceUnit> 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 RModelManager() {
super(RModel.R_TYPE_ID);
getContextItem(LTK.PERSISTENCE_CONTEXT, true);
getContextItem(LTK.EDITOR_CONTEXT, true);
}
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 ISourceUnit copy) {
assert (copy.getModelTypeId().equals(RModel.R_TYPE_ID) ?
copy.getElementType() == IRSourceUnit.R_OTHER_SU : true);
final RContextItem contextItem= (RContextItem) getContextItem(
copy.getWorkingContext(), true );
synchronized (contextItem) {
final String key= copy.getId() + '+' + copy.getModelTypeId();
contextItem.worksheets.put(key, copy);
}
}
@Override
public void deregisterDependentUnit(final ISourceUnit copy) {
final RContextItem contextItem= (RContextItem) getContextItem(
copy.getWorkingContext(), true );
synchronized (contextItem) {
contextItem.worksheets.remove(copy.getId() + '+' + copy.getModelTypeId());
}
}
public ISourceUnit getWorksheetCopy(final String type, final String id, final WorkingContext context) {
final RContextItem contextItem= (RContextItem) getContextItem(
context, false );
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 RSuModelContainer) {
this.reconciler.reconcile((RSuModelContainer) adapter, level, monitor);
}
}
@Override
public IRModelInfo reconcile(final IRSourceUnit sourceUnit, final ISourceUnitModelInfo 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 IRFrame getProjectFrame(final RProject rProject) throws CoreException {
return this.index.getProjectFrame(rProject);
}
@Override
public Set<String> getPkgNames() {
return this.index.getPkgNames();
}
@Override
public IRFrame 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 List<ISourceUnit> findReferencingSourceUnits(final RProject rProject, final RElementName name,
final IProgressMonitor monitor) throws CoreException {
return this.index.findReferencingSourceUnits(rProject, name, monitor);
}
}