View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2018 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.caravan.hal.comparison.impl.difference;
21  
22  import static io.wcm.caravan.hal.comparison.impl.util.HalJsonConversion.asJson;
23  
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import com.fasterxml.jackson.databind.JsonNode;
28  import com.google.common.collect.ImmutableList;
29  
30  import io.wcm.caravan.hal.comparison.HalComparisonContext;
31  import io.wcm.caravan.hal.comparison.HalDifference;
32  import io.wcm.caravan.hal.comparison.HalDifference.ChangeType;
33  import io.wcm.caravan.hal.comparison.HalDifference.EntityType;
34  import io.wcm.caravan.hal.comparison.impl.context.HalComparisonContextImpl;
35  import io.wcm.caravan.hal.resource.HalResource;
36  import io.wcm.caravan.hal.resource.Link;
37  
38  /**
39   * Simplifies creating properly initialised {@link HalDifferenceImpl} instances.
40   */
41  public class HalDifferenceListBuilder {
42  
43    private final List<HalDifference> differences = new ArrayList<>();
44    private final HalComparisonContextImpl context;
45  
46    /**
47     * @param context specifies in which part of the tree the comparison is currently being executed
48     */
49    public HalDifferenceListBuilder(HalComparisonContextImpl context) {
50      this.context = context;
51    }
52  
53    /**
54     * @return the list of differences that were previously reported to this instance
55     */
56    public List<HalDifference> build() {
57      return ImmutableList.copyOf(differences);
58    }
59  
60    /**
61     * Clear the list of differences that were previously reported to this instance
62     */
63    public void clearPreviouslyReported() {
64      differences.clear();
65    }
66  
67    /**
68     * Merges the differences reported to this and another builder
69     * @param other another builder
70     */
71    public void addAllFrom(HalDifferenceListBuilder other) {
72      differences.addAll(other.build());
73    }
74  
75    /**
76     * Merges the differences reported to this and another builder
77     * @param other list of results
78     */
79    public void addAll(List<HalDifference> other) {
80      differences.addAll(other);
81    }
82  
83    private void addDifference(HalDifference.ChangeType changeType, HalDifference.EntityType entityType,
84        String description, JsonNode expectedJson, JsonNode actualJson) {
85  
86      HalDifference diff = new HalDifferenceImpl(context,
87          changeType, entityType,
88          expectedJson, actualJson, description);
89  
90      differences.add(diff);
91    }
92  
93    private void addDifferenceWithNewContext(HalComparisonContext newContext, HalDifference.ChangeType changeType, HalDifference.EntityType entityType,
94        String description, JsonNode expectedJson, JsonNode actualJson) {
95  
96      HalDifference diff = new HalDifferenceImpl(newContext,
97          changeType, entityType,
98          expectedJson, actualJson, description);
99  
100     differences.add(diff);
101   }
102 
103   /**
104    * @param description
105    * @param actual the link that was added
106    * @param index within the actual array
107    */
108   public void reportAdditionalLink(String description, Link actual, int index) {
109     HalComparisonContext newContext = context.withHalPathIndex(index);
110     addDifferenceWithNewContext(newContext, ChangeType.ADDITIONAL, EntityType.LINK, description, null, asJson(actual));
111   }
112 
113   /**
114    * @param description
115    * @param expected the link that was removed
116    * @param index within the expected array
117    */
118   public void reportMissingLink(String description, Link expected, int index) {
119     HalComparisonContext newContext = context.withHalPathIndex(index);
120     addDifferenceWithNewContext(newContext, ChangeType.MISSING, EntityType.LINK, description, asJson(expected), null);
121   }
122 
123   /**
124    * @param description
125    * @param expected the link found in the ground truth resource
126    * @param actual the link that was found instead
127    */
128   public void reportModifiedLink(String description, Link expected, Link actual) {
129     addDifference(ChangeType.MODIFIED, EntityType.LINK, description, asJson(expected), asJson(actual));
130   }
131 
132   /**
133    * @param description
134    * @param expected the links in their original order
135    * @param actual the links in their new order
136    */
137   public void reportReorderedLinks(String description, Iterable<Link> expected, Iterable<Link> actual) {
138     addDifference(ChangeType.REORDERED, EntityType.LINK, description, asJson(expected), asJson(actual));
139   }
140 
141   /**
142    * @param description
143    * @param actual the embedded resource that was added
144    * @param index within the actual array
145    */
146   public void reportAdditionalEmbedded(String description, HalResource actual, int index) {
147     HalComparisonContext newContext = context.withHalPathIndex(index);
148     addDifferenceWithNewContext(newContext, ChangeType.ADDITIONAL, EntityType.EMBEDDED, description, null, asJson(actual));
149   }
150 
151   /**
152    * @param description
153    * @param expected the embedded resource that was removed
154    * @param index within the actual array
155    */
156   public void reportMissingEmbedded(String description, HalResource expected, int index) {
157     HalComparisonContext newContext = context.withHalPathIndex(index);
158     addDifferenceWithNewContext(newContext, ChangeType.MISSING, EntityType.EMBEDDED, description, asJson(expected), null);
159   }
160 
161   /**
162    * @param description
163    * @param expected the embedded resource in the ground truth resource
164    * @param actual the embedded resource that was found instead
165    */
166   public void reportModifiedEmbedded(String description, HalResource expected, HalResource actual) {
167     addDifference(ChangeType.MODIFIED, EntityType.EMBEDDED, description, asJson(expected), asJson(actual));
168   }
169 
170   /**
171    * @param description
172    * @param expected the embedded resources in their original order
173    * @param actual the embedded resources in their new order
174    */
175   public void reportReorderedEmbedded(String description, Iterable<HalResource> expected, Iterable<HalResource> actual) {
176     addDifference(ChangeType.REORDERED, EntityType.EMBEDDED, description, asJson(expected), asJson(actual));
177   }
178 
179   /**
180    * @param description
181    * @param actual the property that was added
182    */
183   public void reportAdditionalProperty(String description, JsonNode actual) {
184     addDifference(ChangeType.ADDITIONAL, EntityType.PROPERTY, description, null, actual);
185   }
186 
187   /**
188    * @param description
189    * @param actual the property that was added
190    * @param index within the actual array
191    */
192   public void reportAdditionalProperty(String description, JsonNode actual, int index) {
193     HalComparisonContext newContext = context.withJsonPathIndex(index);
194     addDifferenceWithNewContext(newContext, ChangeType.ADDITIONAL, EntityType.PROPERTY, description, null, actual);
195   }
196 
197   /**
198    * @param description
199    * @param expected the property that was removed
200    */
201   public void reportMissingProperty(String description, JsonNode expected) {
202     addDifference(ChangeType.MISSING, EntityType.PROPERTY, description, expected, null);
203   }
204 
205   /**
206    * @param description
207    * @param expected the property that was removed
208    * @param index within the expected array
209    */
210   public void reportMissingProperty(String description, JsonNode expected, int index) {
211     HalComparisonContext newContext = context.withJsonPathIndex(index);
212     addDifferenceWithNewContext(newContext, ChangeType.MISSING, EntityType.PROPERTY, description, expected, null);
213   }
214 
215   /**
216    * @param description
217    * @param expected the property from the ground truth resource
218    * @param actual the property that was found instead
219    */
220   public void reportModifiedProperty(String description, JsonNode expected, JsonNode actual) {
221     addDifference(ChangeType.MODIFIED, EntityType.PROPERTY, description, expected, actual);
222   }
223 
224   /**
225    * @param description
226    * @param expected the properties in their original order
227    * @param actual the properties in their new order
228    */
229   public void reportReorderedProperty(String description, JsonNode expected, JsonNode actual) {
230     addDifference(ChangeType.REORDERED, EntityType.PROPERTY, description, expected, actual);
231   }
232 
233 }