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