Skip to content

Commit d26c20a

Browse files
authored
Merge pull request briandilley#173 from indvd00m/master
Possibility to explicitly define how to pass method parameters in JSON
2 parents 42dbeea + 5209cf0 commit d26c20a

File tree

4 files changed

+153
-8
lines changed

4 files changed

+153
-8
lines changed

src/main/java/com/googlecode/jsonrpc4j/JsonRpcMethod.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@
1818
*/
1919
String value();
2020

21+
JsonRpcParamsPassMode paramsPassMode() default JsonRpcParamsPassMode.AUTO;
22+
2123
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.googlecode.jsonrpc4j;
2+
3+
/**
4+
* The JSON-RPC specification allows either passing parameters as an Array, for by-position arguments, or as an Object,
5+
* for by-name arguments.
6+
*
7+
*/
8+
public enum JsonRpcParamsPassMode {
9+
AUTO,
10+
ARRAY,
11+
OBJECT
12+
}

src/main/java/com/googlecode/jsonrpc4j/ReflectionUtil.java

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import java.util.ArrayList;
66
import java.util.Collection;
77
import java.util.Collections;
8-
import java.util.HashMap;
98
import java.util.HashSet;
9+
import java.util.LinkedHashMap;
1010
import java.util.List;
1111
import java.util.Map;
1212
import java.util.Set;
@@ -196,13 +196,43 @@ private static List<List<Annotation>> getParameterAnnotations(Method method) {
196196
* @return the parsed arguments
197197
*/
198198
public static Object parseArguments(Method method, Object[] arguments) {
199-
199+
200+
JsonRpcParamsPassMode paramsPassMode = JsonRpcParamsPassMode.AUTO;
201+
JsonRpcMethod jsonRpcMethod = getAnnotation(method, JsonRpcMethod.class);
202+
if (jsonRpcMethod != null)
203+
paramsPassMode = jsonRpcMethod.paramsPassMode();
204+
200205
Map<String, Object> namedParams = getNamedParameters(method, arguments);
201-
202-
if (namedParams.size() > 0) {
203-
return namedParams;
204-
} else {
205-
return arguments != null ? arguments : new Object[]{};
206+
207+
switch (paramsPassMode) {
208+
case ARRAY:
209+
if (namedParams.size() > 0) {
210+
Object[] parsed = new Object[namedParams.size()];
211+
int i = 0;
212+
for (Object value : namedParams.values()) {
213+
parsed[i++] = value;
214+
}
215+
return parsed;
216+
} else {
217+
return arguments != null ? arguments : new Object[] {};
218+
}
219+
case OBJECT:
220+
if (namedParams.size() > 0) {
221+
return namedParams;
222+
} else {
223+
if (arguments == null)
224+
return new Object[] {};
225+
throw new RuntimeException(
226+
"OBJECT parameters pass mode is impossible without declaring JsonRpcParam annotations for all parameters on method "
227+
+ method.getName());
228+
}
229+
case AUTO:
230+
default:
231+
if (namedParams.size() > 0) {
232+
return namedParams;
233+
} else {
234+
return arguments != null ? arguments : new Object[] {};
235+
}
206236
}
207237
}
208238

@@ -216,7 +246,7 @@ public static Object parseArguments(Method method, Object[] arguments) {
216246
*/
217247
private static Map<String, Object> getNamedParameters(Method method, Object[] arguments) {
218248

219-
Map<String, Object> namedParams = new HashMap<>();
249+
Map<String, Object> namedParams = new LinkedHashMap<>();
220250

221251
Annotation[][] paramAnnotations = method.getParameterAnnotations();
222252
for (int i = 0; i < paramAnnotations.length; i++) {

src/test/java/com/googlecode/jsonrpc4j/ReflectionUtilTest.java

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,80 @@ public void allNamedParams() throws Exception {
4343
assertEquals(2, namedParams.get("two"));
4444
}
4545

46+
@Test
47+
public void noNamedParamsPassParamsAuto() throws Exception {
48+
49+
Object[] arguments = {"1", 2};
50+
assertSame(arguments, ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("noNamedParamsPassParamsAuto", String.class, int.class), arguments));
51+
}
52+
53+
@Test(expected = RuntimeException.class)
54+
public void someNamedParamsPassParamsAuto() throws Exception {
55+
56+
ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("someNamedParamsPassParamsAuto", String.class, int.class), null);
57+
}
58+
59+
@Test
60+
public void allNamedParamsPassParamsAuto() throws Exception {
61+
62+
Object[] arguments = {"1", 2};
63+
@SuppressWarnings("unchecked")
64+
Map<String, Object> namedParams = (Map<String, Object>) ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("allNamedParamsPassParamsAuto", String.class, int.class), arguments);
65+
66+
assertEquals(2, namedParams.size());
67+
assertEquals("1", namedParams.get("one"));
68+
assertEquals(2, namedParams.get("two"));
69+
}
70+
71+
@Test
72+
public void noNamedParamsPassParamsArray() throws Exception {
73+
74+
Object[] arguments = {"1", 2};
75+
assertSame(arguments, ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("noNamedParamsPassParamsArray", String.class, int.class), arguments));
76+
}
77+
78+
@Test(expected = RuntimeException.class)
79+
public void someNamedParamsPassParamsArray() throws Exception {
80+
81+
ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("someNamedParamsPassParamsArray", String.class, int.class), null);
82+
}
83+
84+
@Test
85+
public void allNamedParamsPassParamsArray() throws Exception {
86+
87+
Object[] arguments = {"1", 2};
88+
Object[] params = (Object[]) ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("allNamedParamsPassParamsArray", String.class, int.class), arguments);
89+
90+
assertEquals(2, params.length);
91+
assertEquals("1", params[0]);
92+
assertEquals(2, params[1]);
93+
}
94+
95+
@Test(expected = RuntimeException.class)
96+
public void noNamedParamsPassParamsObject() throws Exception {
97+
98+
Object[] arguments = {"1", 2};
99+
ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("noNamedParamsPassParamsObject", String.class, int.class), arguments);
100+
}
101+
102+
@Test(expected = RuntimeException.class)
103+
public void someNamedParamsPassParamsObject() throws Exception {
104+
105+
ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("someNamedParamsPassParamsObject", String.class, int.class), null);
106+
}
107+
108+
@Test
109+
public void allNamedParamsPassParamsObject() throws Exception {
110+
111+
Object[] arguments = {"1", 2};
112+
@SuppressWarnings("unchecked")
113+
Map<String, Object> namedParams = (Map<String, Object>) ReflectionUtil.parseArguments(JsonRpcTestService.class.getMethod("allNamedParamsPassParamsAuto", String.class, int.class), arguments);
114+
115+
assertEquals(2, namedParams.size());
116+
assertEquals("1", namedParams.get("one"));
117+
assertEquals(2, namedParams.get("two"));
118+
}
119+
46120
private interface JsonRpcTestService {
47121

48122
void noParams();
@@ -52,5 +126,32 @@ private interface JsonRpcTestService {
52126
void someNamedParams(@JsonRpcParam("one") String one, int two);
53127

54128
void allNamedParams(@JsonRpcParam("one") String one, @JsonRpcParam("two") int two);
129+
130+
@JsonRpcMethod(value = "noNamedParamsPassParamsAuto", paramsPassMode = JsonRpcParamsPassMode.AUTO)
131+
void noNamedParamsPassParamsAuto(String one, int two);
132+
133+
@JsonRpcMethod(value = "someNamedParamsPassParamsAuto", paramsPassMode = JsonRpcParamsPassMode.AUTO)
134+
void someNamedParamsPassParamsAuto(@JsonRpcParam("one") String one, int two);
135+
136+
@JsonRpcMethod(value = "allNamedParamsPassParamsAuto", paramsPassMode = JsonRpcParamsPassMode.AUTO)
137+
void allNamedParamsPassParamsAuto(@JsonRpcParam("one") String one, @JsonRpcParam("two") int two);
138+
139+
@JsonRpcMethod(value = "noNamedParamsPassParamsArray", paramsPassMode = JsonRpcParamsPassMode.ARRAY)
140+
void noNamedParamsPassParamsArray(String one, int two);
141+
142+
@JsonRpcMethod(value = "someNamedParamsPassParamsArray", paramsPassMode = JsonRpcParamsPassMode.ARRAY)
143+
void someNamedParamsPassParamsArray(@JsonRpcParam("one") String one, int two);
144+
145+
@JsonRpcMethod(value = "allNamedParamsPassParamsArray", paramsPassMode = JsonRpcParamsPassMode.ARRAY)
146+
void allNamedParamsPassParamsArray(@JsonRpcParam("one") String one, @JsonRpcParam("two") int two);
147+
148+
@JsonRpcMethod(value = "noNamedParamsPassParamsObject", paramsPassMode = JsonRpcParamsPassMode.OBJECT)
149+
void noNamedParamsPassParamsObject(String one, int two);
150+
151+
@JsonRpcMethod(value = "someNamedParamsPassParamsObject", paramsPassMode = JsonRpcParamsPassMode.OBJECT)
152+
void someNamedParamsPassParamsObject(@JsonRpcParam("one") String one, int two);
153+
154+
@JsonRpcMethod(value = "allNamedParamsPassParamsObject", paramsPassMode = JsonRpcParamsPassMode.OBJECT)
155+
void allNamedParamsPassParamsObject(@JsonRpcParam("one") String one, @JsonRpcParam("two") int two);
55156
}
56157
}

0 commit comments

Comments
 (0)