1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.common.events.annotated;
20
21 import java.io.InputStream;
22 import java.io.Reader;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25
26 import org.eclipse.jetty.util.log.Log;
27 import org.eclipse.jetty.util.log.Logger;
28 import org.eclipse.jetty.websocket.api.Session;
29 import org.eclipse.jetty.websocket.api.WebSocketException;
30 import org.eclipse.jetty.websocket.api.util.QuoteUtil;
31
32 public class EventMethod
33 {
34 private static final Logger LOG = Log.getLogger(EventMethod.class);
35
36 private static Object[] dropFirstArg(Object[] args)
37 {
38 if (args.length == 1)
39 {
40 return new Object[0];
41 }
42 Object ret[] = new Object[args.length - 1];
43 System.arraycopy(args,1,ret,0,ret.length);
44 return ret;
45 }
46
47 protected Class<?> pojo;
48 protected Method method;
49 private boolean hasSession = false;
50 private boolean isStreaming = false;
51 private Class<?>[] paramTypes;
52
53 public EventMethod(Class<?> pojo, Method method)
54 {
55 this.pojo = pojo;
56 this.paramTypes = method.getParameterTypes();
57 this.method = method;
58 identifyPresentParamTypes();
59 }
60
61 public EventMethod(Class<?> pojo, String methodName, Class<?>... paramTypes)
62 {
63 try
64 {
65 this.pojo = pojo;
66 this.paramTypes = paramTypes;
67 this.method = pojo.getMethod(methodName,paramTypes);
68 identifyPresentParamTypes();
69 }
70 catch (NoSuchMethodException | SecurityException e)
71 {
72 LOG.warn("Cannot use method {}({}): {}",methodName,paramTypes,e.getMessage());
73 this.method = null;
74 }
75 }
76
77 public void call(Object obj, Object... args)
78 {
79 if ((this.pojo == null) || (this.method == null))
80 {
81 LOG.warn("Cannot execute call: pojo={}, method={}",pojo,method);
82 return;
83 }
84 if (obj == null)
85 {
86 LOG.warn("Cannot call {} on null object",this.method);
87 return;
88 }
89 if (args.length > paramTypes.length)
90 {
91 Object trimArgs[] = dropFirstArg(args);
92 call(obj,trimArgs);
93 return;
94 }
95 if (args.length < paramTypes.length)
96 {
97 throw new IllegalArgumentException("Call arguments length [" + args.length + "] must always be greater than or equal to captured args length ["
98 + paramTypes.length + "]");
99 }
100
101 try
102 {
103 this.method.invoke(obj,args);
104 }
105 catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
106 {
107 String err = String.format("Cannot call method %s on %s with args: %s",method,pojo, QuoteUtil.join(args,","));
108 throw new WebSocketException(err,e);
109 }
110 }
111
112 public Method getMethod()
113 {
114 return method;
115 }
116
117 protected Class<?>[] getParamTypes()
118 {
119 return this.paramTypes;
120 }
121
122 private void identifyPresentParamTypes()
123 {
124 this.hasSession = false;
125 this.isStreaming = false;
126
127 if (paramTypes == null)
128 {
129 return;
130 }
131
132 for (Class<?> paramType : paramTypes)
133 {
134 if (Session.class.isAssignableFrom(paramType))
135 {
136 this.hasSession = true;
137 }
138 if (Reader.class.isAssignableFrom(paramType) || InputStream.class.isAssignableFrom(paramType))
139 {
140 this.isStreaming = true;
141 }
142 }
143 }
144
145 public boolean isHasSession()
146 {
147 return hasSession;
148 }
149
150 public boolean isStreaming()
151 {
152 return isStreaming;
153 }
154 }