diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 2b373270d3..66e3aaf740 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -8,6 +8,13 @@ Updated the embedded Maven from version 3.9.5 to 3.9.6; [Maven 3.9.6 Release Notes](https://maven.apache.org/docs/3.9.6/release-notes.html). +### New project preference for automated Maven project configuration updates + +Automatic configuration updates for Maven projects can now be disabled the in the project preferences. +This allows to disable these updates individually per project and to store the setting in a preference-file under version control, +which is useful for projects that require special workspace configuration that doesn't exactly match the configuration in the `pom.xml`. + +![grafik](https://github.com/eclipse-m2e/m2e-core/assets/44067969/7d27ceda-5d13-4f0e-97f0-ff34c94d7493) ## 2.5.0 diff --git a/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF b/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF index 5940563702..43edc16711 100644 --- a/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.m2e.core.ui;singleton:=true -Bundle-Version: 2.0.8.qualifier +Bundle-Version: 2.0.800.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-Name: %Bundle-Name Bundle-Vendor: %Bundle-Vendor @@ -56,3 +56,9 @@ Service-Component: OSGI-INF/component.xml, OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypeGenerator.xml, OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypePlugin.xml Automatic-Module-Name: org.eclipse.m2e.core.ui +Service-Component: OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypeGenerator.xml, + OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypePlugin.xml +Bundle-ActivationPolicy: lazy +Service-Component: OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypeGenerator.xml, + OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypePlugin.xml +Bundle-ActivationPolicy: lazy diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java index ff4fbbfd8b..acbe088faa 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java @@ -36,10 +36,12 @@ import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.internal.IMavenConstants; -import org.eclipse.m2e.core.project.IProjectConfiguration; +import org.eclipse.m2e.core.internal.preferences.MavenPreferenceInitializer; +import org.eclipse.m2e.core.internal.project.ResolverConfigurationIO; import org.eclipse.m2e.core.project.IProjectConfigurationManager; import org.eclipse.m2e.core.project.ResolverConfiguration; import org.eclipse.m2e.core.ui.internal.Messages; +import org.eclipse.m2e.core.ui.internal.project.MavenUpdateConfigurationChangeListener; /** @@ -52,6 +54,8 @@ public class MavenProjectPreferencePage extends PropertyPage { private Button resolveWorspaceProjectsButton; + private Button autoUpdateConfigurationButton; + // private Button includeModulesButton; private Text selectedProfilesText; @@ -74,10 +78,18 @@ protected Control createContents(Composite parent) { selectedProfilesText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); resolveWorspaceProjectsButton = new Button(composite, SWT.CHECK); - GridData resolveWorspaceProjectsButtonData = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1); - resolveWorspaceProjectsButton.setLayoutData(resolveWorspaceProjectsButtonData); + resolveWorspaceProjectsButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); resolveWorspaceProjectsButton.setText(Messages.MavenProjectPreferencePage_btnResolve); + autoUpdateConfigurationButton = new Button(composite, SWT.CHECK); + autoUpdateConfigurationButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); + autoUpdateConfigurationButton.setText(Messages.MavenPreferencePage_autoUpdateProjectConfiguration); + if(MavenUpdateConfigurationChangeListener.isAutoConfigurationUpdateDisabled()) { + autoUpdateConfigurationButton.setEnabled(false); + String text = autoUpdateConfigurationButton.getText() + " (disabled in workspace preferences)"; + autoUpdateConfigurationButton.setText(text); + } + // includeModulesButton = new Button(composite, SWT.CHECK); // GridData gd = new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1); // gd.verticalIndent = 15; @@ -100,16 +112,19 @@ protected Control createContents(Composite parent) { init(getResolverConfiguration()); + boolean isAutoUpdate = ResolverConfigurationIO.isAutomaticallyUpdateConfiguration(getProject()); + autoUpdateConfigurationButton.setSelection(isAutoUpdate); + return composite; } @Override protected void performDefaults() { init(new ResolverConfiguration()); + autoUpdateConfigurationButton.setSelection(MavenPreferenceInitializer.P_AUTO_UPDATE_CONFIGURATION_DEFAULT); } - private void init(IProjectConfiguration configuration) { - + private void init(ResolverConfiguration configuration) { resolveWorspaceProjectsButton.setSelection(configuration.isResolveWorkspaceProjects()); // includeModulesButton.setSelection(configuration.shouldIncludeModules()); selectedProfilesText.setText(configuration.getSelectedProfiles()); @@ -130,11 +145,14 @@ public boolean performOk() { final ResolverConfiguration configuration = new ResolverConfiguration(getResolverConfiguration()); if(configuration.getSelectedProfiles().equals(selectedProfilesText.getText()) && // configuration.shouldIncludeModules()==includeModulesButton.getSelection() && - configuration.isResolveWorkspaceProjects() == resolveWorspaceProjectsButton.getSelection()) { + configuration.isResolveWorkspaceProjects() == resolveWorspaceProjectsButton.getSelection() + && ResolverConfigurationIO.isAutomaticallyUpdateConfiguration(project) == autoUpdateConfigurationButton + .getSelection()) { return true; } configuration.setResolveWorkspaceProjects(resolveWorspaceProjectsButton.getSelection()); + ResolverConfigurationIO.setAutomaticallyUpdateConfiguration(project, autoUpdateConfigurationButton.getSelection()); // configuration.setIncludeModules(includeModulesButton.getSelection()); configuration.setSelectedProfiles(selectedProfilesText.getText()); @@ -165,9 +183,9 @@ public IStatus runInWorkspace(IProgressMonitor monitor) { return isSet; } - private IProjectConfiguration getResolverConfiguration() { + private ResolverConfiguration getResolverConfiguration() { IProjectConfigurationManager projectManager = MavenPlugin.getProjectConfigurationManager(); - return projectManager.getProjectConfiguration(getProject()); + return (ResolverConfiguration) projectManager.getProjectConfiguration(getProject()); } private IProject getProject() { diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java index 28ee8d7088..a97a344e91 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java @@ -25,6 +25,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.internal.project.ResolverConfigurationIO; import org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob; @@ -40,10 +41,10 @@ public class MavenUpdateConfigurationChangeListener implements IResourceChangeLi @Override public void resourceChanged(IResourceChangeEvent event) { - if(isDisabled()) { + if(isAutoConfigurationUpdateDisabled()) { return; } - List outOfDateProjects = null; + List outOfDateProjects; try { OutOfDateConfigurationDeltaVisitor visitor = new OutOfDateConfigurationDeltaVisitor(); event.getDelta().accept(visitor); @@ -52,10 +53,12 @@ public void resourceChanged(IResourceChangeEvent event) { LOG.error("An error occurred while checking for out-of-date configuration markers", e); return; } + outOfDateProjects = outOfDateProjects.stream() // + .filter(ResolverConfigurationIO::isAutomaticallyUpdateConfiguration).toList(); updateProjectConfiguration(outOfDateProjects); } - private boolean isDisabled() { + public static boolean isAutoConfigurationUpdateDisabled() { return !MavenPlugin.getMavenConfiguration().isAutomaticallyUpdateConfiguration(); } diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java index e9707aee85..a49cdfe843 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java @@ -35,7 +35,7 @@ */ public class OutOfDateConfigurationDeltaVisitor implements IResourceDeltaVisitor { - List outOfDateProjects = new ArrayList<>(); + final List outOfDateProjects = new ArrayList<>(); @Override public boolean visit(IResourceDelta delta) throws CoreException { diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/preferences/MavenPreferenceInitializer.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/preferences/MavenPreferenceInitializer.java index 50ee405d53..335e1a7d30 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/preferences/MavenPreferenceInitializer.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/preferences/MavenPreferenceInitializer.java @@ -27,6 +27,8 @@ */ public class MavenPreferenceInitializer extends AbstractPreferenceInitializer { + public static final boolean P_AUTO_UPDATE_CONFIGURATION_DEFAULT = true; + @Override public void initializeDefaultPreferences() { IEclipsePreferences store = DefaultScope.INSTANCE.getNode(IMavenConstants.PLUGIN_ID); @@ -63,7 +65,7 @@ public void initializeDefaultPreferences() { // set to null since the plugin state location is not available by the time execution reaches here store.remove(MavenPreferenceConstants.P_WORKSPACE_MAPPINGS_LOCATION); - store.putBoolean(MavenPreferenceConstants.P_AUTO_UPDATE_CONFIGURATION, true); + store.putBoolean(MavenPreferenceConstants.P_AUTO_UPDATE_CONFIGURATION, P_AUTO_UPDATE_CONFIGURATION_DEFAULT); store.putBoolean(MavenPreferenceConstants.P_ENABLE_SNAPSHOT_ARCHETYPES, false); diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java index caf9d732b0..19f9f992ae 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java @@ -885,12 +885,16 @@ public void mavenProjectChanged(List events, IProgress if(facade != null) { ProblemSeverity outOfDateSeverity = ProblemSeverity.get(mavenConfiguration.getOutOfDateProjectSeverity()); - mavenMarkerManager.deleteMarkers(facade.getProject(), IMavenConstants.MARKER_CONFIGURATION_ID); + IProject project = facade.getProject(); + mavenMarkerManager.deleteMarkers(project, IMavenConstants.MARKER_CONFIGURATION_ID); if(!ProblemSeverity.ignore.equals(outOfDateSeverity)) { LifecycleMappingConfiguration oldConfiguration = LifecycleMappingConfiguration.restore(facade, monitor); if(oldConfiguration != null && LifecycleMappingFactory.isLifecycleMappingChanged(facade, oldConfiguration, monitor)) { - mavenMarkerManager.addMarker(facade.getProject(), IMavenConstants.MARKER_CONFIGURATION_ID, + if(!ResolverConfigurationIO.isAutomaticallyUpdateConfiguration(project)) { + outOfDateSeverity = ProblemSeverity.info; + } + mavenMarkerManager.addMarker(project, IMavenConstants.MARKER_CONFIGURATION_ID, Messages.ProjectConfigurationUpdateRequired, -1, outOfDateSeverity.getSeverity()); } } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java index b3e2d6976b..d1873e070d 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java @@ -30,10 +30,11 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; -import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.m2e.core.internal.IMavenConstants; import org.eclipse.m2e.core.internal.embedder.MavenProperties; +import org.eclipse.m2e.core.internal.preferences.MavenPreferenceConstants; +import org.eclipse.m2e.core.internal.preferences.MavenPreferenceInitializer; import org.eclipse.m2e.core.project.IProjectConfiguration; import org.eclipse.m2e.core.project.ResolverConfiguration; @@ -55,6 +56,8 @@ public class ResolverConfigurationIO { */ private static final String P_RESOLVE_WORKSPACE_PROJECTS = "resolveWorkspaceProjects"; //$NON-NLS-1$ + private static final String P_AUTO_UPDATE_CONFIGURATION = MavenPreferenceConstants.P_AUTO_UPDATE_CONFIGURATION; + /** * Active profiles project preference key. Value is comma-separated list of enabled profiles. */ @@ -82,13 +85,11 @@ public class ResolverConfigurationIO { private static final String VERSION = "1"; //$NON-NLS-1$ public static boolean saveResolverConfiguration(IProject project, IProjectConfiguration configuration) { - IScopeContext projectScope = new ProjectScope(project); - IEclipsePreferences projectNode = projectScope.getNode(IMavenConstants.PLUGIN_ID); + IEclipsePreferences projectNode = getMavenProjectPreferences(project); if(projectNode != null) { projectNode.put(P_VERSION, VERSION); projectNode.putBoolean(P_RESOLVE_WORKSPACE_PROJECTS, configuration.isResolveWorkspaceProjects()); - projectNode.put(P_SELECTED_PROFILES, configuration.getSelectedProfiles()); if(configuration.getLifecycleMappingId() != null) { @@ -101,21 +102,13 @@ public static boolean saveResolverConfiguration(IProject project, IProjectConfig } else { projectNode.remove(P_PROPERTIES); } - - try { - projectNode.flush(); - return true; - } catch(BackingStoreException ex) { - log.error("Failed to save resolver configuration", ex); - } + return savePreferences(projectNode); } - return false; } public static IProjectConfiguration readResolverConfiguration(IProject project) { - IScopeContext projectScope = new ProjectScope(project); - IEclipsePreferences projectNode = projectScope.getNode(IMavenConstants.PLUGIN_ID); + IEclipsePreferences projectNode = getMavenProjectPreferences(project); if(projectNode == null) { return new ResolverConfiguration(project); } @@ -132,6 +125,34 @@ public static IProjectConfiguration readResolverConfiguration(IProject project) return configuration; } + public static boolean isAutomaticallyUpdateConfiguration(IProject project) { + IEclipsePreferences preferences = getMavenProjectPreferences(project); + boolean defaultValue = MavenPreferenceInitializer.P_AUTO_UPDATE_CONFIGURATION_DEFAULT; + return preferences != null ? preferences.getBoolean(P_AUTO_UPDATE_CONFIGURATION, defaultValue) : defaultValue; + } + + public static void setAutomaticallyUpdateConfiguration(IProject project, boolean isAutomaticallyUpdateConfiguration) { + IEclipsePreferences preferences = getMavenProjectPreferences(project); + if(preferences != null) { + preferences.putBoolean(P_AUTO_UPDATE_CONFIGURATION, isAutomaticallyUpdateConfiguration); + savePreferences(preferences); + } + } + + private static IEclipsePreferences getMavenProjectPreferences(IProject project) { + return new ProjectScope(project).getNode(IMavenConstants.PLUGIN_ID); + } + + private static boolean savePreferences(IEclipsePreferences node) { + try { + node.flush(); + return true; + } catch(BackingStoreException ex) { + log.error("Failed to save resolver configuration", ex); + } + return false; + } + private static File getBasedir(IEclipsePreferences projectNode, IProject project) { String basedirSetting = projectNode.get(P_BASEDIR, null); if(basedirSetting != null) { @@ -144,9 +165,7 @@ private static File getBasedir(IEclipsePreferences projectNode, IProject project } private static String propertiesAsString(Map properties) { - String propAsString = properties.entrySet().stream().map(e -> encodeEntry(e)) - .collect(Collectors.joining(PROPERTIES_SEPARATOR)); - return propAsString; + return properties.entrySet().stream().map(e -> encodeEntry(e)).collect(Collectors.joining(PROPERTIES_SEPARATOR)); } private static Properties stringAsProperties(String properties) {