1*1157Smax.romanov@nginx.com /*
2*1157Smax.romanov@nginx.com  * Licensed to the Apache Software Foundation (ASF) under one or more
3*1157Smax.romanov@nginx.com  * contributor license agreements.  See the NOTICE file distributed with
4*1157Smax.romanov@nginx.com  * this work for additional information regarding copyright ownership.
5*1157Smax.romanov@nginx.com  * The ASF licenses this file to You under the Apache License, Version 2.0
6*1157Smax.romanov@nginx.com  * (the "License"); you may not use this file except in compliance with
7*1157Smax.romanov@nginx.com  * the License.  You may obtain a copy of the License at
8*1157Smax.romanov@nginx.com  *
9*1157Smax.romanov@nginx.com  *     http://www.apache.org/licenses/LICENSE-2.0
10*1157Smax.romanov@nginx.com  *
11*1157Smax.romanov@nginx.com  * Unless required by applicable law or agreed to in writing, software
12*1157Smax.romanov@nginx.com  * distributed under the License is distributed on an "AS IS" BASIS,
13*1157Smax.romanov@nginx.com  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*1157Smax.romanov@nginx.com  * See the License for the specific language governing permissions and
15*1157Smax.romanov@nginx.com  * limitations under the License.
16*1157Smax.romanov@nginx.com  */
17*1157Smax.romanov@nginx.com package nginx.unit.websocket.pojo;
18*1157Smax.romanov@nginx.com 
19*1157Smax.romanov@nginx.com import java.io.ByteArrayInputStream;
20*1157Smax.romanov@nginx.com import java.io.IOException;
21*1157Smax.romanov@nginx.com import java.lang.reflect.Method;
22*1157Smax.romanov@nginx.com import java.nio.ByteBuffer;
23*1157Smax.romanov@nginx.com import java.util.ArrayList;
24*1157Smax.romanov@nginx.com import java.util.List;
25*1157Smax.romanov@nginx.com 
26*1157Smax.romanov@nginx.com import javax.websocket.DecodeException;
27*1157Smax.romanov@nginx.com import javax.websocket.Decoder;
28*1157Smax.romanov@nginx.com import javax.websocket.Decoder.Binary;
29*1157Smax.romanov@nginx.com import javax.websocket.Decoder.BinaryStream;
30*1157Smax.romanov@nginx.com import javax.websocket.EndpointConfig;
31*1157Smax.romanov@nginx.com import javax.websocket.Session;
32*1157Smax.romanov@nginx.com 
33*1157Smax.romanov@nginx.com import org.apache.tomcat.util.res.StringManager;
34*1157Smax.romanov@nginx.com 
35*1157Smax.romanov@nginx.com /**
36*1157Smax.romanov@nginx.com  * ByteBuffer specific concrete implementation for handling whole messages.
37*1157Smax.romanov@nginx.com  */
38*1157Smax.romanov@nginx.com public class PojoMessageHandlerWholeBinary
39*1157Smax.romanov@nginx.com         extends PojoMessageHandlerWholeBase<ByteBuffer> {
40*1157Smax.romanov@nginx.com 
41*1157Smax.romanov@nginx.com     private static final StringManager sm =
42*1157Smax.romanov@nginx.com             StringManager.getManager(PojoMessageHandlerWholeBinary.class);
43*1157Smax.romanov@nginx.com 
44*1157Smax.romanov@nginx.com     private final List<Decoder> decoders = new ArrayList<>();
45*1157Smax.romanov@nginx.com 
46*1157Smax.romanov@nginx.com     private final boolean isForInputStream;
47*1157Smax.romanov@nginx.com 
PojoMessageHandlerWholeBinary(Object pojo, Method method, Session session, EndpointConfig config, List<Class<? extends Decoder>> decoderClazzes, Object[] params, int indexPayload, boolean convert, int indexSession, boolean isForInputStream, long maxMessageSize)48*1157Smax.romanov@nginx.com     public PojoMessageHandlerWholeBinary(Object pojo, Method method,
49*1157Smax.romanov@nginx.com             Session session, EndpointConfig config,
50*1157Smax.romanov@nginx.com             List<Class<? extends Decoder>> decoderClazzes, Object[] params,
51*1157Smax.romanov@nginx.com             int indexPayload, boolean convert, int indexSession,
52*1157Smax.romanov@nginx.com             boolean isForInputStream, long maxMessageSize) {
53*1157Smax.romanov@nginx.com         super(pojo, method, session, params, indexPayload, convert,
54*1157Smax.romanov@nginx.com                 indexSession, maxMessageSize);
55*1157Smax.romanov@nginx.com 
56*1157Smax.romanov@nginx.com         // Update binary text size handled by session
57*1157Smax.romanov@nginx.com         if (maxMessageSize > -1 && maxMessageSize > session.getMaxBinaryMessageBufferSize()) {
58*1157Smax.romanov@nginx.com             if (maxMessageSize > Integer.MAX_VALUE) {
59*1157Smax.romanov@nginx.com                 throw new IllegalArgumentException(sm.getString(
60*1157Smax.romanov@nginx.com                         "pojoMessageHandlerWhole.maxBufferSize"));
61*1157Smax.romanov@nginx.com             }
62*1157Smax.romanov@nginx.com             session.setMaxBinaryMessageBufferSize((int) maxMessageSize);
63*1157Smax.romanov@nginx.com         }
64*1157Smax.romanov@nginx.com 
65*1157Smax.romanov@nginx.com         try {
66*1157Smax.romanov@nginx.com             if (decoderClazzes != null) {
67*1157Smax.romanov@nginx.com                 for (Class<? extends Decoder> decoderClazz : decoderClazzes) {
68*1157Smax.romanov@nginx.com                     if (Binary.class.isAssignableFrom(decoderClazz)) {
69*1157Smax.romanov@nginx.com                         Binary<?> decoder = (Binary<?>) decoderClazz.getConstructor().newInstance();
70*1157Smax.romanov@nginx.com                         decoder.init(config);
71*1157Smax.romanov@nginx.com                         decoders.add(decoder);
72*1157Smax.romanov@nginx.com                     } else if (BinaryStream.class.isAssignableFrom(
73*1157Smax.romanov@nginx.com                             decoderClazz)) {
74*1157Smax.romanov@nginx.com                         BinaryStream<?> decoder = (BinaryStream<?>)
75*1157Smax.romanov@nginx.com                                 decoderClazz.getConstructor().newInstance();
76*1157Smax.romanov@nginx.com                         decoder.init(config);
77*1157Smax.romanov@nginx.com                         decoders.add(decoder);
78*1157Smax.romanov@nginx.com                     } else {
79*1157Smax.romanov@nginx.com                         // Text decoder - ignore it
80*1157Smax.romanov@nginx.com                     }
81*1157Smax.romanov@nginx.com                 }
82*1157Smax.romanov@nginx.com             }
83*1157Smax.romanov@nginx.com         } catch (ReflectiveOperationException e) {
84*1157Smax.romanov@nginx.com             throw new IllegalArgumentException(e);
85*1157Smax.romanov@nginx.com         }
86*1157Smax.romanov@nginx.com         this.isForInputStream = isForInputStream;
87*1157Smax.romanov@nginx.com     }
88*1157Smax.romanov@nginx.com 
89*1157Smax.romanov@nginx.com 
90*1157Smax.romanov@nginx.com     @Override
decode(ByteBuffer message)91*1157Smax.romanov@nginx.com     protected Object decode(ByteBuffer message) throws DecodeException {
92*1157Smax.romanov@nginx.com         for (Decoder decoder : decoders) {
93*1157Smax.romanov@nginx.com             if (decoder instanceof Binary) {
94*1157Smax.romanov@nginx.com                 if (((Binary<?>) decoder).willDecode(message)) {
95*1157Smax.romanov@nginx.com                     return ((Binary<?>) decoder).decode(message);
96*1157Smax.romanov@nginx.com                 }
97*1157Smax.romanov@nginx.com             } else {
98*1157Smax.romanov@nginx.com                 byte[] array = new byte[message.limit() - message.position()];
99*1157Smax.romanov@nginx.com                 message.get(array);
100*1157Smax.romanov@nginx.com                 ByteArrayInputStream bais = new ByteArrayInputStream(array);
101*1157Smax.romanov@nginx.com                 try {
102*1157Smax.romanov@nginx.com                     return ((BinaryStream<?>) decoder).decode(bais);
103*1157Smax.romanov@nginx.com                 } catch (IOException ioe) {
104*1157Smax.romanov@nginx.com                     throw new DecodeException(message, sm.getString(
105*1157Smax.romanov@nginx.com                             "pojoMessageHandlerWhole.decodeIoFail"), ioe);
106*1157Smax.romanov@nginx.com                 }
107*1157Smax.romanov@nginx.com             }
108*1157Smax.romanov@nginx.com         }
109*1157Smax.romanov@nginx.com         return null;
110*1157Smax.romanov@nginx.com     }
111*1157Smax.romanov@nginx.com 
112*1157Smax.romanov@nginx.com 
113*1157Smax.romanov@nginx.com     @Override
convert(ByteBuffer message)114*1157Smax.romanov@nginx.com     protected Object convert(ByteBuffer message) {
115*1157Smax.romanov@nginx.com         byte[] array = new byte[message.remaining()];
116*1157Smax.romanov@nginx.com         message.get(array);
117*1157Smax.romanov@nginx.com         if (isForInputStream) {
118*1157Smax.romanov@nginx.com             return new ByteArrayInputStream(array);
119*1157Smax.romanov@nginx.com         } else {
120*1157Smax.romanov@nginx.com             return array;
121*1157Smax.romanov@nginx.com         }
122*1157Smax.romanov@nginx.com     }
123*1157Smax.romanov@nginx.com 
124*1157Smax.romanov@nginx.com 
125*1157Smax.romanov@nginx.com     @Override
onClose()126*1157Smax.romanov@nginx.com     protected void onClose() {
127*1157Smax.romanov@nginx.com         for (Decoder decoder : decoders) {
128*1157Smax.romanov@nginx.com             decoder.destroy();
129*1157Smax.romanov@nginx.com         }
130*1157Smax.romanov@nginx.com     }
131*1157Smax.romanov@nginx.com }
132