|
1 | 1 | (ns ^{:doc "Internal implementation details."
|
2 | 2 | :no-doc true}
|
3 | 3 | jq.api.api-impl
|
| 4 | + (:require [clojure.string :as str]) |
4 | 5 | (:import (java.util ArrayList)
|
5 | 6 | (net.thisptr.jackson.jq JsonQuery Versions Scope BuiltinFunctionLoader Output)
|
6 | 7 | (com.fasterxml.jackson.databind ObjectMapper JsonNode)
|
7 |
| - (com.fasterxml.jackson.databind.node JsonNodeFactory) |
| 8 | + (com.fasterxml.jackson.databind.node ArrayNode JsonNodeFactory) |
8 | 9 | (net.thisptr.jackson.jq.module.loaders ChainedModuleLoader BuiltinModuleLoader FileSystemModuleLoader)
|
9 | 10 | (net.thisptr.jackson.jq.module ModuleLoader)
|
10 | 11 | (java.nio.file Path)
|
|
63 | 64 | scope)
|
64 | 65 | old-scope))
|
65 | 66 |
|
| 67 | +(defn string->json-node ^JsonNode [^String data] |
| 68 | + (.readTree mapper data)) |
| 69 | + |
| 70 | +(defn json-node->string ^String [^JsonNode data] |
| 71 | + (.writeValueAsString mapper data)) |
| 72 | + |
66 | 73 | ; Helper interface that specifies a method to get a string value.
|
67 | 74 | (definterface IContainer
|
68 | 75 | ; net.thisptr.jackson.jq/Output
|
69 |
| - (^com.fasterxml.jackson.databind.JsonNode getValue [])) |
| 76 | + (^java.lang.Iterable getValue [])) |
70 | 77 |
|
71 | 78 | ; Container class helper that implements the net.thisptr.jackson.jq.Output
|
72 | 79 | ; interface that enables the class to be used as a callback for JQ and exposes the
|
73 | 80 | ; unsynchronized-mutable container field for the result of the JQ transformation.
|
74 |
| -(deftype SingleOutputContainer [^:unsynchronized-mutable ^JsonNode container] |
| 81 | +(deftype JsonNodeOutputContainer [^ArrayNode container] |
75 | 82 | Output
|
76 |
| - (emit [_ json-node] (set! container json-node)) |
| 83 | + (emit [_ json-node] (.add container json-node)) |
77 | 84 | IContainer
|
78 | 85 | (getValue [_] container))
|
79 | 86 |
|
80 |
| -(deftype MultiOutputContainer [^ArrayList container] |
| 87 | +(defn json-node-output-container [] |
| 88 | + (JsonNodeOutputContainer. (.arrayNode JsonNodeFactory/instance))) |
| 89 | + |
| 90 | +(deftype StringOutputContainer [^ArrayList container] |
81 | 91 | Output
|
82 |
| - (emit [_ json-node] |
83 |
| - (.add container json-node)) |
| 92 | + (emit [_ json-node] (.add container (json-node->string json-node))) |
84 | 93 | IContainer
|
85 |
| - (getValue [_] |
86 |
| - (let [jsonArray (.arrayNode JsonNodeFactory/instance (.size container))] |
87 |
| - (doseq [^JsonNode item container] |
88 |
| - (.add jsonArray item)) |
89 |
| - (.clear container) |
90 |
| - jsonArray))) |
| 94 | + (getValue [_] container)) |
91 | 95 |
|
92 |
| -(defn NewMultiOutputContainer [] |
93 |
| - (MultiOutputContainer. (ArrayList.))) |
| 96 | +(defn string-output-container [] |
| 97 | + (StringOutputContainer. (ArrayList.))) |
94 | 98 |
|
95 | 99 | (defn apply-json-query-on-json-node
|
96 | 100 | "Given a JSON data string and a JsonQuery object applies the query
|
97 | 101 | on the JSON data string and return JsonNode; may be given a custom IContainer"
|
98 |
| - (^JsonNode [^JsonNode json-node ^JsonQuery json-query ^Scope scope ^IContainer output-container] |
99 |
| - (let [^IContainer output-container (or output-container (SingleOutputContainer. nil))] |
100 |
| - (.apply json-query (Scope/newChildScope scope) json-node output-container) |
101 |
| - (.getValue output-container))) |
102 |
| - (^JsonNode [^JsonNode json-node ^JsonQuery json-query ^Scope scope] |
103 |
| - (apply-json-query-on-json-node json-node json-query scope nil))) |
| 102 | + ([^JsonNode json-node ^JsonQuery json-query ^Scope scope ^IContainer container] |
| 103 | + (.apply json-query (Scope/newChildScope scope) json-node container) |
| 104 | + (.getValue container)) |
| 105 | + ([^JsonNode json-node ^JsonQuery json-query ^Scope scope] |
| 106 | + (apply-json-query-on-json-node json-node json-query scope (json-node-output-container)))) |
104 | 107 |
|
105 |
| -(defn string->json-node ^JsonNode [^String data] |
106 |
| - (.readTree mapper data)) |
107 |
| - |
108 |
| -(defn json-node->string ^String [^JsonNode data] |
109 |
| - (.writeValueAsString mapper data)) |
| 108 | +(defn apply-json-query-on-json-node-data |
| 109 | + "Passes a JsonNode to the query executor." |
| 110 | + ^String [^JsonNode data ^JsonQuery query ^Scope scope] |
| 111 | + (str/join "\n" (apply-json-query-on-json-node data query scope (string-output-container)))) |
110 | 112 |
|
111 | 113 | (defn apply-json-query-on-string-data
|
112 | 114 | "Reads data JSON string into a JsonNode and passes to the query executor."
|
113 |
| - ^String [^String data ^JsonQuery query ^Scope scope ^IContainer output-container] |
114 |
| - (json-node->string (apply-json-query-on-json-node (string->json-node data) query scope output-container))) |
115 |
| - |
116 |
| -(defn apply-json-query-on-json-node-data |
117 |
| - "Reads data JSON string into a JsonNode and passes to the query executor." |
118 |
| - ^String [^JsonNode data ^JsonQuery query ^Scope scope ^IContainer output-container] |
119 |
| - (json-node->string (apply-json-query-on-json-node data query scope output-container))) |
| 115 | + ^String [^String data ^JsonQuery query ^Scope scope] |
| 116 | + (apply-json-query-on-json-node-data (string->json-node data) query scope)) |
120 | 117 |
|
121 | 118 | (defn new-scope
|
122 | 119 | (^Scope [] (Scope/newChildScope root-scope))
|
|
0 commit comments