2929package com .redislabs .modules .rejson ;
3030
3131import com .google .gson .Gson ;
32+
3233import redis .clients .jedis .Jedis ;
34+ import redis .clients .jedis .JedisPool ;
3335import redis .clients .jedis .commands .ProtocolCommand ;
36+ import redis .clients .jedis .util .Pool ;
3437import redis .clients .jedis .util .SafeEncoder ;
3538
3639import java .util .ArrayList ;
4144 */
4245public class JReJSON {
4346
44- private static Gson gson = new Gson ();
47+ private static final Gson gson = new Gson ();
4548
4649 private enum Command implements ProtocolCommand {
4750 DEL ("JSON.DEL" ),
@@ -77,6 +80,34 @@ public byte[] getRaw() {
7780 }
7881 }
7982
83+ private Pool <Jedis > client ;
84+
85+ /**
86+ * Creates a client to the local machine
87+ */
88+ public JReJSON () {
89+ this ("localhost" , 6379 );
90+ }
91+
92+ /**
93+ * Creates a client to the specific host/post
94+ *
95+ * @param host Redis host
96+ * @param port Redis port
97+ */
98+ public JReJSON (String host , int port ) {
99+ this (new JedisPool (host , port ));
100+ }
101+
102+ /**
103+ * Creates a client using provided Jedis pool
104+ *
105+ * @param jedis bring your own Jedis pool
106+ */
107+ public JReJSON (Pool <Jedis > jedis ) {
108+ this .client = jedis ;
109+ }
110+
80111 /**
81112 * Helper to check for errors and throw them as an exception
82113 * @param str the reply string to "analyze"
@@ -103,27 +134,197 @@ private static void assertReplyOK(final String str) {
103134 */
104135 private static Path getSingleOptionalPath (Path ... path ) {
105136 // check for 0, 1 or more paths
106- if (1 > path .length )
107- // default to root
137+ if (1 > path .length ) { // default to root
108138 return Path .RootPath ();
109- else if ( 1 == path . length )
110- // take 1
139+ }
140+ if ( 1 == path . length ) { // take 1
111141 return path [0 ];
112- else
113- // throw out the baby with the water
114- throw new RuntimeException ("Only a single optional path is allowed" );
142+ }
143+
144+ // throw out the baby with the water
145+ throw new RuntimeException ("Only a single optional path is allowed" );
146+ }
147+
148+ /**
149+ * Deletes the root path
150+ * @param key the key name
151+ * @return the number of paths deleted (0 or 1)
152+ */
153+ public Long del (String key ) {
154+ return del (key , Path .ROOT_PATH );
155+ }
156+
157+
158+ /**
159+ * Deletes a path
160+ * @param key the key name
161+ * @param path optional single path in the object, defaults to root
162+ * @return path deleted
163+ */
164+ public Long del (String key , Path path ) {
165+ byte [][] args = new byte [2 ][];
166+ args [0 ] = SafeEncoder .encode (key );
167+ args [1 ] = SafeEncoder .encode (path .toString ());
168+
169+ try (Jedis conn = getConnection ()) {
170+ conn .getClient ().sendCommand (Command .DEL , args );
171+ return conn .getClient ().getIntegerReply ();
172+ }
173+ }
174+
175+ /**
176+ * Gets an object at the root path
177+ * @param key the key name
178+ * @return the requested object
179+ */
180+ public Object get (String key ) {
181+ return get (key , Path .ROOT_PATH );
182+ }
183+
184+ /**
185+ * Gets an object
186+ * @param key the key name
187+ * @param paths optional one ore more paths in the object
188+ * @return the requested object
189+ */
190+ public Object get (String key , Path ... paths ) {
191+ byte [][] args = new byte [1 + paths .length ][];
192+ int i =0 ;
193+ args [i ] = SafeEncoder .encode (key );
194+ for (Path p :paths ) {
195+ args [++i ] = SafeEncoder .encode (p .toString ());
196+ }
197+
198+ String rep ;
199+ try (Jedis conn = getConnection ()) {
200+ conn .getClient ().sendCommand (Command .GET , args );
201+ rep = conn .getClient ().getBulkReply ();
202+ }
203+ assertReplyNotError (rep );
204+ return gson .fromJson (rep , Object .class );
205+ }
206+
207+ /**
208+ * Sets an object at the root path
209+ * @param key the key name
210+ * @param object the Java object to store
211+ * @param flag an existential modifier
212+ */
213+ public void set (String key , Object object , ExistenceModifier flag ) {
214+ set (key , object , flag , Path .ROOT_PATH );
215+ }
216+
217+ /**
218+ * Sets an object in the root path
219+ * @param key the key name
220+ * @param object the Java object to store
221+ * @param path in the object
222+ */
223+ public void set (String key , Object object ) {
224+ set (key , object , ExistenceModifier .DEFAULT , Path .ROOT_PATH );
225+ }
226+
227+ /**
228+ * Sets an object without caring about target path existing
229+ * @param key the key name
230+ * @param object the Java object to store
231+ * @param path in the object
232+ */
233+ public void set (String key , Object object , Path path ) {
234+ set (key , object , ExistenceModifier .DEFAULT , path );
235+ }
236+
237+ /**
238+ * Sets an object
239+ * @param key the key name
240+ * @param object the Java object to store
241+ * @param flag an existential modifier
242+ * @param path in the object
243+ */
244+ public void set (String key , Object object , ExistenceModifier flag , Path path ) {
245+
246+ List <byte []> args = new ArrayList <>(4 );
247+
248+ args .add (SafeEncoder .encode (key ));
249+ args .add (SafeEncoder .encode (path .toString ()));
250+ args .add (SafeEncoder .encode (gson .toJson (object )));
251+ if (ExistenceModifier .DEFAULT != flag ) {
252+ args .add (flag .getRaw ());
253+ }
254+
255+ String status ;
256+ try (Jedis conn = getConnection ()) {
257+ conn .getClient ()
258+ .sendCommand (Command .SET , args .toArray (new byte [args .size ()][]));
259+ status = conn .getClient ().getStatusCodeReply ();
260+ }
261+ assertReplyOK (status );
262+ }
263+
264+ /**
265+ * Gets the class of an object at the root path
266+ * @param key the key name
267+ * @return the Java class of the requested object
268+ */
269+ public Class <?> type (String key ) {
270+ return type (key );
271+ }
272+
273+ /**
274+ * Gets the class of an object
275+ * @param key the key name
276+ * @param path a path in the object
277+ * @return the Java class of the requested object
278+ */
279+ public Class <?> type (String key , Path path ) {
280+
281+ List <byte []> args = new ArrayList <>(2 );
282+
283+ args .add (SafeEncoder .encode (key ));
284+ args .add (SafeEncoder .encode (path .toString ()));
285+
286+ String rep ;
287+ try (Jedis conn = getConnection ()) {
288+ conn .getClient ()
289+ .sendCommand (Command .TYPE , args .toArray (new byte [args .size ()][]));
290+ rep = conn .getClient ().getBulkReply ();
291+ }
292+
293+ assertReplyNotError (rep );
294+
295+ switch (rep ) {
296+ case "null" :
297+ return null ;
298+ case "boolean" :
299+ return boolean .class ;
300+ case "integer" :
301+ return int .class ;
302+ case "number" :
303+ return float .class ;
304+ case "string" :
305+ return String .class ;
306+ case "object" :
307+ return Object .class ;
308+ case "array" :
309+ return List .class ;
310+ default :
311+ throw new java .lang .RuntimeException (rep );
312+ }
115313 }
314+
116315
117316 /**
118317 * Deletes a path
119318 * @param conn the Jedis connection
120319 * @param key the key name
121320 * @param path optional single path in the object, defaults to root
122321 * @return the number of paths deleted (0 or 1)
322+ * @deprecated use {@link #del(String, Path...)} instead
123323 */
324+ @ Deprecated
124325 public static Long del (Jedis conn , String key , Path ... path ) {
125326
126- List <byte []> args = new ArrayList (2 );
327+ List <byte []> args = new ArrayList <> (2 );
127328
128329 args .add (SafeEncoder .encode (key ));
129330 args .add (SafeEncoder .encode (getSingleOptionalPath (path ).toString ()));
@@ -142,10 +343,12 @@ public static Long del(Jedis conn, String key, Path... path) {
142343 * @param key the key name
143344 * @param paths optional one ore more paths in the object, defaults to root
144345 * @return the requested object
346+ * @deprecated use {@link #get(String, Path...)} instead
145347 */
348+ @ Deprecated
146349 public static Object get (Jedis conn , String key , Path ... paths ) {
147350
148- List <byte []> args = new ArrayList (2 );
351+ List <byte []> args = new ArrayList <> (2 );
149352
150353 args .add (SafeEncoder .encode (key ));
151354 for (Path p :paths ) {
@@ -168,10 +371,12 @@ public static Object get(Jedis conn, String key, Path... paths) {
168371 * @param object the Java object to store
169372 * @param flag an existential modifier
170373 * @param path optional single path in the object, defaults to root
374+ * @deprecated use {@link #set(String, Object, ExistenceModifier, Path...)} instead
171375 */
376+ @ Deprecated
172377 public static void set (Jedis conn , String key , Object object , ExistenceModifier flag , Path ... path ) {
173378
174- List <byte []> args = new ArrayList (4 );
379+ List <byte []> args = new ArrayList <> (4 );
175380
176381 args .add (SafeEncoder .encode (key ));
177382 args .add (SafeEncoder .encode (getSingleOptionalPath (path ).toString ()));
@@ -194,7 +399,9 @@ public static void set(Jedis conn, String key, Object object, ExistenceModifier
194399 * @param key the key name
195400 * @param object the Java object to store
196401 * @param path optional single path in the object, defaults to root
402+ * @deprecated use {@link #set(String, Object, ExistenceModifier, Path...)} instead
197403 */
404+ @ Deprecated
198405 public static void set (Jedis conn , String key , Object object , Path ... path ) {
199406 set (conn ,key , object , ExistenceModifier .DEFAULT , path );
200407 }
@@ -205,10 +412,12 @@ public static void set(Jedis conn, String key, Object object, Path... path) {
205412 * @param key the key name
206413 * @param path optional single path in the object, defaults to root
207414 * @return the Java class of the requested object
415+ * @deprecated use {@link #type(String, Path...)} instead
208416 */
417+ @ Deprecated
209418 public static Class <?> type (Jedis conn , String key , Path ... path ) {
210419
211- List <byte []> args = new ArrayList (2 );
420+ List <byte []> args = new ArrayList <> (2 );
212421
213422 args .add (SafeEncoder .encode (key ));
214423 args .add (SafeEncoder .encode (getSingleOptionalPath (path ).toString ()));
@@ -239,4 +448,8 @@ public static Class<?> type(Jedis conn, String key, Path... path) {
239448 throw new java .lang .RuntimeException (rep );
240449 }
241450 }
451+
452+ private Jedis getConnection () {
453+ return this .client .getResource ();
454+ }
242455}
0 commit comments