View Javadoc
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  
24  import org.apache.maven.api.annotations.Experimental;
25  import org.apache.maven.api.annotations.Immutable;
26  import org.apache.maven.api.annotations.Nonnull;
27  import org.apache.maven.api.annotations.Nullable;
28  import org.apache.maven.api.annotations.ThreadSafe;
29  
30  /**
31   * An immutable xml node.
32   *
33   * @since 4.0.0
34   */
35  @Experimental
36  @ThreadSafe
37  @Immutable
38  public interface XmlNode {
39  
40      String CHILDREN_COMBINATION_MODE_ATTRIBUTE = "combine.children";
41  
42      String CHILDREN_COMBINATION_MERGE = "merge";
43  
44      String CHILDREN_COMBINATION_APPEND = "append";
45  
46      /**
47       * This default mode for combining children DOMs during merge means that where element names match, the process will
48       * try to merge the element data, rather than putting the dominant and recessive elements (which share the same
49       * element name) as siblings in the resulting DOM.
50       */
51      String DEFAULT_CHILDREN_COMBINATION_MODE = CHILDREN_COMBINATION_MERGE;
52  
53      String SELF_COMBINATION_MODE_ATTRIBUTE = "combine.self";
54  
55      String SELF_COMBINATION_OVERRIDE = "override";
56  
57      String SELF_COMBINATION_MERGE = "merge";
58  
59      String SELF_COMBINATION_REMOVE = "remove";
60  
61      /**
62       * In case of complex XML structures, combining can be done based on id.
63       */
64      String ID_COMBINATION_MODE_ATTRIBUTE = "combine.id";
65  
66      /**
67       * In case of complex XML structures, combining can be done based on keys.
68       * This is a comma separated list of attribute names.
69       */
70      String KEYS_COMBINATION_MODE_ATTRIBUTE = "combine.keys";
71  
72      /**
73       * This default mode for combining a DOM node during merge means that where element names match, the process will
74       * try to merge the element attributes and values, rather than overriding the recessive element completely with the
75       * dominant one. This means that wherever the dominant element doesn't provide the value or a particular attribute,
76       * that value or attribute will be set from the recessive DOM node.
77       */
78      String DEFAULT_SELF_COMBINATION_MODE = SELF_COMBINATION_MERGE;
79  
80      @Nonnull
81      String getName();
82  
83      @Nonnull
84      String getNamespaceUri();
85  
86      @Nonnull
87      String getPrefix();
88  
89      @Nullable
90      String getValue();
91  
92      @Nonnull
93      Map<String, String> getAttributes();
94  
95      @Nullable
96      String getAttribute(@Nonnull String name);
97  
98      @Nonnull
99      List<XmlNode> getChildren();
100 
101     @Nullable
102     XmlNode getChild(String name);
103 
104     @Nullable
105     Object getInputLocation();
106 
107     default XmlNode merge(@Nullable XmlNode source) {
108         return merge(source, (Boolean) null);
109     }
110 
111     XmlNode merge(@Nullable XmlNode source, @Nullable Boolean childMergeOverride);
112 
113     /**
114      * Merge recessive into dominant and return either {@code dominant}
115      * with merged information or a clone of {@code recessive} if
116      * {@code dominant} is {@code null}.
117      *
118      * @param dominant the node
119      * @param recessive if {@code null}, nothing will happen
120      * @return the merged node
121      */
122     @Nullable
123     static XmlNode merge(@Nullable XmlNode dominant, @Nullable XmlNode recessive) {
124         return merge(dominant, recessive, null);
125     }
126 
127     @Nullable
128     static XmlNode merge(
129             @Nullable XmlNode dominant, @Nullable XmlNode recessive, @Nullable Boolean childMergeOverride) {
130         if (recessive == null) {
131             return dominant;
132         }
133         if (dominant == null) {
134             return recessive;
135         }
136         return dominant.merge(recessive, childMergeOverride);
137     }
138 }