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.reflect.Method;
22
23 import javax.websocket.Decoder;
24 import javax.websocket.Encoder;
25
26 import org.eclipse.jetty.websocket.common.events.annotated.InvalidSignatureException;
27 import org.eclipse.jetty.websocket.common.util.ReflectUtils;
28 import org.eclipse.jetty.websocket.jsr356.EncoderFactory;
29 import org.eclipse.jetty.websocket.jsr356.JsrSession;
30 import org.eclipse.jetty.websocket.jsr356.annotations.Param.Role;
31
32 public class OnMessageCallable extends JsrCallable
33 {
34 protected final Class<?> returnType;
35 protected Encoder returnEncoder;
36 protected Class<?> decodingType;
37 protected Decoder decoder;
38 protected int idxPartialMessageFlag = -1;
39 protected int idxMessageObject = -1;
40 protected boolean messageRoleAssigned = false;
41
42 public OnMessageCallable(Class<?> pojo, Method method)
43 {
44 super(pojo,method);
45 this.returnType = method.getReturnType();
46 }
47
48 public OnMessageCallable(OnMessageCallable copy)
49 {
50 super(copy);
51 this.returnType = copy.returnType;
52 this.decodingType = copy.decodingType;
53 this.decoder = copy.decoder;
54 this.idxPartialMessageFlag = copy.idxPartialMessageFlag;
55 this.idxMessageObject = copy.idxMessageObject;
56 }
57
58 protected void assertDecoderRequired()
59 {
60 if (getDecoder() == null)
61 {
62 StringBuilder err = new StringBuilder();
63 err.append("Unable to find a valid ");
64 err.append(Decoder.class.getName());
65 err.append(" for parameter #");
66 Param param = params[idxMessageObject];
67 err.append(param.index);
68 err.append(" [").append(param.type).append("] in method: ");
69 err.append(ReflectUtils.toString(pojo,method));
70 throw new InvalidSignatureException(err.toString());
71 }
72 }
73
74 private int findMessageObjectIndex()
75 {
76 int index = -1;
77
78 for (Param.Role role : Param.Role.getMessageRoles())
79 {
80 index = findIndexForRole(role);
81 if (index >= 0)
82 {
83 return index;
84 }
85 }
86
87 return -1;
88 }
89
90 public Decoder getDecoder()
91 {
92 return decoder;
93 }
94
95 public Param getMessageObjectParam()
96 {
97 if (idxMessageObject < 0)
98 {
99 idxMessageObject = findMessageObjectIndex();
100
101 if (idxMessageObject < 0)
102 {
103 StringBuilder err = new StringBuilder();
104 err.append("A message type must be specified [TEXT, BINARY, DECODER, or PONG] : ");
105 err.append(ReflectUtils.toString(pojo,method));
106 throw new InvalidSignatureException(err.toString());
107 }
108 }
109
110 return super.params[idxMessageObject];
111 }
112
113 public Encoder getReturnEncoder()
114 {
115 return returnEncoder;
116 }
117
118 public Class<?> getReturnType()
119 {
120 return returnType;
121 }
122
123 @Override
124 public void init(JsrSession session)
125 {
126 super.init(session);
127 idxPartialMessageFlag = findIndexForRole(Role.MESSAGE_PARTIAL_FLAG);
128
129 EncoderFactory.Wrapper encoderWrapper = session.getEncoderFactory().getWrapperFor(returnType);
130 if (encoderWrapper != null)
131 {
132 this.returnEncoder = encoderWrapper.getEncoder();
133 }
134
135 if (decodingType != null)
136 {
137 this.decoder = session.getDecoderFactory().getDecoderFor(decodingType);
138 }
139 }
140
141 public boolean isMessageRoleAssigned()
142 {
143 return messageRoleAssigned;
144 }
145
146 public boolean isPartialMessageSupported()
147 {
148 return (idxPartialMessageFlag >= 0);
149 }
150
151 @Override
152 public void setDecodingType(Class<?> decodingType)
153 {
154 this.decodingType = decodingType;
155 messageRoleAssigned = true;
156 }
157
158 public void setPartialMessageFlag(Param param)
159 {
160 idxPartialMessageFlag = param.index;
161 }
162 }