View Javadoc
1   // =================== DO NOT EDIT THIS FILE ====================
2   //  Generated by Modello Velocity from merger.vm
3   //  template, any modifications will be overwritten.
4   // ==============================================================
5   package org.apache.maven.settings.v4;
6   
7   import java.io.ObjectStreamException;
8   import java.util.AbstractList;
9   import java.util.ArrayList;
10  import java.util.Collection;
11  import java.util.HashMap;
12  import java.util.Iterator;
13  import java.util.LinkedHashMap;
14  import java.util.List;
15  import java.util.Map;
16  import java.util.Objects;
17  import java.util.function.BinaryOperator;
18  import java.util.function.Function;
19  import java.util.stream.Collectors;
20  
21  import org.apache.maven.api.annotations.Generated;
22  import org.apache.maven.api.xml.XmlNode;
23  import org.apache.maven.api.settings.TrackableBase;
24  import org.apache.maven.api.settings.IdentifiableBase;
25  import org.apache.maven.api.settings.Settings;
26  import org.apache.maven.api.settings.Proxy;
27  import org.apache.maven.api.settings.Server;
28  import org.apache.maven.api.settings.Mirror;
29  import org.apache.maven.api.settings.Profile;
30  import org.apache.maven.api.settings.Activation;
31  import org.apache.maven.api.settings.RepositoryBase;
32  import org.apache.maven.api.settings.Repository;
33  import org.apache.maven.api.settings.RepositoryPolicy;
34  import org.apache.maven.api.settings.ActivationProperty;
35  import org.apache.maven.api.settings.ActivationOS;
36  import org.apache.maven.api.settings.ActivationFile;
37  import org.apache.maven.api.settings.InputLocation;
38  import org.apache.maven.api.settings.InputSource;
39  
40  @Generated
41  public class SettingsMerger {
42  
43      private final boolean deepMerge;
44  
45      public SettingsMerger() {
46          this(true);
47      }
48  
49      public SettingsMerger(boolean deepMerge) {
50          this.deepMerge = deepMerge;
51      }
52  
53      /**
54       * Merges the specified source object into the given target object.
55       *
56       * @param target The target object whose existing contents should be merged with the source, must not be
57       *            <code>null</code>.
58       * @param source The (read-only) source object that should be merged into the target object, may be
59       *            <code>null</code>.
60       * @param sourceDominant A flag indicating whether either the target object or the source object provides the
61       *            dominant data.
62       * @param hints A set of key-value pairs that customized merger implementations can use to carry domain-specific
63       *            information along, may be <code>null</code>.
64       */
65      public Settings merge(Settings target, Settings source, boolean sourceDominant, Map<?, ?> hints) {
66          Objects.requireNonNull(target, "target cannot be null");
67          if (source == null) {
68              return target;
69          }
70          Map<Object, Object> context = new HashMap<>();
71          if (hints != null) {
72              context.putAll(hints);
73          }
74          return mergeSettings(target, source, sourceDominant, context);
75      }
76  
77      protected TrackableBase mergeTrackableBase(TrackableBase target, TrackableBase source, boolean sourceDominant, Map<Object, Object> context) {
78          TrackableBase.Builder builder = TrackableBase.newBuilder(target);
79          mergeTrackableBase(builder, target, source, sourceDominant, context);
80          return builder.build();
81      }
82  
83      protected void mergeTrackableBase(TrackableBase.Builder builder, TrackableBase target, TrackableBase source, boolean sourceDominant, Map<Object, Object> context) {
84      }
85  
86  
87      protected IdentifiableBase mergeIdentifiableBase(IdentifiableBase target, IdentifiableBase source, boolean sourceDominant, Map<Object, Object> context) {
88          IdentifiableBase.Builder builder = IdentifiableBase.newBuilder(target);
89          mergeIdentifiableBase(builder, target, source, sourceDominant, context);
90          return builder.build();
91      }
92  
93      protected void mergeIdentifiableBase(IdentifiableBase.Builder builder, IdentifiableBase target, IdentifiableBase source, boolean sourceDominant, Map<Object, Object> context) {
94          mergeTrackableBase(builder, target, source, sourceDominant, context);
95          mergeIdentifiableBase_Id(builder, target, source, sourceDominant, context);
96      }
97  
98      protected void mergeIdentifiableBase_Id(IdentifiableBase.Builder builder, IdentifiableBase target, IdentifiableBase source, boolean sourceDominant, Map<Object, Object> context) {
99          String src = source.getId();
100         String tgt = target.getId();
101         if (src != null && (sourceDominant || tgt == null)) {
102             builder.id(src);
103             builder.location("id", source.getLocation("id"));
104         }
105     }
106 
107     protected Settings mergeSettings(Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
108         Settings.Builder builder = Settings.newBuilder(target);
109         mergeSettings(builder, target, source, sourceDominant, context);
110         return builder.build();
111     }
112 
113     protected void mergeSettings(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
114         mergeTrackableBase(builder, target, source, sourceDominant, context);
115         mergeSettings_LocalRepository(builder, target, source, sourceDominant, context);
116         mergeSettings_InteractiveMode(builder, target, source, sourceDominant, context);
117         mergeSettings_UsePluginRegistry(builder, target, source, sourceDominant, context);
118         mergeSettings_Offline(builder, target, source, sourceDominant, context);
119         mergeSettings_Proxies(builder, target, source, sourceDominant, context);
120         mergeSettings_Servers(builder, target, source, sourceDominant, context);
121         mergeSettings_Mirrors(builder, target, source, sourceDominant, context);
122         mergeSettings_Repositories(builder, target, source, sourceDominant, context);
123         mergeSettings_PluginRepositories(builder, target, source, sourceDominant, context);
124         mergeSettings_Profiles(builder, target, source, sourceDominant, context);
125         mergeSettings_ActiveProfiles(builder, target, source, sourceDominant, context);
126         mergeSettings_PluginGroups(builder, target, source, sourceDominant, context);
127     }
128 
129     protected void mergeSettings_LocalRepository(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
130         String src = source.getLocalRepository();
131         String tgt = target.getLocalRepository();
132         if (src != null && (sourceDominant || tgt == null)) {
133             builder.localRepository(src);
134             builder.location("localRepository", source.getLocation("localRepository"));
135         }
136     }
137     protected void mergeSettings_InteractiveMode(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
138         if (sourceDominant) {
139             builder.interactiveMode(source.isInteractiveMode());
140         }
141     }
142     protected void mergeSettings_UsePluginRegistry(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
143         if (sourceDominant) {
144             builder.usePluginRegistry(source.isUsePluginRegistry());
145         }
146     }
147     protected void mergeSettings_Offline(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
148         if (sourceDominant) {
149             builder.offline(source.isOffline());
150         }
151     }
152     protected void mergeSettings_Proxies(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
153         if (deepMerge) {
154             builder.proxies(merge(target.getProxies(), source.getProxies(), getProxyKey(),
155                     (t, s) -> mergeProxy(t, s, sourceDominant, context)));
156         } else {
157             builder.proxies(merge(target.getProxies(), source.getProxies(), sourceDominant, getProxyKey()));
158         }
159     }
160     protected void mergeSettings_Servers(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
161         if (deepMerge) {
162             builder.servers(merge(target.getServers(), source.getServers(), getServerKey(),
163                     (t, s) -> mergeServer(t, s, sourceDominant, context)));
164         } else {
165             builder.servers(merge(target.getServers(), source.getServers(), sourceDominant, getServerKey()));
166         }
167     }
168     protected void mergeSettings_Mirrors(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
169         if (deepMerge) {
170             builder.mirrors(merge(target.getMirrors(), source.getMirrors(), getMirrorKey(),
171                     (t, s) -> mergeMirror(t, s, sourceDominant, context)));
172         } else {
173             builder.mirrors(merge(target.getMirrors(), source.getMirrors(), sourceDominant, getMirrorKey()));
174         }
175     }
176     protected void mergeSettings_Repositories(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
177         if (deepMerge) {
178             builder.repositories(merge(target.getRepositories(), source.getRepositories(), getRepositoryKey(),
179                     (t, s) -> mergeRepository(t, s, sourceDominant, context)));
180         } else {
181             builder.repositories(merge(target.getRepositories(), source.getRepositories(), sourceDominant, getRepositoryKey()));
182         }
183     }
184     protected void mergeSettings_PluginRepositories(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
185         if (deepMerge) {
186             builder.pluginRepositories(merge(target.getPluginRepositories(), source.getPluginRepositories(), getRepositoryKey(),
187                     (t, s) -> mergeRepository(t, s, sourceDominant, context)));
188         } else {
189             builder.pluginRepositories(merge(target.getPluginRepositories(), source.getPluginRepositories(), sourceDominant, getRepositoryKey()));
190         }
191     }
192     protected void mergeSettings_Profiles(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
193         if (deepMerge) {
194             builder.profiles(merge(target.getProfiles(), source.getProfiles(), getProfileKey(),
195                     (t, s) -> mergeProfile(t, s, sourceDominant, context)));
196         } else {
197             builder.profiles(merge(target.getProfiles(), source.getProfiles(), sourceDominant, getProfileKey()));
198         }
199     }
200     protected void mergeSettings_ActiveProfiles(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
201         builder.activeProfiles(merge(target.getActiveProfiles(), source.getActiveProfiles(), sourceDominant, e -> e));
202     }
203     protected void mergeSettings_PluginGroups(Settings.Builder builder, Settings target, Settings source, boolean sourceDominant, Map<Object, Object> context) {
204         builder.pluginGroups(merge(target.getPluginGroups(), source.getPluginGroups(), sourceDominant, e -> e));
205     }
206 
207     protected Proxy mergeProxy(Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
208         Proxy.Builder builder = Proxy.newBuilder(target);
209         mergeProxy(builder, target, source, sourceDominant, context);
210         return builder.build();
211     }
212 
213     protected void mergeProxy(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
214         mergeIdentifiableBase(builder, target, source, sourceDominant, context);
215         mergeProxy_ActiveString(builder, target, source, sourceDominant, context);
216         mergeProxy_Protocol(builder, target, source, sourceDominant, context);
217         mergeProxy_Username(builder, target, source, sourceDominant, context);
218         mergeProxy_Password(builder, target, source, sourceDominant, context);
219         mergeProxy_PortString(builder, target, source, sourceDominant, context);
220         mergeProxy_Host(builder, target, source, sourceDominant, context);
221         mergeProxy_NonProxyHosts(builder, target, source, sourceDominant, context);
222     }
223 
224     protected void mergeProxy_Id(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
225         String src = source.getId();
226         String tgt = target.getId();
227         if (src != null && (sourceDominant || tgt == null)) {
228             builder.id(src);
229             builder.location("id", source.getLocation("id"));
230         }
231     }
232     protected void mergeProxy_ActiveString(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
233         String src = source.getActiveString();
234         String tgt = target.getActiveString();
235         if (src != null && (sourceDominant || tgt == null)) {
236             builder.activeString(src);
237             builder.location("activeString", source.getLocation("activeString"));
238         }
239     }
240     protected void mergeProxy_Protocol(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
241         String src = source.getProtocol();
242         String tgt = target.getProtocol();
243         if (src != null && (sourceDominant || tgt == null)) {
244             builder.protocol(src);
245             builder.location("protocol", source.getLocation("protocol"));
246         }
247     }
248     protected void mergeProxy_Username(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
249         String src = source.getUsername();
250         String tgt = target.getUsername();
251         if (src != null && (sourceDominant || tgt == null)) {
252             builder.username(src);
253             builder.location("username", source.getLocation("username"));
254         }
255     }
256     protected void mergeProxy_Password(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
257         String src = source.getPassword();
258         String tgt = target.getPassword();
259         if (src != null && (sourceDominant || tgt == null)) {
260             builder.password(src);
261             builder.location("password", source.getLocation("password"));
262         }
263     }
264     protected void mergeProxy_PortString(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
265         String src = source.getPortString();
266         String tgt = target.getPortString();
267         if (src != null && (sourceDominant || tgt == null)) {
268             builder.portString(src);
269             builder.location("portString", source.getLocation("portString"));
270         }
271     }
272     protected void mergeProxy_Host(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
273         String src = source.getHost();
274         String tgt = target.getHost();
275         if (src != null && (sourceDominant || tgt == null)) {
276             builder.host(src);
277             builder.location("host", source.getLocation("host"));
278         }
279     }
280     protected void mergeProxy_NonProxyHosts(Proxy.Builder builder, Proxy target, Proxy source, boolean sourceDominant, Map<Object, Object> context) {
281         String src = source.getNonProxyHosts();
282         String tgt = target.getNonProxyHosts();
283         if (src != null && (sourceDominant || tgt == null)) {
284             builder.nonProxyHosts(src);
285             builder.location("nonProxyHosts", source.getLocation("nonProxyHosts"));
286         }
287     }
288 
289     protected Server mergeServer(Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
290         Server.Builder builder = Server.newBuilder(target);
291         mergeServer(builder, target, source, sourceDominant, context);
292         return builder.build();
293     }
294 
295     protected void mergeServer(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
296         mergeIdentifiableBase(builder, target, source, sourceDominant, context);
297         mergeServer_Username(builder, target, source, sourceDominant, context);
298         mergeServer_Password(builder, target, source, sourceDominant, context);
299         mergeServer_PrivateKey(builder, target, source, sourceDominant, context);
300         mergeServer_Passphrase(builder, target, source, sourceDominant, context);
301         mergeServer_FilePermissions(builder, target, source, sourceDominant, context);
302         mergeServer_DirectoryPermissions(builder, target, source, sourceDominant, context);
303         mergeServer_Configuration(builder, target, source, sourceDominant, context);
304     }
305 
306     protected void mergeServer_Id(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
307         String src = source.getId();
308         String tgt = target.getId();
309         if (src != null && (sourceDominant || tgt == null)) {
310             builder.id(src);
311             builder.location("id", source.getLocation("id"));
312         }
313     }
314     protected void mergeServer_Username(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
315         String src = source.getUsername();
316         String tgt = target.getUsername();
317         if (src != null && (sourceDominant || tgt == null)) {
318             builder.username(src);
319             builder.location("username", source.getLocation("username"));
320         }
321     }
322     protected void mergeServer_Password(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
323         String src = source.getPassword();
324         String tgt = target.getPassword();
325         if (src != null && (sourceDominant || tgt == null)) {
326             builder.password(src);
327             builder.location("password", source.getLocation("password"));
328         }
329     }
330     protected void mergeServer_PrivateKey(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
331         String src = source.getPrivateKey();
332         String tgt = target.getPrivateKey();
333         if (src != null && (sourceDominant || tgt == null)) {
334             builder.privateKey(src);
335             builder.location("privateKey", source.getLocation("privateKey"));
336         }
337     }
338     protected void mergeServer_Passphrase(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
339         String src = source.getPassphrase();
340         String tgt = target.getPassphrase();
341         if (src != null && (sourceDominant || tgt == null)) {
342             builder.passphrase(src);
343             builder.location("passphrase", source.getLocation("passphrase"));
344         }
345     }
346     protected void mergeServer_FilePermissions(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
347         String src = source.getFilePermissions();
348         String tgt = target.getFilePermissions();
349         if (src != null && (sourceDominant || tgt == null)) {
350             builder.filePermissions(src);
351             builder.location("filePermissions", source.getLocation("filePermissions"));
352         }
353     }
354     protected void mergeServer_DirectoryPermissions(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
355         String src = source.getDirectoryPermissions();
356         String tgt = target.getDirectoryPermissions();
357         if (src != null && (sourceDominant || tgt == null)) {
358             builder.directoryPermissions(src);
359             builder.location("directoryPermissions", source.getLocation("directoryPermissions"));
360         }
361     }
362     protected void mergeServer_Configuration(Server.Builder builder, Server target, Server source, boolean sourceDominant, Map<Object, Object> context) {
363         XmlNode src = source.getConfiguration();
364         if (src != null) {
365             XmlNode tgt = target.getConfiguration();
366             if (tgt == null) {
367                 builder.configuration(src);
368                 builder.location("configuration", source.getLocation("configuration"));
369             } else if (sourceDominant) {
370                 builder.configuration(src.merge(tgt));
371                 builder.location("configuration", target.getLocation("configuration"));
372             } else {
373                 builder.configuration(tgt.merge(src));
374                 builder.location("configuration", null);
375             }
376         }
377     }
378 
379     protected Mirror mergeMirror(Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
380         Mirror.Builder builder = Mirror.newBuilder(target);
381         mergeMirror(builder, target, source, sourceDominant, context);
382         return builder.build();
383     }
384 
385     protected void mergeMirror(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
386         mergeIdentifiableBase(builder, target, source, sourceDominant, context);
387         mergeMirror_MirrorOf(builder, target, source, sourceDominant, context);
388         mergeMirror_Name(builder, target, source, sourceDominant, context);
389         mergeMirror_Url(builder, target, source, sourceDominant, context);
390         mergeMirror_Layout(builder, target, source, sourceDominant, context);
391         mergeMirror_MirrorOfLayouts(builder, target, source, sourceDominant, context);
392         mergeMirror_Blocked(builder, target, source, sourceDominant, context);
393     }
394 
395     protected void mergeMirror_Id(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
396         String src = source.getId();
397         String tgt = target.getId();
398         if (src != null && (sourceDominant || tgt == null)) {
399             builder.id(src);
400             builder.location("id", source.getLocation("id"));
401         }
402     }
403     protected void mergeMirror_MirrorOf(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
404         String src = source.getMirrorOf();
405         String tgt = target.getMirrorOf();
406         if (src != null && (sourceDominant || tgt == null)) {
407             builder.mirrorOf(src);
408             builder.location("mirrorOf", source.getLocation("mirrorOf"));
409         }
410     }
411     protected void mergeMirror_Name(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
412         String src = source.getName();
413         String tgt = target.getName();
414         if (src != null && (sourceDominant || tgt == null)) {
415             builder.name(src);
416             builder.location("name", source.getLocation("name"));
417         }
418     }
419     protected void mergeMirror_Url(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
420         String src = source.getUrl();
421         String tgt = target.getUrl();
422         if (src != null && (sourceDominant || tgt == null)) {
423             builder.url(src);
424             builder.location("url", source.getLocation("url"));
425         }
426     }
427     protected void mergeMirror_Layout(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
428         String src = source.getLayout();
429         String tgt = target.getLayout();
430         if (src != null && (sourceDominant || tgt == null)) {
431             builder.layout(src);
432             builder.location("layout", source.getLocation("layout"));
433         }
434     }
435     protected void mergeMirror_MirrorOfLayouts(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
436         String src = source.getMirrorOfLayouts();
437         String tgt = target.getMirrorOfLayouts();
438         if (src != null && (sourceDominant || tgt == null)) {
439             builder.mirrorOfLayouts(src);
440             builder.location("mirrorOfLayouts", source.getLocation("mirrorOfLayouts"));
441         }
442     }
443     protected void mergeMirror_Blocked(Mirror.Builder builder, Mirror target, Mirror source, boolean sourceDominant, Map<Object, Object> context) {
444         if (sourceDominant) {
445             builder.blocked(source.isBlocked());
446         }
447     }
448 
449     protected Profile mergeProfile(Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context) {
450         Profile.Builder builder = Profile.newBuilder(target);
451         mergeProfile(builder, target, source, sourceDominant, context);
452         return builder.build();
453     }
454 
455     protected void mergeProfile(Profile.Builder builder, Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context) {
456         mergeIdentifiableBase(builder, target, source, sourceDominant, context);
457         mergeProfile_Activation(builder, target, source, sourceDominant, context);
458         mergeProfile_Properties(builder, target, source, sourceDominant, context);
459         mergeProfile_Repositories(builder, target, source, sourceDominant, context);
460         mergeProfile_PluginRepositories(builder, target, source, sourceDominant, context);
461     }
462 
463     protected void mergeProfile_Id(Profile.Builder builder, Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context) {
464         String src = source.getId();
465         String tgt = target.getId();
466         if (src != null && (sourceDominant || tgt == null)) {
467             builder.id(src);
468             builder.location("id", source.getLocation("id"));
469         }
470     }
471     protected void mergeProfile_Activation(Profile.Builder builder, Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context) {
472         Activation src = source.getActivation();
473         if (src != null) {
474             Activation tgt = target.getActivation();
475             if (tgt == null) {
476                 tgt = Activation.newInstance(false);
477             }
478             Activation merged = mergeActivation(tgt, src, sourceDominant, context);
479             builder.activation(merged);
480             if (target.getActivation() == null) {
481                 builder.location("activation", source.getLocation("activation"));
482             } else if (merged != tgt) {
483                 builder.location("activation", new InputLocation(-1, -1));
484             }
485         }
486     }
487     protected void mergeProfile_Properties(Profile.Builder builder, Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context) {
488         Map<String, String> src = source.getProperties();
489         if (!src.isEmpty()) {
490             Map<String, String> tgt = target.getProperties();
491             if (tgt.isEmpty()) {
492                 builder.properties(src);
493                 builder.location("properties", source.getLocation("properties"));
494             } else {
495                 Map<String, String> merged = new HashMap<>();
496                 merged.putAll(sourceDominant ? target.getProperties() : source.getProperties());
497                 merged.putAll(sourceDominant ? source.getProperties() : target.getProperties());
498                 builder.properties(merged);
499                 builder.location("properties", InputLocation.merge(target.getLocation("properties"), source.getLocation("properties"), sourceDominant));
500             }
501         }
502     }
503     protected void mergeProfile_Repositories(Profile.Builder builder, Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context) {
504         if (deepMerge) {
505             builder.repositories(merge(target.getRepositories(), source.getRepositories(), getRepositoryKey(),
506                     (t, s) -> mergeRepository(t, s, sourceDominant, context)));
507         } else {
508             builder.repositories(merge(target.getRepositories(), source.getRepositories(), sourceDominant, getRepositoryKey()));
509         }
510     }
511     protected void mergeProfile_PluginRepositories(Profile.Builder builder, Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context) {
512         if (deepMerge) {
513             builder.pluginRepositories(merge(target.getPluginRepositories(), source.getPluginRepositories(), getRepositoryKey(),
514                     (t, s) -> mergeRepository(t, s, sourceDominant, context)));
515         } else {
516             builder.pluginRepositories(merge(target.getPluginRepositories(), source.getPluginRepositories(), sourceDominant, getRepositoryKey()));
517         }
518     }
519 
520     protected Activation mergeActivation(Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
521         Activation.Builder builder = Activation.newBuilder(target);
522         mergeActivation(builder, target, source, sourceDominant, context);
523         return builder.build();
524     }
525 
526     protected void mergeActivation(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
527         mergeActivation_ActiveByDefault(builder, target, source, sourceDominant, context);
528         mergeActivation_Jdk(builder, target, source, sourceDominant, context);
529         mergeActivation_Os(builder, target, source, sourceDominant, context);
530         mergeActivation_Property(builder, target, source, sourceDominant, context);
531         mergeActivation_File(builder, target, source, sourceDominant, context);
532     }
533 
534     protected void mergeActivation_ActiveByDefault(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
535         if (sourceDominant) {
536             builder.activeByDefault(source.isActiveByDefault());
537         }
538     }
539     protected void mergeActivation_Jdk(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
540         String src = source.getJdk();
541         String tgt = target.getJdk();
542         if (src != null && (sourceDominant || tgt == null)) {
543             builder.jdk(src);
544             builder.location("jdk", source.getLocation("jdk"));
545         }
546     }
547     protected void mergeActivation_Os(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
548         ActivationOS src = source.getOs();
549         if (src != null) {
550             ActivationOS tgt = target.getOs();
551             if (tgt == null) {
552                 tgt = ActivationOS.newInstance(false);
553             }
554             ActivationOS merged = mergeActivationOS(tgt, src, sourceDominant, context);
555             builder.os(merged);
556             if (target.getOs() == null) {
557                 builder.location("os", source.getLocation("os"));
558             } else if (merged != tgt) {
559                 builder.location("os", new InputLocation(-1, -1));
560             }
561         }
562     }
563     protected void mergeActivation_Property(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
564         ActivationProperty src = source.getProperty();
565         if (src != null) {
566             ActivationProperty tgt = target.getProperty();
567             if (tgt == null) {
568                 tgt = ActivationProperty.newInstance(false);
569             }
570             ActivationProperty merged = mergeActivationProperty(tgt, src, sourceDominant, context);
571             builder.property(merged);
572             if (target.getProperty() == null) {
573                 builder.location("property", source.getLocation("property"));
574             } else if (merged != tgt) {
575                 builder.location("property", new InputLocation(-1, -1));
576             }
577         }
578     }
579     protected void mergeActivation_File(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
580         ActivationFile src = source.getFile();
581         if (src != null) {
582             ActivationFile tgt = target.getFile();
583             if (tgt == null) {
584                 tgt = ActivationFile.newInstance(false);
585             }
586             ActivationFile merged = mergeActivationFile(tgt, src, sourceDominant, context);
587             builder.file(merged);
588             if (target.getFile() == null) {
589                 builder.location("file", source.getLocation("file"));
590             } else if (merged != tgt) {
591                 builder.location("file", new InputLocation(-1, -1));
592             }
593         }
594     }
595 
596     protected RepositoryBase mergeRepositoryBase(RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
597         RepositoryBase.Builder builder = RepositoryBase.newBuilder(target);
598         mergeRepositoryBase(builder, target, source, sourceDominant, context);
599         return builder.build();
600     }
601 
602     protected void mergeRepositoryBase(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
603         mergeIdentifiableBase(builder, target, source, sourceDominant, context);
604         mergeRepositoryBase_Name(builder, target, source, sourceDominant, context);
605         mergeRepositoryBase_Url(builder, target, source, sourceDominant, context);
606         mergeRepositoryBase_Layout(builder, target, source, sourceDominant, context);
607     }
608 
609     protected void mergeRepositoryBase_Id(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
610         String src = source.getId();
611         String tgt = target.getId();
612         if (src != null && (sourceDominant || tgt == null)) {
613             builder.id(src);
614             builder.location("id", source.getLocation("id"));
615         }
616     }
617     protected void mergeRepositoryBase_Name(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
618         String src = source.getName();
619         String tgt = target.getName();
620         if (src != null && (sourceDominant || tgt == null)) {
621             builder.name(src);
622             builder.location("name", source.getLocation("name"));
623         }
624     }
625     protected void mergeRepositoryBase_Url(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
626         String src = source.getUrl();
627         String tgt = target.getUrl();
628         if (src != null && (sourceDominant || tgt == null)) {
629             builder.url(src);
630             builder.location("url", source.getLocation("url"));
631         }
632     }
633     protected void mergeRepositoryBase_Layout(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
634         String src = source.getLayout();
635         String tgt = target.getLayout();
636         if (src != null && (sourceDominant || tgt == null)) {
637             builder.layout(src);
638             builder.location("layout", source.getLocation("layout"));
639         }
640     }
641 
642     protected Repository mergeRepository(Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
643         Repository.Builder builder = Repository.newBuilder(target);
644         mergeRepository(builder, target, source, sourceDominant, context);
645         return builder.build();
646     }
647 
648     protected void mergeRepository(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
649         mergeRepositoryBase(builder, target, source, sourceDominant, context);
650         mergeRepository_Releases(builder, target, source, sourceDominant, context);
651         mergeRepository_Snapshots(builder, target, source, sourceDominant, context);
652     }
653 
654     protected void mergeRepository_Id(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
655         String src = source.getId();
656         String tgt = target.getId();
657         if (src != null && (sourceDominant || tgt == null)) {
658             builder.id(src);
659             builder.location("id", source.getLocation("id"));
660         }
661     }
662     protected void mergeRepository_Name(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
663         String src = source.getName();
664         String tgt = target.getName();
665         if (src != null && (sourceDominant || tgt == null)) {
666             builder.name(src);
667             builder.location("name", source.getLocation("name"));
668         }
669     }
670     protected void mergeRepository_Url(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
671         String src = source.getUrl();
672         String tgt = target.getUrl();
673         if (src != null && (sourceDominant || tgt == null)) {
674             builder.url(src);
675             builder.location("url", source.getLocation("url"));
676         }
677     }
678     protected void mergeRepository_Layout(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
679         String src = source.getLayout();
680         String tgt = target.getLayout();
681         if (src != null && (sourceDominant || tgt == null)) {
682             builder.layout(src);
683             builder.location("layout", source.getLocation("layout"));
684         }
685     }
686     protected void mergeRepository_Releases(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
687         RepositoryPolicy src = source.getReleases();
688         if (src != null) {
689             RepositoryPolicy tgt = target.getReleases();
690             if (tgt == null) {
691                 tgt = RepositoryPolicy.newInstance(false);
692             }
693             RepositoryPolicy merged = mergeRepositoryPolicy(tgt, src, sourceDominant, context);
694             builder.releases(merged);
695             if (target.getReleases() == null) {
696                 builder.location("releases", source.getLocation("releases"));
697             } else if (merged != tgt) {
698                 builder.location("releases", new InputLocation(-1, -1));
699             }
700         }
701     }
702     protected void mergeRepository_Snapshots(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
703         RepositoryPolicy src = source.getSnapshots();
704         if (src != null) {
705             RepositoryPolicy tgt = target.getSnapshots();
706             if (tgt == null) {
707                 tgt = RepositoryPolicy.newInstance(false);
708             }
709             RepositoryPolicy merged = mergeRepositoryPolicy(tgt, src, sourceDominant, context);
710             builder.snapshots(merged);
711             if (target.getSnapshots() == null) {
712                 builder.location("snapshots", source.getLocation("snapshots"));
713             } else if (merged != tgt) {
714                 builder.location("snapshots", new InputLocation(-1, -1));
715             }
716         }
717     }
718 
719     protected RepositoryPolicy mergeRepositoryPolicy(RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
720         RepositoryPolicy.Builder builder = RepositoryPolicy.newBuilder(target);
721         mergeRepositoryPolicy(builder, target, source, sourceDominant, context);
722         return builder.build();
723     }
724 
725     protected void mergeRepositoryPolicy(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
726         mergeRepositoryPolicy_Enabled(builder, target, source, sourceDominant, context);
727         mergeRepositoryPolicy_UpdatePolicy(builder, target, source, sourceDominant, context);
728         mergeRepositoryPolicy_ChecksumPolicy(builder, target, source, sourceDominant, context);
729     }
730 
731     protected void mergeRepositoryPolicy_Enabled(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
732         if (sourceDominant) {
733             builder.enabled(source.isEnabled());
734         }
735     }
736     protected void mergeRepositoryPolicy_UpdatePolicy(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
737         String src = source.getUpdatePolicy();
738         String tgt = target.getUpdatePolicy();
739         if (src != null && (sourceDominant || tgt == null)) {
740             builder.updatePolicy(src);
741             builder.location("updatePolicy", source.getLocation("updatePolicy"));
742         }
743     }
744     protected void mergeRepositoryPolicy_ChecksumPolicy(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
745         String src = source.getChecksumPolicy();
746         String tgt = target.getChecksumPolicy();
747         if (src != null && (sourceDominant || tgt == null)) {
748             builder.checksumPolicy(src);
749             builder.location("checksumPolicy", source.getLocation("checksumPolicy"));
750         }
751     }
752 
753     protected ActivationProperty mergeActivationProperty(ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
754         ActivationProperty.Builder builder = ActivationProperty.newBuilder(target);
755         mergeActivationProperty(builder, target, source, sourceDominant, context);
756         return builder.build();
757     }
758 
759     protected void mergeActivationProperty(ActivationProperty.Builder builder, ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
760         mergeActivationProperty_Name(builder, target, source, sourceDominant, context);
761         mergeActivationProperty_Value(builder, target, source, sourceDominant, context);
762     }
763 
764     protected void mergeActivationProperty_Name(ActivationProperty.Builder builder, ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
765         String src = source.getName();
766         String tgt = target.getName();
767         if (src != null && (sourceDominant || tgt == null)) {
768             builder.name(src);
769             builder.location("name", source.getLocation("name"));
770         }
771     }
772     protected void mergeActivationProperty_Value(ActivationProperty.Builder builder, ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
773         String src = source.getValue();
774         String tgt = target.getValue();
775         if (src != null && (sourceDominant || tgt == null)) {
776             builder.value(src);
777             builder.location("value", source.getLocation("value"));
778         }
779     }
780 
781     protected ActivationOS mergeActivationOS(ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
782         ActivationOS.Builder builder = ActivationOS.newBuilder(target);
783         mergeActivationOS(builder, target, source, sourceDominant, context);
784         return builder.build();
785     }
786 
787     protected void mergeActivationOS(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
788         mergeActivationOS_Name(builder, target, source, sourceDominant, context);
789         mergeActivationOS_Family(builder, target, source, sourceDominant, context);
790         mergeActivationOS_Arch(builder, target, source, sourceDominant, context);
791         mergeActivationOS_Version(builder, target, source, sourceDominant, context);
792     }
793 
794     protected void mergeActivationOS_Name(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
795         String src = source.getName();
796         String tgt = target.getName();
797         if (src != null && (sourceDominant || tgt == null)) {
798             builder.name(src);
799             builder.location("name", source.getLocation("name"));
800         }
801     }
802     protected void mergeActivationOS_Family(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
803         String src = source.getFamily();
804         String tgt = target.getFamily();
805         if (src != null && (sourceDominant || tgt == null)) {
806             builder.family(src);
807             builder.location("family", source.getLocation("family"));
808         }
809     }
810     protected void mergeActivationOS_Arch(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
811         String src = source.getArch();
812         String tgt = target.getArch();
813         if (src != null && (sourceDominant || tgt == null)) {
814             builder.arch(src);
815             builder.location("arch", source.getLocation("arch"));
816         }
817     }
818     protected void mergeActivationOS_Version(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
819         String src = source.getVersion();
820         String tgt = target.getVersion();
821         if (src != null && (sourceDominant || tgt == null)) {
822             builder.version(src);
823             builder.location("version", source.getLocation("version"));
824         }
825     }
826 
827     protected ActivationFile mergeActivationFile(ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
828         ActivationFile.Builder builder = ActivationFile.newBuilder(target);
829         mergeActivationFile(builder, target, source, sourceDominant, context);
830         return builder.build();
831     }
832 
833     protected void mergeActivationFile(ActivationFile.Builder builder, ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
834         mergeActivationFile_Missing(builder, target, source, sourceDominant, context);
835         mergeActivationFile_Exists(builder, target, source, sourceDominant, context);
836     }
837 
838     protected void mergeActivationFile_Missing(ActivationFile.Builder builder, ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
839         String src = source.getMissing();
840         String tgt = target.getMissing();
841         if (src != null && (sourceDominant || tgt == null)) {
842             builder.missing(src);
843             builder.location("missing", source.getLocation("missing"));
844         }
845     }
846     protected void mergeActivationFile_Exists(ActivationFile.Builder builder, ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
847         String src = source.getExists();
848         String tgt = target.getExists();
849         if (src != null && (sourceDominant || tgt == null)) {
850             builder.exists(src);
851             builder.location("exists", source.getLocation("exists"));
852         }
853     }
854 
855 
856     protected KeyComputer<TrackableBase> getTrackableBaseKey() {
857         return v -> v;
858     }
859     protected KeyComputer<IdentifiableBase> getIdentifiableBaseKey() {
860         return v -> v;
861     }
862     protected KeyComputer<Settings> getSettingsKey() {
863         return v -> v;
864     }
865     protected KeyComputer<Proxy> getProxyKey() {
866         return v -> v;
867     }
868     protected KeyComputer<Server> getServerKey() {
869         return v -> v;
870     }
871     protected KeyComputer<Mirror> getMirrorKey() {
872         return v -> v;
873     }
874     protected KeyComputer<Profile> getProfileKey() {
875         return v -> v;
876     }
877     protected KeyComputer<Activation> getActivationKey() {
878         return v -> v;
879     }
880     protected KeyComputer<RepositoryBase> getRepositoryBaseKey() {
881         return v -> v;
882     }
883     protected KeyComputer<Repository> getRepositoryKey() {
884         return v -> v;
885     }
886     protected KeyComputer<RepositoryPolicy> getRepositoryPolicyKey() {
887         return v -> v;
888     }
889     protected KeyComputer<ActivationProperty> getActivationPropertyKey() {
890         return v -> v;
891     }
892     protected KeyComputer<ActivationOS> getActivationOSKey() {
893         return v -> v;
894     }
895     protected KeyComputer<ActivationFile> getActivationFileKey() {
896         return v -> v;
897     }
898 
899     /**
900      * Use to compute keys for data structures
901      * @param <T> the data structure type
902      */
903     @FunctionalInterface
904     public interface KeyComputer<T> extends Function<T, Object> {
905     }
906 
907     /**
908      * Merge two lists
909      */
910     public static <T> List<T> merge(List<T> tgt, List<T> src, boolean sourceDominant, KeyComputer<T> computer) {
911         return merge(tgt, src, computer, (t, s) -> sourceDominant ? s : t);
912     }
913 
914     public static <T> List<T> merge(List<T> tgt, List<T> src, KeyComputer<T> computer, BinaryOperator<T> remapping) {
915         if (src.isEmpty()) {
916             return tgt;
917         }
918 
919         MergingList<T> list;
920         if (tgt instanceof MergingList) {
921             list = (MergingList<T>) tgt;
922         } else {
923             list = new MergingList<>(computer, src.size() + tgt.size());
924             list.mergeAll(tgt, (t, s) -> s);
925         }
926 
927         list.mergeAll(src, remapping);
928         return list;
929     }
930 
931     /**
932      * Merging list
933      * @param <V>
934      */
935     private static class MergingList<V> extends AbstractList<V> implements java.io.Serializable {
936 
937         private final KeyComputer<V> keyComputer;
938         private Map<Object, V> map;
939         private List<V> list;
940 
941         MergingList(KeyComputer<V> keyComputer, int initialCapacity) {
942             this.map = new LinkedHashMap<>(initialCapacity);
943             this.keyComputer = keyComputer;
944         }
945 
946         Object writeReplace() throws ObjectStreamException {
947             return new ArrayList<>(this);
948         }
949 
950         @Override
951         public Iterator<V> iterator() {
952             if (map != null) {
953                 return map.values().iterator();
954             } else {
955                 return list.iterator();
956             }
957         }
958 
959         void mergeAll(Collection<V> vs, BinaryOperator<V> remapping) {
960             if (map == null) {
961                 map = list.stream().collect(Collectors.toMap(keyComputer,
962                     Function.identity(),
963                     null,
964                     LinkedHashMap::new));
965                 list = null;
966             }
967 
968             if (vs instanceof MergingList && ((MergingList<V>) vs).map != null) {
969                 for (Map.Entry<Object, V> e : ((MergingList<V>) vs).map.entrySet()) {
970                     Object key = e.getKey();
971                     V v = e.getValue();
972                     map.merge(key, v, remapping);
973                 }
974             } else {
975                 for (V v : vs) {
976                     Object key = keyComputer.apply(v);
977                     map.merge(key, v, remapping);
978                 }
979             }
980         }
981 
982         @Override
983         public boolean contains(Object o) {
984             if (map != null) {
985                 return map.containsValue(o);
986             } else {
987                 return list.contains(o);
988             }
989         }
990 
991         private List<V> asList() {
992             if (list == null) {
993                 list = new ArrayList<>(map.values());
994                 map = null;
995             }
996             return list;
997         }
998 
999         @Override
1000         public void add(int index, V element) {
1001             asList().add(index, element);
1002         }
1003 
1004         @Override
1005         public V remove(int index) {
1006             return asList().remove(index);
1007         }
1008 
1009         @Override
1010         public V get(int index) {
1011             return asList().get(index);
1012         }
1013 
1014         @Override
1015         public int size() {
1016             if (map != null) {
1017                 return map.size();
1018             } else {
1019                 return list.size();
1020             }
1021         }
1022     }
1023 }