1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.jsr356.annotations;
20
21 import java.lang.annotation.Annotation;
22 import java.lang.reflect.Method;
23 import java.util.Map;
24
25 import javax.websocket.DecodeException;
26 import javax.websocket.Decoder;
27
28 import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
29 import org.eclipse.jetty.websocket.common.events.annotated.CallableMethod;
30 import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException;
31 import org.eclipse.jetty.websocket.common.util.ReflectUtils;
32 import org.eclipse.jetty.websocket.jsr356.JsrSession;
33 import org.eclipse.jetty.websocket.jsr356.annotations.Param.Role;
34
35 public abstract class JsrCallable extends CallableMethod
36 {
37 protected final Param[] params;
38 protected final Object[] args;
39 protected int idxSession = -1;
40 protected int idxConfig = -1;
41
42 public JsrCallable(Class<?> pojo, Method method)
43 {
44 super(pojo,method);
45
46 Class<?> ptypes[] = method.getParameterTypes();
47 Annotation pannos[][] = method.getParameterAnnotations();
48 int len = ptypes.length;
49 params = new Param[len];
50 for (int i = 0; i < len; i++)
51 {
52 params[i] = new Param(i,ptypes[i],pannos[i]);
53 }
54
55 args = new Object[len];
56 }
57
58
59
60
61
62 public JsrCallable(JsrCallable copy)
63 {
64 this(copy.getPojo(),copy.getMethod());
65 this.idxSession = copy.idxSession;
66 this.idxConfig = copy.idxConfig;
67 System.arraycopy(copy.params,0,this.params,0,params.length);
68 System.arraycopy(copy.args,0,this.args,0,args.length);
69 }
70
71 protected void assertRoleRequired(int index, String description)
72 {
73 if (index < 0)
74 {
75 StringBuilder err = new StringBuilder();
76 err.append("Unable to find parameter with role [");
77 err.append(description).append("] in method: ");
78 err.append(ReflectUtils.toString(pojo,method));
79 throw new InvalidSignatureException(err.toString());
80 }
81 }
82
83
84
85
86
87
88
89
90 protected int findIndexForRole(Role role)
91 {
92 Param param = findParamForRole(role);
93 if (param != null)
94 {
95 return param.index;
96 }
97 return -1;
98 }
99
100
101
102
103
104
105
106
107 protected Param findParamForRole(Role role)
108 {
109 for (Param param : params)
110 {
111 if (param.role == role)
112 {
113 return param;
114 }
115 }
116 return null;
117 }
118
119 public Param[] getParams()
120 {
121 return params;
122 }
123
124 public void init(JsrSession session)
125 {
126
127
128 idxSession = findIndexForRole(Param.Role.SESSION);
129 if (idxSession >= 0)
130 {
131 args[idxSession] = session;
132 }
133
134
135 idxConfig = findIndexForRole(Param.Role.ENDPOINT_CONFIG);
136 if (idxConfig >= 0)
137 {
138 args[idxConfig] = session.getEndpointConfig();
139 }
140
141
142
143 Map<String, String> pathParams = session.getPathParameters();
144 if ((pathParams != null) && (pathParams.size() > 0))
145 {
146 for (Param param : params)
147 {
148 if (param.role == Role.PATH_PARAM)
149 {
150 int idx = param.index;
151 String rawvalue = pathParams.get(param.getPathParamName());
152
153 Decoder decoder = session.getDecoderFactory().getDecoderFor(param.type);
154 if (decoder instanceof Decoder.Text<?>)
155 {
156 Decoder.Text<?> textDecoder = (Decoder.Text<?>)decoder;
157 try
158 {
159 args[idx] = textDecoder.decode(rawvalue);
160 }
161 catch (DecodeException e)
162 {
163 session.notifyError(e);
164 }
165 }
166 else
167 {
168 throw new InvalidWebSocketException("PathParam decoders must use Decoder.Text");
169 }
170 }
171 }
172 }
173 }
174
175 public abstract void setDecoderClass(Class<? extends Decoder> decoderClass);
176 }