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