1515
1616package org .eclipse .m2e .core .internal .embedder ;
1717
18- import static org .eclipse .m2e .core .internal .M2EUtils .copyProperties ;
19-
2018import java .io .BufferedInputStream ;
2119import java .io .BufferedOutputStream ;
2220import java .io .File ;
3634import java .util .Objects ;
3735import java .util .Properties ;
3836import java .util .Set ;
37+ import java .util .concurrent .ConcurrentHashMap ;
3938import java .util .concurrent .CopyOnWriteArrayList ;
4039
4140import org .osgi .service .component .annotations .Component ;
138137import org .apache .maven .wagon .proxy .ProxyInfo ;
139138
140139import org .eclipse .m2e .core .embedder .ICallable ;
140+ import org .eclipse .m2e .core .embedder .IComponentLookup ;
141141import org .eclipse .m2e .core .embedder .ILocalRepositoryListener ;
142142import org .eclipse .m2e .core .embedder .IMaven ;
143143import org .eclipse .m2e .core .embedder .IMavenConfiguration ;
144144import org .eclipse .m2e .core .embedder .IMavenConfigurationChangeListener ;
145145import org .eclipse .m2e .core .embedder .IMavenExecutionContext ;
146146import org .eclipse .m2e .core .embedder .ISettingsChangeListener ;
147147import org .eclipse .m2e .core .embedder .MavenConfigurationChangeEvent ;
148+ import org .eclipse .m2e .core .embedder .MavenSettingsLocations ;
148149import org .eclipse .m2e .core .internal .IMavenConstants ;
150+ import org .eclipse .m2e .core .internal .M2EUtils ;
149151import org .eclipse .m2e .core .internal .Messages ;
150152import 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}
0 commit comments