1 /*
2 * #%L
3 * wcm.io
4 * %%
5 * Copyright (C) 2014 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.testing.json;
21
22 import java.io.InputStream;
23
24 import org.osgi.annotation.versioning.ProviderType;
25
26 import com.fasterxml.jackson.databind.JsonNode;
27 import com.jayway.jsonpath.DocumentContext;
28 import com.jayway.jsonpath.JsonPath;
29 import com.jayway.jsonpath.Predicate;
30
31 /**
32 * A wrapper for JSON payload and JSON path operations which create a new {@link JsonFixture} object.
33 */
34 @ProviderType
35 public final class JsonFixture {
36
37 private final DocumentContext doc;
38
39 /**
40 * @param input The payload input stream
41 */
42 public JsonFixture(final InputStream input) {
43 doc = JsonPath.parse(input);
44 }
45
46 private JsonFixture(final DocumentContext context) {
47 this.doc = context;
48 }
49
50 /**
51 * Adds the value to array at the given path.
52 * @param path The JSON path
53 * @param value The value to add
54 * @param filters Optional JSON path filters
55 * @return The new JSON fixture
56 */
57 public JsonFixture add(final String path, final Object value, final Predicate... filters) {
58 return new JsonFixture(cloneContext().add(path, value, filters));
59 }
60
61 /**
62 * Deletes JSON nodes at the given path.
63 * @param path The JSON path
64 * @param filters Optional JSON path filters
65 * @return The new JSON fixture
66 */
67 public JsonFixture delete(final String path, final Predicate... filters) {
68 return new JsonFixture(cloneContext().delete(JsonPath.compile(path, filters)));
69 }
70
71 /**
72 * Adds or updates the value for a given key on the given path.
73 * @param path The JSON path
74 * @param key The JSON object key
75 * @param value The new value
76 * @param filters Optional JSON path filters
77 * @return The new JSON fixture
78 */
79 public JsonFixture put(final String path, final String key, final Object value, final Predicate... filters) {
80 return new JsonFixture(cloneContext().put(path, key, value, filters));
81 }
82
83 /**
84 * Extracts the JSON node elements at the given path.
85 * @param path The JSON path
86 * @param filters Optional JSON path filters
87 * @return The new JSON fixture
88 */
89 public JsonFixture read(final String path, final Predicate... filters) {
90 JsonNode extracted = cloneContext().read(path, JsonNode.class, filters);
91 return new JsonFixture(JsonPath.parse(extracted));
92 }
93
94 /**
95 * Sets a new value at the given path.
96 * @param path The JSON path
97 * @param value The new value
98 * @param filters Optional JSON path filters
99 * @return The new JSON fixture
100 */
101 public JsonFixture set(final String path, final Object value, final Predicate... filters) {
102 return new JsonFixture(cloneContext().set(path, value, filters));
103 }
104
105 private DocumentContext cloneContext() {
106 // TODO: Check for better cloning possibility
107 return JsonPath.parse(toJsonNode().toString());
108 }
109
110 @Override
111 public String toString() {
112 return toJsonNode().toString();
113 }
114
115 /**
116 * @return The JsonNode representation for the payload
117 */
118 public JsonNode toJsonNode() {
119 return (JsonNode)doc.read("$");
120 }
121
122 DocumentContext getDocumentContext() {
123 return doc;
124 }
125
126 }