View Javadoc
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 }