Closed GoogleCodeExporter closed 8 years ago
Here is a patch to add support for the WebParam annotation. This patch also
slightly alters the code for handling legacy JsonRpcParamName annotations by
using an anonymous JsonRpcParam class rather than a Proxy instance. I feel it
is cleaner while providing higher performance (less overhead).
NOTE: the line offsets in this patch are based on the changes in the patch
included in Issue#38.
Index: src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java
===================================================================
--- src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java (revision 238634)
+++ src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java (working copy)
@@ -4,7 +4,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.lang.reflect.InvocationHandler;
+import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -20,6 +20,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.jws.WebParam;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.servlet.http.HttpServletRequest;
@@ -681,17 +687,35 @@
for (List<JsonRpcParamName> annots : depMethodAnnotations) {
if (annots.size()>0) {
final JsonRpcParamName annotation = annots.get(0);
- annotations.add((JsonRpcParam)Proxy.newProxyInstance(
- getClass().getClassLoader(), new Class[] {JsonRpcParam.class},
- new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- if (method.getName().equals("value")) {
- return annotation.value();
- }
- throw new Exception("Unknown method: "+method.getName());
- }
- }));
+ annotations.add(new JsonRpcParam() {
+ public Class<? extends Annotation> annotationType() {
+ return JsonRpcParam.class;
+ }
+ public String value() {
+ return annotation.value();
+ }
+ });
+ } else {
+ annots.add(null);
+ }
+ }
+ }
+
+ List<List<WebParam>> jaxwsAnnotations = ReflectionUtil
+ .getParameterAnnotations(method, WebParam.class);
+ if (!jaxwsAnnotations.isEmpty())
+ {
+ for (List<WebParam> annots : jaxwsAnnotations) {
+ if (annots.size()>0) {
+ final WebParam annotation = annots.get(0);
+ annotations.add(new JsonRpcParam() {
+ public Class<? extends Annotation> annotationType() {
+ return JsonRpcParam.class;
+ }
+ public String value() {
+ return annotation.name();
+ }
+ });
} else {
annots.add(null);
}
Original comment by brett.wo...@gmail.com
on 26 Sep 2012 at 3:39
thanks, i plan on resolving this any many other issues in the next day or two.
Original comment by brian.di...@gmail.com
on 3 Oct 2012 at 11:22
I'm not sure that I'm ready to break support for jdk 1.5 just yet. Can you
think of any compelling reasons that we should? Also, if you could implement
this in a way that wouldn't cause problems in jdk1.5 then there wouldn't be any
issues.
Original comment by brian.di...@gmail.com
on 5 Oct 2012 at 11:53
Original comment by brian.di...@gmail.com
on 6 Oct 2012 at 12:11
Here's a new patch that uses reflection rather than a hard dependency on
javax.jws.WebParam. It should compile and run under jdk 1.5.
I noticed you use Eclipse, you can just highlight this patch and copy it to the
clipboard. Then select your top-level project and paste (Ctrl-V or whatever),
Eclipse will prompt you to apply the patch. If you have Quick Diff enabled
under Preferences->General->Editors->Text Editors, and check the 'Show
differences in overview ruler' box and change the drop-down for the reference
source to 'SVN Working Copy Base', you'll get little highlight markers in the
editor showing each changed line. Hovering over the marker shows the original
line of code. Very handy for reviewing patches like this.
NOTE: the line offsets in this patch are based on the changes in the patch
included in Issue#38 .
Index: src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java
===================================================================
--- src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java (revision 238659)
+++ src/main/java/com/googlecode/jsonrpc4j/JsonRpcServer.java (working copy)
@@ -1,10 +1,14 @@
package com.googlecode.jsonrpc4j;
+import static com.googlecode.jsonrpc4j.ReflectionUtil.findMethods;
+import static com.googlecode.jsonrpc4j.ReflectionUtil.getParameterAnnotations;
+import static com.googlecode.jsonrpc4j.ReflectionUtil.getParameterTypes;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.lang.reflect.InvocationHandler;
+import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -48,6 +52,9 @@
public static final ErrorResolver DEFAULT_ERRROR_RESOLVER
= new MultipleErrorResolver(AnnotationsErrorResolver.INSTANCE, DefaultErrorResolver.INSTANCE);
+ private static Class<?> WEBPARAM_ANNOTATION_CLASS;
+ private static Method WEBPARAM_NAME_METHOD;
+
private boolean backwardsComaptible = true;
private boolean rethrowExceptions = false;
private boolean allowExtraParams = false;
@@ -57,6 +64,16 @@
private Object handler;
private Class<?> remoteInterface;
+ static {
+ ClassLoader classLoader = JsonRpcServer.class.getClassLoader();
+ try {
+ WEBPARAM_ANNOTATION_CLASS = classLoader.loadClass("javax.jws.WebParam");
+ WEBPARAM_NAME_METHOD = WEBPARAM_ANNOTATION_CLASS.getMethod("name");
+ } catch (Exception e) {
+ // Must be Java 1.5
+ }
+ }
+
/**
* Creates the server with the given {@link ObjectMapper} delegating
* all calls to the given {@code handler} {@link Object} but only
@@ -331,7 +348,7 @@
// find methods
Set<Method> methods = new HashSet<Method>();
- methods.addAll(ReflectionUtil.findMethods(getHandlerInterfaces(),
methodName));
+ methods.addAll(findMethods(getHandlerInterfaces(), methodName));
if (methods.isEmpty()) {
writeAndFlushValue(ops, createErrorResponse(
jsonRpc, id, -32601, "Method not found", null));
@@ -613,7 +630,7 @@
// matching parameter types
int mostMatches = -1;
for (Method method : matchedMethods) {
- List<Class<?>> parameterTypes = ReflectionUtil.getParameterTypes(method);
+ List<Class<?>> parameterTypes = getParameterTypes(method);
int numMatches = 0;
for (int i=0; i<parameterTypes.size() && i<numParams; i++) {
if (isMatchingType(paramNodes.get(i), parameterTypes.get(i))) {
@@ -668,7 +685,7 @@
for (Method method : methods) {
// get parameter types
- List<Class<?>> parameterTypes = ReflectionUtil.getParameterTypes(method);
+ List<Class<?>> parameterTypes = getParameterTypes(method);
// bail early if possible
if (!allowExtraParams && paramNames.size()>parameterTypes.size()) {
@@ -681,39 +698,54 @@
List<JsonRpcParam> annotations = new ArrayList<JsonRpcParam>();
// try the deprecated parameter first
- List<List<JsonRpcParamName>> depMethodAnnotations = ReflectionUtil
- .getParameterAnnotations(method, JsonRpcParamName.class);
- if (!depMethodAnnotations.isEmpty()) {
- for (List<JsonRpcParamName> annots : depMethodAnnotations) {
- if (annots.size()>0) {
- final JsonRpcParamName annotation = annots.get(0);
- annotations.add((JsonRpcParam)Proxy.newProxyInstance(
- getClass().getClassLoader(), new Class[] {JsonRpcParam.class},
- new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- if (method.getName().equals("value")) {
- return annotation.value();
- }
- throw new Exception("Unknown method: "+method.getName());
- }
- }));
- } else {
- annots.add(null);
- }
+ List<List<JsonRpcParamName>> depMethodAnnotations =
getParameterAnnotations(method, JsonRpcParamName.class);
+ for (List<JsonRpcParamName> annots : depMethodAnnotations) {
+ if (annots.size()>0) {
+ final JsonRpcParamName annotation = annots.get(0);
+ annotations.add(new JsonRpcParam() {
+ public Class<? extends Annotation> annotationType() {
+ return JsonRpcParam.class;
+ }
+ public String value() {
+ return annotation.value();
+ }
+ });
+ } else {
+ annots.add(null);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ List<List<Annotation>> jaxwsAnnotations = WEBPARAM_ANNOTATION_CLASS != null
+ ? getParameterAnnotations(method, (Class<Annotation>)
WEBPARAM_ANNOTATION_CLASS)
+ : new ArrayList<List<Annotation>>();
+ for (List<Annotation> annots : jaxwsAnnotations) {
+ if (annots.size()>0) {
+ final Annotation annotation = annots.get(0);
+ annotations.add(new JsonRpcParam() {
+ public Class<? extends Annotation> annotationType() {
+ return JsonRpcParam.class;
+ }
+ public String value() {
+ try {
+ return (String) WEBPARAM_NAME_METHOD.invoke(annotation);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ } else {
+ annots.add(null);
}
}
// now try the non-deprecated parameters
- List<List<JsonRpcParam>> methodAnnotations = ReflectionUtil
- .getParameterAnnotations(method, JsonRpcParam.class);
- if (!methodAnnotations.isEmpty()) {
- for (List<JsonRpcParam> annots : methodAnnotations) {
- if (annots.size()>0) {
- annotations.add(annots.get(0));
- } else {
- annots.add(null);
- }
+ List<List<JsonRpcParam>> methodAnnotations =
getParameterAnnotations(method, JsonRpcParam.class);
+ for (List<JsonRpcParam> annots : methodAnnotations) {
+ if (annots.size()>0) {
+ annotations.add(annots.get(0));
+ } else {
+ annots.add(null);
}
}
Original comment by brett.wo...@gmail.com
on 23 Oct 2012 at 3:24
Thanks, will be included in next release.
Original comment by brian.di...@gmail.com
on 28 Nov 2012 at 8:02
Original issue reported on code.google.com by
brett.wo...@gmail.com
on 26 Sep 2012 at 12:29