| /*=============================================================================# |
| # Copyright (c) 2005, 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; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectDescription; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImIdentitySet; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ecommons.preferences.PreferencesManageListener; |
| import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess; |
| import org.eclipse.statet.ecommons.preferences.core.PreferenceSetService; |
| import org.eclipse.statet.ecommons.resources.core.AbstractProjectNature; |
| import org.eclipse.statet.ecommons.resources.core.BuildUtils; |
| import org.eclipse.statet.ecommons.resources.core.ProjectUtils; |
| |
| import org.eclipse.statet.ltk.buildpaths.core.IBuildpathElement; |
| import org.eclipse.statet.r.core.RCodeStyleSettings; |
| import org.eclipse.statet.r.core.RCore; |
| import org.eclipse.statet.r.core.RProject; |
| import org.eclipse.statet.r.core.RProjects; |
| import org.eclipse.statet.r.core.renv.IREnvManager; |
| import org.eclipse.statet.rj.renv.core.REnv; |
| import org.eclipse.statet.rj.renv.core.REnvUtils; |
| |
| |
| @NonNullByDefault |
| public class RProjectNature extends AbstractProjectNature implements RProject, PreferenceSetService.ChangeListener { |
| |
| |
| public static final String OLD_QUALIFIER= "de.walware.r.core/RProjectBuild"; //$NON-NLS-1$ |
| |
| public static final String RPKG_ROOT_FOLDER_PATH_KEY= "RPkgRootFolder.path"; //$NON-NLS-1$ |
| public static final String RENV_CODE_KEY= "REnv.code"; //$NON-NLS-1$ |
| |
| |
| private static final ImIdentitySet<String> PREF_QUALIFIERS= ImCollections.newIdentitySet( |
| IREnvManager.PREF_QUALIFIER, |
| BUILD_PREF_QUALIFIER ); |
| |
| |
| public static @Nullable RProjectNature getRProject(final @Nullable IProject project) { |
| try { |
| return (project != null) ? (RProjectNature) project.getNature(RProjects.R_NATURE_ID) : null; |
| } |
| catch (final CoreException e) { |
| RCorePlugin.log(e.getStatus()); |
| return null; |
| } |
| } |
| |
| |
| private @Nullable String rPkgName; |
| |
| private PreferencesManageListener preferenceListener; |
| |
| private RCodeStyleSettings rCodeStyle; |
| |
| private @Nullable REnv rEnv; |
| |
| private RBuildpathPrefs rBuildpathPrefs; |
| private ImList<IBuildpathElement> rRawBuildpath; |
| |
| |
| @SuppressWarnings("null") |
| public RProjectNature() { |
| super(); |
| } |
| |
| |
| @Override |
| public void setProject(final IProject project) { |
| super.setProject(project); |
| |
| addPreferenceSetListener(this, PREF_QUALIFIERS); |
| |
| updateREnv(); |
| |
| this.rCodeStyle= new RCodeStyleSettings(1); |
| this.preferenceListener= new PreferencesManageListener(this.rCodeStyle, getPrefs(), |
| RCodeStyleSettings.ALL_GROUP_IDS ); |
| |
| this.rBuildpathPrefs= new RBuildpathPrefs(getProjectContext(), BUILD_PREF_QUALIFIER, |
| getProject() ); |
| updateBuildpath(); |
| |
| this.rPkgName= RCorePlugin.getInstance().getRModelManager().getIndex() |
| .getPkgName(project.getName()); |
| |
| RCorePlugin.getInstance().getResourceTracker().register(project, this); |
| } |
| |
| @Override |
| public void dispose() { |
| RCorePlugin.getInstance().getResourceTracker().unregister(getProject()); |
| |
| super.dispose(); |
| |
| if (this.preferenceListener != null) { |
| this.preferenceListener.dispose(); |
| this.preferenceListener= null; |
| } |
| |
| this.rEnv= null; |
| } |
| |
| @Override |
| public void deconfigure() throws CoreException { |
| dispose(); |
| super.deconfigure(); |
| } |
| |
| @Override |
| public void addBuilders() throws CoreException { |
| final IProject project= getProject(); |
| final IProjectDescription description= project.getDescription(); |
| boolean changed= false; |
| changed|= ProjectUtils.addBuilder(description, RSupportBuilder.ID); |
| |
| if (changed) { |
| project.setDescription(description, null); |
| } |
| } |
| |
| @Override |
| public void removeBuilders() throws CoreException { |
| final IProject project= getProject(); |
| final IProjectDescription description= project.getDescription(); |
| boolean changed= false; |
| changed|= ProjectUtils.removeBuilder(description, RSupportBuilder.ID); |
| |
| if (changed) { |
| project.setDescription(description, null); |
| } |
| } |
| |
| |
| @Override |
| public void preferenceChanged(final PreferenceSetService.ChangeEvent event) { |
| boolean clean= false; |
| |
| if (event.contains(IREnvManager.PREF_QUALIFIER) |
| || event.contains(RProject.RENV_CODE_PREF) ) { |
| updateREnv(); |
| } |
| if (event.contains(RProject.BUILD_PREF_QUALIFIER, RBuildpathPrefs.STAMP_KEY)) { |
| updateBuildpath(); |
| clean= true; |
| } |
| if (event.contains(RProject.PKG_BASE_FOLDER_PATH_PREF)) { |
| clean= true; |
| } |
| |
| if (clean) { |
| BuildUtils.getCleanJob(getProject(), false).schedule(); |
| } |
| } |
| |
| private void updateREnv() { |
| final IREnvManager rEnvManager= RCore.getREnvManager(); |
| final String s= getProjectValue(RProject.RENV_CODE_PREF); |
| this.rEnv= (s != null) ? REnvUtils.decode(s, rEnvManager) : rEnvManager.getDefault(); |
| } |
| |
| private void updateBuildpath() { |
| final ImList<IBuildpathElement> rawBuildpath= this.rBuildpathPrefs.load(); |
| synchronized (this) { |
| this.rRawBuildpath= rawBuildpath; |
| } |
| } |
| |
| @Override |
| public PreferenceAccess getPrefs() { |
| return this; |
| } |
| |
| @Override |
| public @Nullable REnv getREnv() { |
| return this.rEnv; |
| } |
| |
| @Override |
| public RCodeStyleSettings getRCodeStyle() { |
| return this.rCodeStyle; |
| } |
| |
| @Override |
| public @Nullable IPath getPkgRootPath() { |
| final IProject project= getProject(); |
| try { |
| if (project.hasNature(RProjects.R_PKG_NATURE_ID)) { |
| final IPath projectPath= getProject().getFullPath(); |
| final String s= getPreferenceValue(RProject.PKG_BASE_FOLDER_PATH_PREF); |
| if (s != null) { |
| return projectPath.append(Path.fromPortableString(s)); |
| } |
| return projectPath; |
| } |
| } |
| catch (final CoreException e) { |
| } |
| return null; |
| } |
| |
| |
| @Override |
| public ImList<IBuildpathElement> getRawBuildpath() { |
| return this.rRawBuildpath; |
| } |
| |
| |
| @Override |
| public @Nullable String getPkgName() { |
| return this.rPkgName; |
| } |
| |
| /** |
| * Called by project builder |
| * |
| * @param pkgName |
| */ |
| public void updateRPkgConfig(final @Nullable String pkgName) { |
| final boolean changed= (pkgName != null) != (this.rPkgName != null); |
| this.rPkgName= pkgName; |
| |
| if (changed) { |
| // checkPackageNature(); |
| } |
| } |
| |
| public void saveBuildpath(final ImList<IBuildpathElement> rawBuildpath) { |
| if (getRawBuildpath().equals(rawBuildpath)) { |
| return; |
| } |
| this.rBuildpathPrefs.save(rawBuildpath, true); |
| } |
| |
| } |