Skip to content

Commit 6f195b7

Browse files
committed
Support loading of settings from other locations
Currently there is only one cached settings object for the all projects but it is possible for projects to carry individual settings. This now enhances the settings handling in a way to support providing a composite key of global and local settings to be loaded an cached.
1 parent 830c305 commit 6f195b7

File tree

5 files changed

+141
-57
lines changed

5 files changed

+141
-57
lines changed

org.eclipse.m2e.core/src/org/eclipse/m2e/core/embedder/IMaven.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ <T> T getMojoParameterValue(MavenProject project, String parameter, Class<T> typ
187187
*/
188188
Settings getSettings() throws CoreException;
189189

190+
Settings getSettings(MavenSettingsLocations locations) throws CoreException;
191+
190192
String getLocalRepositoryPath();
191193

192194
ArtifactRepository getLocalRepository() throws CoreException;
@@ -209,6 +211,10 @@ <T> T getMojoParameterValue(MavenProject project, String parameter, Class<T> typ
209211

210212
List<ArtifactRepository> getPluginArtifactRepositories(boolean injectSettings) throws CoreException;
211213

214+
/**
215+
* @deprecated use {@link #getSettings(MavenSettingsLocations)} instead
216+
*/
217+
@Deprecated(forRemoval = true)
212218
Settings buildSettings(String globalSettings, String userSettings) throws CoreException;
213219

214220
void writeSettings(Settings settings, OutputStream out) throws CoreException;

org.eclipse.m2e.core/src/org/eclipse/m2e/core/embedder/IMavenConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ public interface IMavenConfiguration {
134134
*/
135135
boolean buildWithNullSchedulingRule();
136136

137+
MavenSettingsLocations getSettingsLocations();
138+
137139
static IMavenConfiguration getWorkspaceConfiguration() {
138140
MavenPluginActivator activator = MavenPluginActivator.getDefault();
139141
if(activator == null) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/********************************************************************************
2+
* Copyright (c) 2024 Christoph Läubrich and others
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Christoph Läubrich - initial API and implementation
12+
********************************************************************************/
13+
14+
package org.eclipse.m2e.core.embedder;
15+
16+
import java.io.File;
17+
18+
19+
/**
20+
* This recored encapsulates the combination of a global and a user settings files as defined in
21+
* https://maven.apache.org/settings.html
22+
*/
23+
public record MavenSettingsLocations(File globalSettings, File userSettings) {
24+
25+
}

org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java

Lines changed: 86 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
package org.eclipse.m2e.core.internal.embedder;
1717

18-
import static org.eclipse.m2e.core.internal.M2EUtils.copyProperties;
19-
2018
import java.io.BufferedInputStream;
2119
import java.io.BufferedOutputStream;
2220
import java.io.File;
@@ -36,6 +34,7 @@
3634
import java.util.Objects;
3735
import java.util.Properties;
3836
import java.util.Set;
37+
import java.util.concurrent.ConcurrentHashMap;
3938
import java.util.concurrent.CopyOnWriteArrayList;
4039

4140
import org.osgi.service.component.annotations.Component;
@@ -138,14 +137,17 @@
138137
import org.apache.maven.wagon.proxy.ProxyInfo;
139138

140139
import org.eclipse.m2e.core.embedder.ICallable;
140+
import org.eclipse.m2e.core.embedder.IComponentLookup;
141141
import org.eclipse.m2e.core.embedder.ILocalRepositoryListener;
142142
import org.eclipse.m2e.core.embedder.IMaven;
143143
import org.eclipse.m2e.core.embedder.IMavenConfiguration;
144144
import org.eclipse.m2e.core.embedder.IMavenConfigurationChangeListener;
145145
import org.eclipse.m2e.core.embedder.IMavenExecutionContext;
146146
import org.eclipse.m2e.core.embedder.ISettingsChangeListener;
147147
import org.eclipse.m2e.core.embedder.MavenConfigurationChangeEvent;
148+
import org.eclipse.m2e.core.embedder.MavenSettingsLocations;
148149
import org.eclipse.m2e.core.internal.IMavenConstants;
150+
import org.eclipse.m2e.core.internal.M2EUtils;
149151
import org.eclipse.m2e.core.internal.Messages;
150152
import org.eclipse.m2e.core.internal.preferences.MavenPreferenceConstants;
151153

@@ -169,15 +171,9 @@ public class MavenImpl implements IMaven, IMavenConfigurationChangeListener {
169171
private PlexusContainerManager containerManager;
170172

171173
/**
172-
* Cached parsed settings.xml instance
174+
* Cached parsed settingsCacheMap.xml instance
173175
*/
174-
private Settings settings;
175-
176-
/** File length of cached user settings */
177-
private long settingsLength;
178-
179-
/** Last modified timestamp of cached user settings */
180-
private long settingsTimestamp;
176+
private Map<MavenSettingsLocations, MavenSettings> settingsCacheMap = new ConcurrentHashMap<>();
181177

182178
@Override
183179
public String getLocalRepositoryPath() {
@@ -274,54 +270,13 @@ public ArtifactRepository getLocalRepository() throws CoreException {
274270

275271
@Override
276272
public Settings getSettings() throws CoreException {
277-
return getSettings(false);
273+
return getSettings(mavenConfiguration.getSettingsLocations());
278274
}
279275

280-
public synchronized Settings getSettings(boolean forceReload) throws CoreException {
281-
// MUST NOT use createRequest!
282-
283-
File userSettingsFile = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE;
284-
if(mavenConfiguration.getUserSettingsFile() != null) {
285-
userSettingsFile = new File(mavenConfiguration.getUserSettingsFile());
286-
}
287-
288-
boolean reload = forceReload || settings == null;
289-
290-
if(!reload && userSettingsFile != null) {
291-
reload = userSettingsFile.lastModified() != settingsTimestamp || userSettingsFile.length() != settingsLength;
292-
}
293-
294-
if(reload) {
295-
// TODO: Can't that delegate to buildSettings()?
296-
SettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
297-
// 440696 guard against ConcurrentModificationException
298-
Properties systemProperties = new Properties();
299-
copyProperties(systemProperties, System.getProperties());
300-
request.setSystemProperties(systemProperties);
301-
if(mavenConfiguration.getGlobalSettingsFile() != null) {
302-
request.setGlobalSettingsFile(new File(mavenConfiguration.getGlobalSettingsFile()));
303-
}
304-
if(userSettingsFile != null) {
305-
request.setUserSettingsFile(userSettingsFile);
306-
}
307-
try {
308-
settings = lookup(SettingsBuilder.class).build(request).getEffectiveSettings();
309-
} catch(SettingsBuildingException ex) {
310-
String msg = "Could not read settings.xml, assuming default values";
311-
log.error(msg, ex);
312-
/*
313-
* NOTE: This method provides input for various other core functions, just bailing out would make m2e highly
314-
* unusuable. Instead, we fail gracefully and just ignore the broken settings, using defaults.
315-
*/
316-
settings = new Settings();
317-
}
318-
319-
if(userSettingsFile != null) {
320-
settingsLength = userSettingsFile.length();
321-
settingsTimestamp = userSettingsFile.lastModified();
322-
}
323-
}
324-
return settings;
276+
@Override
277+
public Settings getSettings(MavenSettingsLocations locations) throws CoreException {
278+
MavenSettings cache = settingsCacheMap.computeIfAbsent(locations, key -> new MavenSettings(key, MavenImpl.this));
279+
return cache.getSettings();
325280
}
326281

327282
@Override
@@ -372,7 +327,8 @@ public List<SettingsProblem> validateSettings(String settings) {
372327

373328
@Override
374329
public void reloadSettings() throws CoreException {
375-
Settings reloadedSettings = getSettings(true);
330+
settingsCacheMap.clear();
331+
Settings reloadedSettings = getSettings(mavenConfiguration.getSettingsLocations());
376332
for(ISettingsChangeListener listener : settingsListeners) {
377333
try {
378334
listener.settingsChanged(reloadedSettings);
@@ -1103,4 +1059,77 @@ public MavenExecutionContext createExecutionContext() {
11031059
return new MavenExecutionContext(this, null, null);
11041060
}
11051061

1062+
private static final class MavenSettings {
1063+
private long userSettingsLength;
1064+
1065+
private long userSettingsTimestamp;
1066+
1067+
private long globalSettingsLength;
1068+
1069+
private long globalSettingsTimestamp;
1070+
1071+
private MavenSettingsLocations locations;
1072+
1073+
private Settings settings;
1074+
1075+
private IComponentLookup lookup;
1076+
1077+
public MavenSettings(MavenSettingsLocations locations, IComponentLookup lookup) {
1078+
this.locations = locations;
1079+
this.lookup = lookup;
1080+
}
1081+
1082+
private synchronized Settings getSettings() throws CoreException {
1083+
File global = locations.globalSettings();
1084+
long gs;
1085+
long gt;
1086+
if(global != null && global.isFile()) {
1087+
gs = global.length();
1088+
gt = global.lastModified();
1089+
} else {
1090+
gs = -1;
1091+
gt = -1;
1092+
}
1093+
File user = locations.userSettings();
1094+
long us;
1095+
long ut;
1096+
if(user != null && user.isFile()) {
1097+
us = user.length();
1098+
ut = user.lastModified();
1099+
} else {
1100+
us = -1;
1101+
ut = -1;
1102+
}
1103+
boolean reload = settings == null || gs != globalSettingsLength || gt != globalSettingsTimestamp
1104+
|| us != userSettingsLength || ut != userSettingsTimestamp;
1105+
if(reload) {
1106+
SettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
1107+
Properties systemProperties = new Properties();
1108+
M2EUtils.copyProperties(systemProperties, System.getProperties());
1109+
request.setSystemProperties(systemProperties);
1110+
if(global != null) {
1111+
request.setGlobalSettingsFile(global);
1112+
}
1113+
if(user != null) {
1114+
request.setUserSettingsFile(user);
1115+
}
1116+
try {
1117+
settings = lookup.lookup(SettingsBuilder.class).build(request).getEffectiveSettings();
1118+
} catch(SettingsBuildingException ex) {
1119+
log.error("Could not read settingsCacheMap.xml, assuming default values", ex);
1120+
/*
1121+
* NOTE: This method provides input for various other core functions, just bailing out would make m2e highly
1122+
* unusable. Instead, we fail gracefully and just ignore the broken settingsCacheMap, using defaults.
1123+
*/
1124+
settings = new Settings();
1125+
}
1126+
globalSettingsLength = gs;
1127+
globalSettingsTimestamp = gt;
1128+
userSettingsLength = us;
1129+
userSettingsTimestamp = ut;
1130+
}
1131+
return settings;
1132+
}
1133+
}
1134+
11061135
}

org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/preferences/MavenConfigurationImpl.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
package org.eclipse.m2e.core.internal.preferences;
1515

16+
import java.io.File;
1617
import java.util.Map;
1718
import java.util.Objects;
1819

@@ -41,10 +42,12 @@
4142
import org.eclipse.core.runtime.preferences.PreferenceFilterEntry;
4243

4344
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
45+
import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor;
4446

4547
import org.eclipse.m2e.core.embedder.IMavenConfiguration;
4648
import org.eclipse.m2e.core.embedder.IMavenConfigurationChangeListener;
4749
import org.eclipse.m2e.core.embedder.MavenConfigurationChangeEvent;
50+
import org.eclipse.m2e.core.embedder.MavenSettingsLocations;
4851
import org.eclipse.m2e.core.internal.IMavenConstants;
4952
import org.eclipse.m2e.core.internal.MavenPluginActivator;
5053
import org.eclipse.m2e.core.internal.lifecyclemapping.LifecycleMappingFactory;
@@ -206,6 +209,25 @@ public void preferenceChange(PreferenceChangeEvent event) {
206209
}
207210
}
208211

212+
@Override
213+
public MavenSettingsLocations getSettingsLocations() {
214+
File userSettings;
215+
File globalSettings;
216+
String configSettingsFile = getUserSettingsFile();
217+
if (configSettingsFile==null) {
218+
userSettings = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE;
219+
} else {
220+
userSettings = new File(configSettingsFile);
221+
}
222+
String configGlobalSettingsFile = getGlobalSettingsFile();
223+
if(configGlobalSettingsFile == null) {
224+
globalSettings = null;
225+
} else {
226+
globalSettings = new File(configGlobalSettingsFile);
227+
}
228+
return new MavenSettingsLocations(globalSettings, userSettings);
229+
}
230+
209231
@Override
210232
public void added(NodeChangeEvent event) {
211233
}

0 commit comments

Comments
 (0)