1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.api.xml;
20
21 import java.util.List;
22 import java.util.Map;
23 import org.apache.maven.api.annotations.Experimental;
24 import org.apache.maven.api.annotations.Immutable;
25 import org.apache.maven.api.annotations.Nonnull;
26 import org.apache.maven.api.annotations.Nullable;
27 import org.apache.maven.api.annotations.ThreadSafe;
28
29 /**
30 * An immutable xml node.
31 *
32 * @since 4.0
33 */
34 @Experimental
35 @ThreadSafe
36 @Immutable
37 public interface Dom {
38
39 String CHILDREN_COMBINATION_MODE_ATTRIBUTE = "combine.children";
40
41 String CHILDREN_COMBINATION_MERGE = "merge";
42
43 String CHILDREN_COMBINATION_APPEND = "append";
44
45 /**
46 * This default mode for combining children DOMs during merge means that where element names match, the process will
47 * try to merge the element data, rather than putting the dominant and recessive elements (which share the same
48 * element name) as siblings in the resulting DOM.
49 */
50 String DEFAULT_CHILDREN_COMBINATION_MODE = CHILDREN_COMBINATION_MERGE;
51
52 String SELF_COMBINATION_MODE_ATTRIBUTE = "combine.self";
53
54 String SELF_COMBINATION_OVERRIDE = "override";
55
56 String SELF_COMBINATION_MERGE = "merge";
57
58 String SELF_COMBINATION_REMOVE = "remove";
59
60 /**
61 * In case of complex XML structures, combining can be done based on id.
62 */
63 String ID_COMBINATION_MODE_ATTRIBUTE = "combine.id";
64
65 /**
66 * In case of complex XML structures, combining can be done based on keys.
67 * This is a comma separated list of attribute names.
68 */
69 String KEYS_COMBINATION_MODE_ATTRIBUTE = "combine.keys";
70
71 /**
72 * This default mode for combining a DOM node during merge means that where element names match, the process will
73 * try to merge the element attributes and values, rather than overriding the recessive element completely with the
74 * dominant one. This means that wherever the dominant element doesn't provide the value or a particular attribute,
75 * that value or attribute will be set from the recessive DOM node.
76 */
77 String DEFAULT_SELF_COMBINATION_MODE = SELF_COMBINATION_MERGE;
78
79 @Nonnull
80 String getName();
81
82 @Nullable
83 String getValue();
84
85 @Nonnull
86 Map<String, String> getAttributes();
87
88 @Nullable
89 String getAttribute(@Nonnull String name);
90
91 @Nonnull
92 List<Dom> getChildren();
93
94 @Nullable
95 Dom getChild(String name);
96
97 @Nullable
98 Object getInputLocation();
99
100 default Dom merge(@Nullable Dom source) {
101 return merge(source, (Boolean) null);
102 }
103
104 Dom merge(@Nullable Dom source, @Nullable Boolean childMergeOverride);
105
106 Dom clone();
107
108 /**
109 * Merge recessive into dominant and return either {@code dominant}
110 * with merged information or a clone of {@code recessive} if
111 * {@code dominant} is {@code null}.
112 *
113 * @param dominant the node
114 * @param recessive if {@code null}, nothing will happen
115 * @return the merged node
116 */
117 @Nullable
118 static Dom merge(@Nullable Dom dominant, @Nullable Dom recessive) {
119 return merge(dominant, recessive, null);
120 }
121
122 @Nullable
123 static Dom merge(@Nullable Dom dominant, @Nullable Dom recessive, @Nullable Boolean childMergeOverride) {
124 if (recessive == null) {
125 return dominant;
126 }
127 if (dominant == null) {
128 return recessive;
129 }
130 return dominant.merge(recessive, childMergeOverride);
131 }
132 }