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.ArrayList; 20 import java.util.Collection; 21 import java.util.Collections; 22 import java.util.HashMap; 23 import java.util.Map; 24 25 /** 26 * <p> 27 * A simple data class used by node models to store parameters of an update operation. 28 * </p> 29 * <p> 30 * The {@code Configuration} interface provides a method for setting the value of a given key. The passed in value can 31 * be a single object or a collection of values. This makes an update operation rather complicated because a collection 32 * of query results selected by the passed in key has to be matched to another collection of values - and both 33 * collections can have different sizes. Therefore, an update operation may involve changing of existing nodes, adding 34 * new nodes (if there are more values than currently existing nodes), and removing nodes (if there are more existing 35 * nodes than provided values). This class collects all this information making it possible to actually perform the 36 * update based on a passed in instance. 37 * </p> 38 * 39 * @since 2.0 40 * @param <T> the type of nodes involved in this update operation 41 */ 42 public class NodeUpdateData<T> { 43 /** The map with the query results whose value has to be changed. */ 44 private final Map<QueryResult<T>, Object> changedValues; 45 46 /** The collection with the new values to be added. */ 47 private final Collection<Object> newValues; 48 49 /** The collection with query results about the nodes to be removed. */ 50 private final Collection<QueryResult<T>> removedNodes; 51 52 /** The key of the current update operation. */ 53 private final String key; 54 55 /** 56 * Creates a new instance of {@code NodeUpdateData} and initializes all its properties. All passed in collections are 57 * optional and can be <b>null</b>. 58 * 59 * @param changedValues the map defining the changed values 60 * @param newValues the collection with the new values 61 * @param removedNodes the collection with the nodes to be removed 62 * @param key the key of the update operation 63 */ 64 public NodeUpdateData(final Map<QueryResult<T>, Object> changedValues, final Collection<Object> newValues, final Collection<QueryResult<T>> removedNodes, 65 final String key) { 66 this.changedValues = copyMap(changedValues); 67 this.newValues = copyCollection(newValues); 68 this.removedNodes = copyCollection(removedNodes); 69 this.key = key; 70 } 71 72 /** 73 * Gets an unmodifiable map with the values to be changed. The keys of the map are the query results for the nodes 74 * affected, the values are the new values to be assigned to these nodes. 75 * 76 * @return the map with values to be changed 77 */ 78 public Map<QueryResult<T>, Object> getChangedValues() { 79 return changedValues; 80 } 81 82 /** 83 * Gets a collection with the values to be newly added. For these values new nodes have to be created and added under 84 * the key stored in this object. 85 * 86 * @return the collection with new values 87 */ 88 public Collection<Object> getNewValues() { 89 return newValues; 90 } 91 92 /** 93 * Adds a collection with the nodes to be removed. These nodes are no longer needed and have to be removed from the node 94 * model processing this request. 95 * 96 * @return the collection with nodes to be removed 97 */ 98 public Collection<QueryResult<T>> getRemovedNodes() { 99 return removedNodes; 100 } 101 102 /** 103 * Gets the key for this update operation. 104 * 105 * @return the key for this operation 106 */ 107 public String getKey() { 108 return key; 109 } 110 111 /** 112 * Creates an unmodifiable defensive copy of the passed in map which may be null. 113 * 114 * @param map the map to be copied 115 * @param <K> the type of the keys involved 116 * @param <V> the type of the values involved 117 * @return the unmodifiable copy 118 */ 119 private static <K, V> Map<K, V> copyMap(final Map<? extends K, ? extends V> map) { 120 if (map == null) { 121 return Collections.emptyMap(); 122 } 123 return Collections.unmodifiableMap(new HashMap<>(map)); 124 } 125 126 /** 127 * Creates an unmodifiable defensive copy of the passed in collection with may be null. 128 * 129 * @param col the collection to be copied 130 * @param <T> the element type of the collection 131 * @return the unmodifiable copy 132 */ 133 private static <T> Collection<T> copyCollection(final Collection<? extends T> col) { 134 if (col == null) { 135 return Collections.emptySet(); 136 } 137 return Collections.unmodifiableCollection(new ArrayList<>(col)); 138 } 139 }