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