1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.configuration2.tree; 18 19 import java.util.Collections; 20 import java.util.HashSet; 21 import java.util.Set; 22 23 /** 24 * <p> 25 * A base class for node combiner implementations. 26 * </p> 27 * <p> 28 * A <em>node combiner</em> is an object that knows how two hierarchical node structures can be combined into a single 29 * one. Of course, there are many possible ways of implementing such a combination, e.g. constructing a union, an 30 * intersection, or an "override" structure (were nodes in the first hierarchy take precedence over nodes in the second 31 * hierarchy). This abstract base class only provides some helper methods and defines the common interface for node 32 * combiners. Concrete sub classes will implement the diverse combination algorithms. 33 * </p> 34 * <p> 35 * For some concrete combiner implementations it is important to distinguish whether a node is a single node or whether 36 * it belongs to a list structure. Alone from the input structures, the combiner will not always be able to make this 37 * decision. So sometimes it may be necessary for the developer to configure the combiner and tell it, which nodes 38 * should be treated as list nodes. For this purpose the {@code addListNode()} method exists. It can be passed the name 39 * of a node, which should be considered a list node. 40 * </p> 41 * 42 * @since 1.3 43 */ 44 public abstract class NodeCombiner { 45 /** 46 * A default handler object for immutable nodes. This object can be used by derived classes for dealing with nodes. 47 * However, it provides only limited functionality; it supports only operations on child nodes, but no references to 48 * parent nodes. 49 */ 50 protected static final NodeHandler<ImmutableNode> HANDLER = createNodeHandler(); 51 52 /** Stores a list with node names that are known to be list nodes. */ 53 private final Set<String> listNodes; 54 55 /** 56 * Creates a new instance of {@code NodeCombiner}. 57 */ 58 public NodeCombiner() { 59 listNodes = new HashSet<>(); 60 } 61 62 /** 63 * Adds the name of a node to the list of known list nodes. This means that nodes with this name will never be combined. 64 * 65 * @param nodeName the name to be added 66 */ 67 public void addListNode(final String nodeName) { 68 listNodes.add(nodeName); 69 } 70 71 /** 72 * Gets a set with the names of nodes that are known to be list nodes. 73 * 74 * @return a set with the names of list nodes 75 */ 76 public Set<String> getListNodes() { 77 return Collections.unmodifiableSet(listNodes); 78 } 79 80 /** 81 * Checks if a node is a list node. This implementation tests if the given node name is contained in the set of known 82 * list nodes. Derived classes which use different criteria may overload this method. 83 * 84 * @param node the node to be tested 85 * @return a flag whether this is a list node 86 */ 87 public boolean isListNode(final ImmutableNode node) { 88 return listNodes.contains(node.getNodeName()); 89 } 90 91 /** 92 * Combines the hierarchies represented by the given root nodes. This method must be defined in concrete sub classes 93 * with the implementation of a specific combination algorithm. 94 * 95 * @param node1 the first root node 96 * @param node2 the second root node 97 * @return the root node of the resulting combined node structure 98 */ 99 public abstract ImmutableNode combine(ImmutableNode node1, ImmutableNode node2); 100 101 /** 102 * Creates a node handler object for immutable nodes which can be used by sub classes to perform advanced operations on 103 * nodes. 104 * 105 * @return the node handler implementation 106 */ 107 private static NodeHandler<ImmutableNode> createNodeHandler() { 108 return new AbstractImmutableNodeHandler() { 109 @Override 110 public ImmutableNode getParent(final ImmutableNode node) { 111 return null; 112 } 113 114 @Override 115 public ImmutableNode getRootNode() { 116 return null; 117 } 118 }; 119 } 120 }