View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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 }