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         mergeActivation_Packaging(builder, target, source, sourceDominant, context);
533     }
534 
535     protected void mergeActivation_ActiveByDefault(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
536         if (sourceDominant) {
537             builder.activeByDefault(source.isActiveByDefault());
538         }
539     }
540     protected void mergeActivation_Jdk(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
541         String src = source.getJdk();
542         String tgt = target.getJdk();
543         if (src != null && (sourceDominant || tgt == null)) {
544             builder.jdk(src);
545             builder.location("jdk", source.getLocation("jdk"));
546         }
547     }
548     protected void mergeActivation_Os(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
549         ActivationOS src = source.getOs();
550         if (src != null) {
551             ActivationOS tgt = target.getOs();
552             if (tgt == null) {
553                 tgt = ActivationOS.newInstance(false);
554             }
555             ActivationOS merged = mergeActivationOS(tgt, src, sourceDominant, context);
556             builder.os(merged);
557             if (target.getOs() == null) {
558                 builder.location("os", source.getLocation("os"));
559             } else if (merged != tgt) {
560                 builder.location("os", new InputLocation(-1, -1));
561             }
562         }
563     }
564     protected void mergeActivation_Property(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
565         ActivationProperty src = source.getProperty();
566         if (src != null) {
567             ActivationProperty tgt = target.getProperty();
568             if (tgt == null) {
569                 tgt = ActivationProperty.newInstance(false);
570             }
571             ActivationProperty merged = mergeActivationProperty(tgt, src, sourceDominant, context);
572             builder.property(merged);
573             if (target.getProperty() == null) {
574                 builder.location("property", source.getLocation("property"));
575             } else if (merged != tgt) {
576                 builder.location("property", new InputLocation(-1, -1));
577             }
578         }
579     }
580     protected void mergeActivation_File(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
581         ActivationFile src = source.getFile();
582         if (src != null) {
583             ActivationFile tgt = target.getFile();
584             if (tgt == null) {
585                 tgt = ActivationFile.newInstance(false);
586             }
587             ActivationFile merged = mergeActivationFile(tgt, src, sourceDominant, context);
588             builder.file(merged);
589             if (target.getFile() == null) {
590                 builder.location("file", source.getLocation("file"));
591             } else if (merged != tgt) {
592                 builder.location("file", new InputLocation(-1, -1));
593             }
594         }
595     }
596     protected void mergeActivation_Packaging(Activation.Builder builder, Activation target, Activation source, boolean sourceDominant, Map<Object, Object> context) {
597         String src = source.getPackaging();
598         String tgt = target.getPackaging();
599         if (src != null && (sourceDominant || tgt == null)) {
600             builder.packaging(src);
601             builder.location("packaging", source.getLocation("packaging"));
602         }
603     }
604 
605     protected RepositoryBase mergeRepositoryBase(RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
606         RepositoryBase.Builder builder = RepositoryBase.newBuilder(target);
607         mergeRepositoryBase(builder, target, source, sourceDominant, context);
608         return builder.build();
609     }
610 
611     protected void mergeRepositoryBase(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
612         mergeIdentifiableBase(builder, target, source, sourceDominant, context);
613         mergeRepositoryBase_Name(builder, target, source, sourceDominant, context);
614         mergeRepositoryBase_Url(builder, target, source, sourceDominant, context);
615         mergeRepositoryBase_Layout(builder, target, source, sourceDominant, context);
616     }
617 
618     protected void mergeRepositoryBase_Id(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
619         String src = source.getId();
620         String tgt = target.getId();
621         if (src != null && (sourceDominant || tgt == null)) {
622             builder.id(src);
623             builder.location("id", source.getLocation("id"));
624         }
625     }
626     protected void mergeRepositoryBase_Name(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
627         String src = source.getName();
628         String tgt = target.getName();
629         if (src != null && (sourceDominant || tgt == null)) {
630             builder.name(src);
631             builder.location("name", source.getLocation("name"));
632         }
633     }
634     protected void mergeRepositoryBase_Url(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
635         String src = source.getUrl();
636         String tgt = target.getUrl();
637         if (src != null && (sourceDominant || tgt == null)) {
638             builder.url(src);
639             builder.location("url", source.getLocation("url"));
640         }
641     }
642     protected void mergeRepositoryBase_Layout(RepositoryBase.Builder builder, RepositoryBase target, RepositoryBase source, boolean sourceDominant, Map<Object, Object> context) {
643         String src = source.getLayout();
644         String tgt = target.getLayout();
645         if (src != null && (sourceDominant || tgt == null)) {
646             builder.layout(src);
647             builder.location("layout", source.getLocation("layout"));
648         }
649     }
650 
651     protected Repository mergeRepository(Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
652         Repository.Builder builder = Repository.newBuilder(target);
653         mergeRepository(builder, target, source, sourceDominant, context);
654         return builder.build();
655     }
656 
657     protected void mergeRepository(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
658         mergeRepositoryBase(builder, target, source, sourceDominant, context);
659         mergeRepository_Releases(builder, target, source, sourceDominant, context);
660         mergeRepository_Snapshots(builder, target, source, sourceDominant, context);
661     }
662 
663     protected void mergeRepository_Id(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
664         String src = source.getId();
665         String tgt = target.getId();
666         if (src != null && (sourceDominant || tgt == null)) {
667             builder.id(src);
668             builder.location("id", source.getLocation("id"));
669         }
670     }
671     protected void mergeRepository_Name(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
672         String src = source.getName();
673         String tgt = target.getName();
674         if (src != null && (sourceDominant || tgt == null)) {
675             builder.name(src);
676             builder.location("name", source.getLocation("name"));
677         }
678     }
679     protected void mergeRepository_Url(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
680         String src = source.getUrl();
681         String tgt = target.getUrl();
682         if (src != null && (sourceDominant || tgt == null)) {
683             builder.url(src);
684             builder.location("url", source.getLocation("url"));
685         }
686     }
687     protected void mergeRepository_Layout(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
688         String src = source.getLayout();
689         String tgt = target.getLayout();
690         if (src != null && (sourceDominant || tgt == null)) {
691             builder.layout(src);
692             builder.location("layout", source.getLocation("layout"));
693         }
694     }
695     protected void mergeRepository_Releases(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
696         RepositoryPolicy src = source.getReleases();
697         if (src != null) {
698             RepositoryPolicy tgt = target.getReleases();
699             if (tgt == null) {
700                 tgt = RepositoryPolicy.newInstance(false);
701             }
702             RepositoryPolicy merged = mergeRepositoryPolicy(tgt, src, sourceDominant, context);
703             builder.releases(merged);
704             if (target.getReleases() == null) {
705                 builder.location("releases", source.getLocation("releases"));
706             } else if (merged != tgt) {
707                 builder.location("releases", new InputLocation(-1, -1));
708             }
709         }
710     }
711     protected void mergeRepository_Snapshots(Repository.Builder builder, Repository target, Repository source, boolean sourceDominant, Map<Object, Object> context) {
712         RepositoryPolicy src = source.getSnapshots();
713         if (src != null) {
714             RepositoryPolicy tgt = target.getSnapshots();
715             if (tgt == null) {
716                 tgt = RepositoryPolicy.newInstance(false);
717             }
718             RepositoryPolicy merged = mergeRepositoryPolicy(tgt, src, sourceDominant, context);
719             builder.snapshots(merged);
720             if (target.getSnapshots() == null) {
721                 builder.location("snapshots", source.getLocation("snapshots"));
722             } else if (merged != tgt) {
723                 builder.location("snapshots", new InputLocation(-1, -1));
724             }
725         }
726     }
727 
728     protected RepositoryPolicy mergeRepositoryPolicy(RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
729         RepositoryPolicy.Builder builder = RepositoryPolicy.newBuilder(target);
730         mergeRepositoryPolicy(builder, target, source, sourceDominant, context);
731         return builder.build();
732     }
733 
734     protected void mergeRepositoryPolicy(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
735         mergeRepositoryPolicy_Enabled(builder, target, source, sourceDominant, context);
736         mergeRepositoryPolicy_UpdatePolicy(builder, target, source, sourceDominant, context);
737         mergeRepositoryPolicy_ChecksumPolicy(builder, target, source, sourceDominant, context);
738     }
739 
740     protected void mergeRepositoryPolicy_Enabled(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
741         if (sourceDominant) {
742             builder.enabled(source.isEnabled());
743         }
744     }
745     protected void mergeRepositoryPolicy_UpdatePolicy(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
746         String src = source.getUpdatePolicy();
747         String tgt = target.getUpdatePolicy();
748         if (src != null && (sourceDominant || tgt == null)) {
749             builder.updatePolicy(src);
750             builder.location("updatePolicy", source.getLocation("updatePolicy"));
751         }
752     }
753     protected void mergeRepositoryPolicy_ChecksumPolicy(RepositoryPolicy.Builder builder, RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant, Map<Object, Object> context) {
754         String src = source.getChecksumPolicy();
755         String tgt = target.getChecksumPolicy();
756         if (src != null && (sourceDominant || tgt == null)) {
757             builder.checksumPolicy(src);
758             builder.location("checksumPolicy", source.getLocation("checksumPolicy"));
759         }
760     }
761 
762     protected ActivationProperty mergeActivationProperty(ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
763         ActivationProperty.Builder builder = ActivationProperty.newBuilder(target);
764         mergeActivationProperty(builder, target, source, sourceDominant, context);
765         return builder.build();
766     }
767 
768     protected void mergeActivationProperty(ActivationProperty.Builder builder, ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
769         mergeActivationProperty_Name(builder, target, source, sourceDominant, context);
770         mergeActivationProperty_Value(builder, target, source, sourceDominant, context);
771     }
772 
773     protected void mergeActivationProperty_Name(ActivationProperty.Builder builder, ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
774         String src = source.getName();
775         String tgt = target.getName();
776         if (src != null && (sourceDominant || tgt == null)) {
777             builder.name(src);
778             builder.location("name", source.getLocation("name"));
779         }
780     }
781     protected void mergeActivationProperty_Value(ActivationProperty.Builder builder, ActivationProperty target, ActivationProperty source, boolean sourceDominant, Map<Object, Object> context) {
782         String src = source.getValue();
783         String tgt = target.getValue();
784         if (src != null && (sourceDominant || tgt == null)) {
785             builder.value(src);
786             builder.location("value", source.getLocation("value"));
787         }
788     }
789 
790     protected ActivationOS mergeActivationOS(ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
791         ActivationOS.Builder builder = ActivationOS.newBuilder(target);
792         mergeActivationOS(builder, target, source, sourceDominant, context);
793         return builder.build();
794     }
795 
796     protected void mergeActivationOS(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
797         mergeActivationOS_Name(builder, target, source, sourceDominant, context);
798         mergeActivationOS_Family(builder, target, source, sourceDominant, context);
799         mergeActivationOS_Arch(builder, target, source, sourceDominant, context);
800         mergeActivationOS_Version(builder, target, source, sourceDominant, context);
801     }
802 
803     protected void mergeActivationOS_Name(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
804         String src = source.getName();
805         String tgt = target.getName();
806         if (src != null && (sourceDominant || tgt == null)) {
807             builder.name(src);
808             builder.location("name", source.getLocation("name"));
809         }
810     }
811     protected void mergeActivationOS_Family(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
812         String src = source.getFamily();
813         String tgt = target.getFamily();
814         if (src != null && (sourceDominant || tgt == null)) {
815             builder.family(src);
816             builder.location("family", source.getLocation("family"));
817         }
818     }
819     protected void mergeActivationOS_Arch(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
820         String src = source.getArch();
821         String tgt = target.getArch();
822         if (src != null && (sourceDominant || tgt == null)) {
823             builder.arch(src);
824             builder.location("arch", source.getLocation("arch"));
825         }
826     }
827     protected void mergeActivationOS_Version(ActivationOS.Builder builder, ActivationOS target, ActivationOS source, boolean sourceDominant, Map<Object, Object> context) {
828         String src = source.getVersion();
829         String tgt = target.getVersion();
830         if (src != null && (sourceDominant || tgt == null)) {
831             builder.version(src);
832             builder.location("version", source.getLocation("version"));
833         }
834     }
835 
836     protected ActivationFile mergeActivationFile(ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
837         ActivationFile.Builder builder = ActivationFile.newBuilder(target);
838         mergeActivationFile(builder, target, source, sourceDominant, context);
839         return builder.build();
840     }
841 
842     protected void mergeActivationFile(ActivationFile.Builder builder, ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
843         mergeActivationFile_Missing(builder, target, source, sourceDominant, context);
844         mergeActivationFile_Exists(builder, target, source, sourceDominant, context);
845     }
846 
847     protected void mergeActivationFile_Missing(ActivationFile.Builder builder, ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
848         String src = source.getMissing();
849         String tgt = target.getMissing();
850         if (src != null && (sourceDominant || tgt == null)) {
851             builder.missing(src);
852             builder.location("missing", source.getLocation("missing"));
853         }
854     }
855     protected void mergeActivationFile_Exists(ActivationFile.Builder builder, ActivationFile target, ActivationFile source, boolean sourceDominant, Map<Object, Object> context) {
856         String src = source.getExists();
857         String tgt = target.getExists();
858         if (src != null && (sourceDominant || tgt == null)) {
859             builder.exists(src);
860             builder.location("exists", source.getLocation("exists"));
861         }
862     }
863 
864 
865     protected KeyComputer<TrackableBase> getTrackableBaseKey() {
866         return v -> v;
867     }
868     protected KeyComputer<IdentifiableBase> getIdentifiableBaseKey() {
869         return v -> v;
870     }
871     protected KeyComputer<Settings> getSettingsKey() {
872         return v -> v;
873     }
874     protected KeyComputer<Proxy> getProxyKey() {
875         return v -> v;
876     }
877     protected KeyComputer<Server> getServerKey() {
878         return v -> v;
879     }
880     protected KeyComputer<Mirror> getMirrorKey() {
881         return v -> v;
882     }
883     protected KeyComputer<Profile> getProfileKey() {
884         return v -> v;
885     }
886     protected KeyComputer<Activation> getActivationKey() {
887         return v -> v;
888     }
889     protected KeyComputer<RepositoryBase> getRepositoryBaseKey() {
890         return v -> v;
891     }
892     protected KeyComputer<Repository> getRepositoryKey() {
893         return v -> v;
894     }
895     protected KeyComputer<RepositoryPolicy> getRepositoryPolicyKey() {
896         return v -> v;
897     }
898     protected KeyComputer<ActivationProperty> getActivationPropertyKey() {
899         return v -> v;
900     }
901     protected KeyComputer<ActivationOS> getActivationOSKey() {
902         return v -> v;
903     }
904     protected KeyComputer<ActivationFile> getActivationFileKey() {
905         return v -> v;
906     }
907 
908     /**
909      * Use to compute keys for data structures
910      * @param <T> the data structure type
911      */
912     @FunctionalInterface
913     public interface KeyComputer<T> extends Function<T, Object> {
914     }
915 
916     /**
917      * Merge two lists
918      */
919     public static <T> List<T> merge(List<T> tgt, List<T> src, boolean sourceDominant, KeyComputer<T> computer) {
920         return merge(tgt, src, computer, (t, s) -> sourceDominant ? s : t);
921     }
922 
923     public static <T> List<T> merge(List<T> tgt, List<T> src, KeyComputer<T> computer, BinaryOperator<T> remapping) {
924         if (src.isEmpty()) {
925             return tgt;
926         }
927 
928         MergingList<T> list;
929         if (tgt instanceof MergingList) {
930             list = (MergingList<T>) tgt;
931         } else {
932             list = new MergingList<>(computer, src.size() + tgt.size());
933             list.mergeAll(tgt, (t, s) -> s);
934         }
935 
936         list.mergeAll(src, remapping);
937         return list;
938     }
939 
940     /**
941      * Merging list
942      * @param <V>
943      */
944     private static class MergingList<V> extends AbstractList<V> implements java.io.Serializable {
945 
946         private final KeyComputer<V> keyComputer;
947         private Map<Object, V> map;
948         private List<V> list;
949 
950         MergingList(KeyComputer<V> keyComputer, int initialCapacity) {
951             this.map = new LinkedHashMap<>(initialCapacity);
952             this.keyComputer = keyComputer;
953         }
954 
955         Object writeReplace() throws ObjectStreamException {
956             return new ArrayList<>(this);
957         }
958 
959         @Override
960         public Iterator<V> iterator() {
961             if (map != null) {
962                 return map.values().iterator();
963             } else {
964                 return list.iterator();
965             }
966         }
967 
968         void mergeAll(Collection<V> vs, BinaryOperator<V> remapping) {
969             if (map == null) {
970                 map = list.stream().collect(Collectors.toMap(keyComputer,
971                     Function.identity(),
972                     null,
973                     LinkedHashMap::new));
974                 list = null;
975             }
976 
977             if (vs instanceof MergingList && ((MergingList<V>) vs).map != null) {
978                 for (Map.Entry<Object, V> e : ((MergingList<V>) vs).map.entrySet()) {
979                     Object key = e.getKey();
980                     V v = e.getValue();
981                     map.merge(key, v, remapping);
982                 }
983             } else {
984                 for (V v : vs) {
985                     Object key = keyComputer.apply(v);
986                     map.merge(key, v, remapping);
987                 }
988             }
989         }
990 
991         @Override
992         public boolean contains(Object o) {
993             if (map != null) {
994                 return map.containsValue(o);
995             } else {
996                 return list.contains(o);
997             }
998         }
999 
1000         private List<V> asList() {
1001             if (list == null) {
1002                 list = new ArrayList<>(map.values());
1003                 map = null;
1004             }
1005             return list;
1006         }
1007 
1008         @Override
1009         public void add(int index, V element) {
1010             asList().add(index, element);
1011         }
1012 
1013         @Override
1014         public V remove(int index) {
1015             return asList().remove(index);
1016         }
1017 
1018         @Override
1019         public V get(int index) {
1020             return asList().get(index);
1021         }
1022 
1023         @Override
1024         public int size() {
1025             if (map != null) {
1026                 return map.size();
1027             } else {
1028                 return list.size();
1029             }
1030         }
1031     }
1032 }