@@ -23,7 +23,6 @@ Jedis _conn() {
2323 }
2424
2525 private enum Command implements ProtocolCommand {
26-
2726 DEL ("JSON.DEL" ),
2827 GET ("JSON.GET" ),
2928 SET ("JSON.SET" ),
@@ -39,14 +38,60 @@ public byte[] getRaw() {
3938 }
4039 }
4140
42- private void assertReplyNotError (final String str ) throws Exception {
41+ /**
42+ * Existential modifier for the set command, by default we don't care
43+ */
44+ public enum ExistenceModifier implements ProtocolCommand {
45+ DEFAULT ("" ),
46+ NOT_EXISTS ("NX" ),
47+ MUST_EXIST ("XX" );
48+ private final byte [] raw ;
49+
50+ ExistenceModifier (String alt ) {
51+ raw = SafeEncoder .encode (alt );
52+ }
53+
54+ public byte [] getRaw () {
55+ return raw ;
56+ }
57+ }
58+
59+ /**
60+ * Helper to check for errors and throw them as an exception
61+ * @param str the reply string to "analyze"
62+ * @throws Exception
63+ */
64+ private void assertReplyNotError (final String str ) {
4365 if (str .startsWith ("-ERR" ))
44- throw new Exception (str .substring (5 ));
66+ throw new RuntimeException (str .substring (5 ));
4567 }
4668
47- private void assertReplyOK (final String str ) throws Exception {
69+ /**
70+ * Helper to check for an OK reply
71+ * @param str the reply string to "scrutinize"
72+ */
73+ private void assertReplyOK (final String str ) {
4874 if (!str .equals ("OK" ))
49- throw new Exception (str );
75+ throw new RuntimeException (str );
76+ }
77+
78+ /**
79+ * Helper to handle single optional path argument situations
80+ * @param path a single optional path
81+ * @return the provided path or root if not
82+ */
83+ private Path getSingleOptionalPath (Path ... path ) {
84+ // check for 0, 1 or more paths
85+ if (1 > path .length ) {
86+ // default to root
87+ return Path .RootPath ();
88+ } else if (1 == path .length ){
89+ // take 1
90+ return path [0 ];
91+ } else {
92+ // throw out the baby with the water
93+ throw new RuntimeException ("Only a single optional path is allowed" );
94+ }
5095 }
5196
5297 /**
@@ -56,7 +101,7 @@ private void assertReplyOK(final String str) throws Exception {
56101 * @param timeout the timeout
57102 * @param poolSize the pool's size
58103 */
59- public Client (final String host , final int port , final int timeout , final int poolSize ) {
104+ public Client (String host , int port , int timeout , int poolSize ) {
60105 JedisPoolConfig conf = new JedisPoolConfig ();
61106 conf .setMaxTotal (poolSize );
62107 conf .setTestOnBorrow (false );
@@ -73,26 +118,31 @@ public Client(final String host, final int port, final int timeout, final int po
73118
74119 }
75120
76- public Client (final String host , final int port ) {
121+ /**
122+ * Create a new client with default timeout and poolSize
123+ * @param host the Redis host
124+ * @param port the Redis port
125+ */
126+ public Client (String host , int port ) {
77127 this (host , port , 500 , 100 );
78128 }
79129
80130 /**
81131 * Deletes a path
82132 * @param key the key name
83- * @param path a path in the object
133+ * @param path optional single path in the object, defaults to root
84134 * @return the number of paths deleted (0 or 1)
85135 */
86- public Long del (final String key , final Path path ) throws Exception {
136+ public Long del (String key , Path ... path ) {
87137 Jedis conn = _conn ();
88- ArrayList <byte []> args = new ArrayList (3 );
138+ ArrayList <byte []> args = new ArrayList (2 );
89139
90140 args .add (SafeEncoder .encode (key ));
91- args .add (SafeEncoder .encode (path .toString ()));
141+ args .add (SafeEncoder .encode (getSingleOptionalPath ( path ) .toString ()));
92142
93143 Long rep = conn .getClient ()
94- .sendCommand (Command .DEL , args .toArray (new byte [args .size ()][]))
95- .getIntegerReply ();
144+ .sendCommand (Command .DEL , args .toArray (new byte [args .size ()][]))
145+ .getIntegerReply ();
96146 conn .close ();
97147
98148 return rep ;
@@ -101,10 +151,10 @@ public Long del(final String key, final Path path) throws Exception {
101151 /**
102152 * Gets an object
103153 * @param key the key name
104- * @param paths a path in the object
154+ * @param paths optional one ore more paths in the object, defaults to root
105155 * @return the requested object
106156 */
107- public Object get (final String key , final Path ... paths ) throws Exception {
157+ public Object get (String key , Path ... paths ) {
108158 Jedis conn = _conn ();
109159 ArrayList <byte []> args = new ArrayList (2 );
110160
@@ -127,17 +177,20 @@ public Object get(final String key, final Path... paths) throws Exception {
127177 /**
128178 * Sets an object
129179 * @param key the key name
130- * @param path a path in the object
131180 * @param object the Java object to store
181+ * @param flag an existential modifier
182+ * @param path optional single path in the object, defaults to root
132183 */
133- public void set (final String key , final Path path , final Object object ) throws Exception {
134- // TODO: support NX|XX flags
184+ public void set (String key , Object object , ExistenceModifier flag , Path ... path ) {
135185 Jedis conn = _conn ();
136- ArrayList <byte []> args = new ArrayList (3 );
186+ ArrayList <byte []> args = new ArrayList (4 );
137187
138188 args .add (SafeEncoder .encode (key ));
139- args .add (SafeEncoder .encode (path .toString ()));
189+ args .add (SafeEncoder .encode (getSingleOptionalPath ( path ) .toString ()));
140190 args .add (SafeEncoder .encode (gson .toJson (object )));
191+ if (ExistenceModifier .DEFAULT != flag ) {
192+ args .add (flag .getRaw ());
193+ }
141194
142195 String status = conn .getClient ()
143196 .sendCommand (Command .SET , args .toArray (new byte [args .size ()][]))
@@ -147,18 +200,28 @@ public void set(final String key, final Path path, final Object object) throws E
147200 assertReplyOK (status );
148201 }
149202
203+ /**
204+ * Sets an object without caring about target path existing
205+ * @param key the key name
206+ * @param object the Java object to store
207+ * @param path optional single path in the object, defaults to root
208+ */
209+ public void set (String key , Object object , Path ... path ) {
210+ this .set (key , object , ExistenceModifier .DEFAULT , path );
211+ }
212+
150213 /**
151214 * Gets the class of an object
152215 * @param key the key name
153- * @param path a path in the object
216+ * @param path optional single path in the object, defaults to root
154217 * @return the Java class of the requested object
155218 */
156- public Class <? extends Object > type (final String key , final Path path ) throws Exception {
219+ public Class <? extends Object > type (String key , Path ... path ) {
157220 Jedis conn = _conn ();
158221 ArrayList <byte []> args = new ArrayList (2 );
159222
160223 args .add (SafeEncoder .encode (key ));
161- args .add (SafeEncoder .encode (path .toString ()));
224+ args .add (SafeEncoder .encode (getSingleOptionalPath ( path ) .toString ()));
162225
163226 String rep = conn .getClient ()
164227 .sendCommand (Command .TYPE , args .toArray (new byte [args .size ()][]))
@@ -183,8 +246,7 @@ public Class<? extends Object> type(final String key, final Path path) throws Ex
183246 case "array" :
184247 return List .class ;
185248 default :
186- throw new Exception (rep );
249+ throw new java . lang . RuntimeException (rep );
187250 }
188251 }
189-
190252}
0 commit comments