91c523ed1c56d57e831c3caa73c83a8f6fa29f7c
[policy/apex-pdp.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.model.utilities.comparison;
22
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.TreeMap;
27
28 /**
29  * This class holds the result of a difference check between two keyed maps. Four results are returned in the class. The
30  * {@code leftOnly} result is the entries that appear only in the left map. the {@code rightOnly} result is the entries
31  * that appear only in the right map. The {@code differentValues} result are the entries that have the same key but
32  * different values in the maps being compared. The {@code identicalValues} result are the entries with identical keys
33  * and values in both maps being compared.
34  *
35  * @author Liam Fallon (liam.fallon@ericsson.com)
36  * @param <K> the generic type
37  * @param <V> the generic type
38  */
39 public class KeyedMapDifference<K, V> {
40     private static final String KEY = "key=";
41     private static final String VALUE = ",value=";
42
43     // Three maps to hold the comparison result
44     private Map<K, V> leftOnly = new TreeMap<>();
45     private Map<K, V> rightOnly = new TreeMap<>();
46     private Map<K, V> identicalValues = new TreeMap<>();
47     private Map<K, List<V>> differentValues = new TreeMap<>();
48
49     /**
50      * Gets the entries that were found only in the left map.
51      *
52      * @return the entries only in the left map
53      */
54     public Map<K, V> getLeftOnly() {
55         return leftOnly;
56     }
57
58     /**
59      * Gets the entries that were found only in the right map.
60      *
61      * @return the entries only in the right map
62      */
63     public Map<K, V> getRightOnly() {
64         return rightOnly;
65     }
66
67     /**
68      * Gets the entries that were identical (keys and values the same) in both maps.
69      *
70      * @return the identical entries
71      */
72     public Map<K, V> getIdenticalValues() {
73         return identicalValues;
74     }
75
76     /**
77      * Gets the entries that had the same key but different values in both maps.
78      *
79      * @return the entries that were different. There are two values in the list of values for each entry. The first
80      *         value is the value that was in the left map and the second value is the value that was in the right map.
81      */
82     public Map<K, List<V>> getDifferentValues() {
83         return differentValues;
84     }
85
86     /**
87      * Return a string representation of the differences.
88      *
89      * @param diffsOnly if set, then a blank string is returned if the maps are equal
90      * @param keysOnly if set, then a terse string that prints only the keys is returned, otherwise both keys and values
91      *        are printed
92      * @return the string
93      */
94     public String asString(final boolean diffsOnly, final boolean keysOnly) {
95         StringBuilder builder = new StringBuilder();
96
97         if (leftOnly.isEmpty()) {
98             if (!diffsOnly) {
99                 builder.append("*** all left keys in right\n");
100             }
101         } else {
102             builder.append(getInOneSideOnlyAsString(leftOnly, "left", keysOnly));
103         }
104
105         if (rightOnly.isEmpty()) {
106             if (!diffsOnly) {
107                 builder.append("*** all right keys in left\n");
108             }
109         } else {
110             builder.append(getInOneSideOnlyAsString(rightOnly, "right", keysOnly));
111         }
112
113         if (differentValues.isEmpty()) {
114             if (!diffsOnly) {
115                 builder.append("*** all values in left and right are identical\n");
116             }
117         } else {
118             builder.append(getDifferencesAsString(keysOnly));
119         }
120
121         if (!diffsOnly) {
122             builder.append(getIdenticalsAsString(keysOnly));
123         }
124
125         return builder.toString();
126     }
127
128     /**
129      * Output the entries in a map with entries that are in one side only as a string.
130      * 
131      * @param sideMap the map for the side being checked
132      * @param sideMapString the string that represents the map in output strings
133      * @param keysOnly if true, just add key information and not entries
134      * @return the entries as a string
135      */
136     private Object getInOneSideOnlyAsString(final Map<K, V> sideMap, final String sideMapString,
137                     final boolean keysOnly) {
138         StringBuilder builder = new StringBuilder();
139
140         builder.append("*** list of keys on " + sideMapString + " only\n");
141         for (Entry<K, V> leftEntry : sideMap.entrySet()) {
142             builder.append(KEY);
143             builder.append(leftEntry.getKey());
144             if (!keysOnly) {
145                 builder.append(VALUE);
146                 builder.append(leftEntry.getValue());
147             }
148             builder.append('\n');
149         }
150
151         return builder.toString();
152     }
153
154     /**
155      * Output the differences between two the maps as a string.
156      * 
157      * @param keysOnly if true, just add key information and not entries
158      * @return the differences as a string
159      */
160     private String getDifferencesAsString(final boolean keysOnly) {
161         StringBuilder builder = new StringBuilder();
162
163         builder.append("*** list of differing entries between left and right\n");
164         for (Entry<K, List<V>> differentEntry : differentValues.entrySet()) {
165             builder.append(KEY);
166             builder.append(differentEntry.getKey());
167             if (!keysOnly) {
168                 builder.append(",values={");
169                 boolean first = true;
170                 for (V differentEntryValue : differentEntry.getValue()) {
171                     builder.append(differentEntryValue);
172                     if (first) {
173                         first = false;
174                     } else {
175                         builder.append(',');
176                     }
177                 }
178                 builder.append("}");
179             }
180             builder.append('\n');
181         }
182
183         return builder.toString();
184     }
185
186     /**
187      * Output the identical entries in the maps as a string.
188      * 
189      * @param keysOnly if true, just add key information and not entries
190      * @return the identical entries as a string
191      */
192     private String getIdenticalsAsString(final boolean keysOnly) {
193         StringBuilder builder = new StringBuilder();
194
195         builder.append("*** list of identical entries in left and right\n");
196         for (Entry<K, V> identicalEntry : identicalValues.entrySet()) {
197             builder.append(KEY);
198             builder.append(identicalEntry.getKey());
199             if (!keysOnly) {
200                 builder.append(VALUE);
201                 builder.append(identicalEntry.getValue());
202             }
203             builder.append('\n');
204         }
205
206         return builder.toString();
207     }
208 }