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 public JsrCallable(JsrCallable copy)
62 {
63 this(copy.getPojo(),copy.getMethod());
64 this.idxSession = copy.idxSession;
65 this.idxConfig = copy.idxConfig;
66 System.arraycopy(copy.params,0,this.params,0,params.length);
67 System.arraycopy(copy.args,0,this.args,0,args.length);
68 }
69
70 protected void assertRoleRequired(int index, String description)
71 {
72 if (index < 0)
73 {
74 StringBuilder err = new StringBuilder();
75 err.append("Unable to find parameter with role [");
76 err.append(description).append("] in method: ");
77 err.append(ReflectUtils.toString(pojo,method));
78 throw new InvalidSignatureException(err.toString());
79 }
80 }
81
82
83
84
85
86
87
88
89 protected int findIndexForRole(Role role)
90 {
91 Param param = findParamForRole(role);
92 if (param != null)
93 {
94 return param.index;
95 }
96 return -1;
97 }
98
99
100
101
102
103
104
105
106 protected Param findParamForRole(Role role)
107 {
108 for (Param param : params)
109 {
110 if (param.role == role)
111 {
112 return param;
113 }
114 }
115 return null;
116 }
117
118 public Param[] getParams()
119 {
120 return params;
121 }
122
123 public void init(JsrSession session)
124 {
125
126
127 idxSession = findIndexForRole(Param.Role.SESSION);
128 if (idxSession >= 0)
129 {
130 args[idxSession] = session;
131 }
132
133
134 idxConfig = findIndexForRole(Param.Role.ENDPOINT_CONFIG);
135 if (idxConfig >= 0)
136 {
137 args[idxConfig] = session.getEndpointConfig();
138 }
139
140
141
142 Map<String, String> pathParams = session.getPathParameters();
143 if ((pathParams != null) && (pathParams.size() > 0))
144 {
145 for (Param param : params)
146 {
147 if (param.role == Role.PATH_PARAM)
148 {
149 int idx = param.index;
150 String rawvalue = pathParams.get(param.getPathParamName());
151
152 Decoder decoder = session.getDecoderFactory().getDecoderFor(param.type);
153 if (decoder instanceof Decoder.Text<?>)
154 {
155 Decoder.Text<?> textDecoder = (Decoder.Text<?>)decoder;
156 try
157 {
158 args[idx] = textDecoder.decode(rawvalue);
159 }
160 catch (DecodeException e)
161 {
162 session.notifyError(e);
163 }
164 }
165 else
166 {
167 throw new InvalidWebSocketException("PathParam decoders must use Decoder.Text");
168 }
169 }
170 }
171 }
172 }
173
174 public abstract void setDecoderClass(Class<? extends Decoder> decoderClass);
175 }