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  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 }