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/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..25120823eb 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 @@ -40,6 +40,7 @@ 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 +53,8 @@ public class MavenProjectPreferencePage extends PropertyPage { private Button resolveWorspaceProjectsButton; + private Button autoUpdateConfigurationButton; + // private Button includeModulesButton; private Text selectedProfilesText; @@ -74,10 +77,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; @@ -111,6 +122,7 @@ protected void performDefaults() { private void init(IProjectConfiguration configuration) { resolveWorspaceProjectsButton.setSelection(configuration.isResolveWorkspaceProjects()); + autoUpdateConfigurationButton.setSelection(configuration.isAutomaticallyUpdateConfiguration()); // includeModulesButton.setSelection(configuration.shouldIncludeModules()); selectedProfilesText.setText(configuration.getSelectedProfiles()); } @@ -130,11 +142,13 @@ 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() + && configuration.isAutomaticallyUpdateConfiguration() == autoUpdateConfigurationButton.getSelection()) { return true; } configuration.setResolveWorkspaceProjects(resolveWorspaceProjectsButton.getSelection()); + configuration.setAutomaticallyUpdateConfiguration(autoUpdateConfigurationButton.getSelection()); // configuration.setIncludeModules(includeModulesButton.getSelection()); configuration.setSelectedProfiles(selectedProfilesText.getText()); 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..ceab137f80 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,8 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.project.IProjectConfiguration; +import org.eclipse.m2e.core.project.IProjectConfigurationManager; import org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob; @@ -40,10 +42,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 +54,15 @@ public void resourceChanged(IResourceChangeEvent event) { LOG.error("An error occurred while checking for out-of-date configuration markers", e); return; } + IProjectConfigurationManager configManager = MavenPlugin.getProjectConfigurationManager(); + outOfDateProjects = outOfDateProjects.stream().filter(p -> { + IProjectConfiguration configuration = configManager.getProjectConfiguration(p); + return configuration.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/project/ProjectConfigurationManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java index caf9d732b0..d51614f24d 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(!getProjectConfiguration(project).isAutomaticallyUpdateConfiguration()) { + 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..4eaeebb32c 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 @@ -34,6 +34,7 @@ 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.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. */ @@ -88,6 +91,7 @@ public static boolean saveResolverConfiguration(IProject project, IProjectConfig projectNode.put(P_VERSION, VERSION); projectNode.putBoolean(P_RESOLVE_WORKSPACE_PROJECTS, configuration.isResolveWorkspaceProjects()); + projectNode.putBoolean(P_AUTO_UPDATE_CONFIGURATION, configuration.isAutomaticallyUpdateConfiguration()); projectNode.put(P_SELECTED_PROFILES, configuration.getSelectedProfiles()); @@ -125,6 +129,7 @@ public static IProjectConfiguration readResolverConfiguration(IProject project) } ResolverConfiguration configuration = new ResolverConfiguration(); configuration.setResolveWorkspaceProjects(projectNode.getBoolean(P_RESOLVE_WORKSPACE_PROJECTS, false)); + configuration.setAutomaticallyUpdateConfiguration(projectNode.getBoolean(P_AUTO_UPDATE_CONFIGURATION, true)); configuration.setSelectedProfiles(projectNode.get(P_SELECTED_PROFILES, "")); //$NON-NLS-1$ configuration.setLifecycleMappingId(projectNode.get(P_LIFECYCLE_MAPPING_ID, (String) null)); configuration.setProperties(stringAsProperties(projectNode.get(P_PROPERTIES, null))); @@ -144,9 +149,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) { diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenProjectFacade.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenProjectFacade.java index b04b0d6e35..e53688b0c2 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenProjectFacade.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/registry/MavenProjectFacade.java @@ -656,6 +656,8 @@ private static final class MavenProjectConfiguration implements IProjectConfigur private final boolean resolveWorkspace; + private final boolean automaticallyUpdateConfiguration; + private final String profiles; private final Map userProperties; @@ -674,6 +676,7 @@ private MavenProjectConfiguration(IProjectConfiguration baseConfiguration) { this.properties = Map.copyOf(baseConfiguration.getConfigurationProperties()); this.userProperties = Map.copyOf(baseConfiguration.getUserProperties()); this.resolveWorkspace = baseConfiguration.isResolveWorkspaceProjects(); + this.automaticallyUpdateConfiguration = baseConfiguration.isAutomaticallyUpdateConfiguration(); this.profiles = baseConfiguration.getSelectedProfiles(); this.activeProfiles = List.copyOf(baseConfiguration.getActiveProfileList()); this.inactiveProfiles = List.copyOf(baseConfiguration.getInactiveProfileList()); @@ -694,6 +697,11 @@ public boolean isResolveWorkspaceProjects() { return resolveWorkspace; } + @Override + public boolean isAutomaticallyUpdateConfiguration() { + return automaticallyUpdateConfiguration; + } + @Override public String getSelectedProfiles() { return profiles; diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IProjectConfiguration.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IProjectConfiguration.java index f9dd85a204..e81195eb30 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IProjectConfiguration.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/IProjectConfiguration.java @@ -44,6 +44,8 @@ public interface IProjectConfiguration { boolean isResolveWorkspaceProjects(); + boolean isAutomaticallyUpdateConfiguration(); + String getSelectedProfiles(); List getActiveProfileList(); @@ -62,10 +64,10 @@ public interface IProjectConfiguration { * @return */ public static int contentsHashCode(IProjectConfiguration configuration) { - return Objects.hash(configuration.isResolveWorkspaceProjects(), configuration.getActiveProfileList(), - configuration.getInactiveProfileList(), configuration.getLifecycleMappingId(), - configuration.getConfigurationProperties(), configuration.getUserProperties(), - configuration.getMultiModuleProjectDirectory()); + return Objects.hash(configuration.isResolveWorkspaceProjects(), configuration.isAutomaticallyUpdateConfiguration(), + configuration.getActiveProfileList(), configuration.getInactiveProfileList(), + configuration.getLifecycleMappingId(), configuration.getConfigurationProperties(), + configuration.getUserProperties(), configuration.getMultiModuleProjectDirectory()); } public static boolean contentsEquals(IProjectConfiguration configuration, IProjectConfiguration other) { @@ -76,6 +78,7 @@ public static boolean contentsEquals(IProjectConfiguration configuration, IProje return false; } return configuration.isResolveWorkspaceProjects() == other.isResolveWorkspaceProjects() + && configuration.isAutomaticallyUpdateConfiguration() == other.isAutomaticallyUpdateConfiguration() && Objects.equals(configuration.getLifecycleMappingId(), other.getLifecycleMappingId()) && Objects.equals(configuration.getActiveProfileList(), other.getActiveProfileList()) && Objects.equals(configuration.getInactiveProfileList(), other.getInactiveProfileList()) diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java index 3a325938cb..9dc2b7e7da 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java @@ -48,6 +48,8 @@ public class ResolverConfiguration implements Serializable, IProjectConfiguratio private boolean resolveWorkspaceProjects = true; + private boolean automaticallyUpdateConfiguration = true; + private String selectedProfiles = ""; //$NON-NLS-1$ private String lifecycleMappingId; @@ -83,6 +85,7 @@ public ResolverConfiguration(IProjectConfiguration resolverConfiguration) { properties2.putAll(resolverConfiguration.getConfigurationProperties()); setProperties(properties2); setResolveWorkspaceProjects(resolverConfiguration.isResolveWorkspaceProjects()); + setAutomaticallyUpdateConfiguration(resolverConfiguration.isAutomaticallyUpdateConfiguration()); setSelectedProfiles(resolverConfiguration.getSelectedProfiles()); } @@ -134,6 +137,11 @@ public boolean isResolveWorkspaceProjects() { return this.resolveWorkspaceProjects; } + @Override + public boolean isAutomaticallyUpdateConfiguration() { + return this.automaticallyUpdateConfiguration; + } + /* (non-Javadoc) * @see org.eclipse.m2e.core.project.IProjectConfiguration#getSelectedProfiles() */ @@ -146,6 +154,10 @@ public void setResolveWorkspaceProjects(boolean resolveWorkspaceProjects) { this.resolveWorkspaceProjects = resolveWorkspaceProjects; } + public void setAutomaticallyUpdateConfiguration(boolean automaticallyUpdateConfiguration) { + this.automaticallyUpdateConfiguration = automaticallyUpdateConfiguration; + } + public void setSelectedProfiles(String profiles) { this.selectedProfiles = profiles; this.activeProfiles = parseProfiles(profiles, true);