Newer Version Available

This content describes an older version of this product. View Latest

How to Reconstruct a Field from Its Diff Value

The value of a diff field is in the unified diff format. Use a diff utility to obtain the full field value from the diff.

For example, you can use the Java Diff Utilities library.

The following code sample shows the order of operations and the library tools used. The toLines() method, which you implement, splits the diff value into a list of lines. The BufferedReader Java object determines how the newline character is represented, so you don’t need to pass in the newLine value.

Next, patches are obtained from the diff lines through the Java diff utility method DiffUtils.parseUnifiedDiff(). The patches are the changes applied to the content. The toLines() method is called again to split the original content into lines. The patches are then applied to the original lines using the DiffUtils.patch() method.

You implement the combineLines() method to combine the updated lines into one string variable. The newLine variable is passed to combineLines() to reintroduce the original line breaks in the text. Set the newLine variable to the newline character sequence that was in the original content (\r\n or \n). For more information, see Considerations for Newline Characters and Computing the SHA-256 Hash. The revised string variable is the reconstructed value from the diff that contains the updates.

The final step is to generate a SHA-256 hash value to validate that the original updated value matches the reconstructed value. To generate a hash, use the Apache Common DigestUtils library. After the hash is generated, compare it to the one sent in the event and ensure that both hash values are equal.

1public void BuildOriginalValueFromDiff(String original, String diff, String newLine) {
2    // Split diff value into lines and get patches.
3    List<String> diffLines = toLines(diff);
4    Patch<String> patch = DiffUtils.parseUnifiedDiff(diffLines);
5
6    // Split original text into lines.
7    List<String> originalLines = toLines(original);
8
9    // Apply patches to original lines, then combined lines.
10    List<String> revisedLines = DiffUtils.patch(originalLines, patch);
11    String revised = combineLines(revisedLines, newLine);
12
13    // Generate SHA-256 hash on reconstructed value.
14    String checkSum = DigestUtils.sha256Hex(revised);
15
16    // Extract hash from the event diff field.
17
18    // Compare extracted hash with generated hash and verify they are equal.
19}

The following are examples of what to implement to split lines and combine lines.

1private List<String> toLines(String s) {
2    BufferedReader rd = new BufferedReader(new StringReader(s));
3    return rd.lines().collect(Collectors.toList());
4}
5
6private String combineLines(List<String> lines, String newLine) {
7    StringBuilder sb = new StringBuilder();
8    lines.forEach(l -> sb.append(l).append(newLine));
9    sb.deleteCharAt(sb.length()-newLine.length());  // remove last newline added
10    return sb.toString();
11}