001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.mina;
018
019 import java.nio.charset.CharacterCodingException;
020 import java.nio.charset.Charset;
021 import java.nio.charset.CharsetEncoder;
022
023 import org.apache.camel.CamelContext;
024 import org.apache.camel.NoTypeConversionAvailableException;
025 import org.apache.mina.common.ByteBuffer;
026 import org.apache.mina.common.IoSession;
027 import org.apache.mina.filter.codec.ProtocolCodecFactory;
028 import org.apache.mina.filter.codec.ProtocolDecoder;
029 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
030 import org.apache.mina.filter.codec.ProtocolEncoder;
031 import org.apache.mina.filter.codec.ProtocolEncoderOutput;
032
033 /**
034 * @version $Revision: 3039 $
035 */
036 public class MinaUdpProtocolCodecFactory implements ProtocolCodecFactory {
037
038 private final Charset charset;
039 private final CamelContext context;
040
041 public MinaUdpProtocolCodecFactory(CamelContext context, Charset charset) {
042 this.context = context;
043 this.charset = charset;
044 }
045
046 public ProtocolEncoder getEncoder() throws Exception {
047 return new ProtocolEncoder() {
048 private CharsetEncoder encoder;
049
050 public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
051 if (encoder == null) {
052 encoder = charset.newEncoder();
053 }
054 ByteBuffer buf = toByteBuffer(message, encoder);
055 buf.flip();
056 out.write(buf);
057 }
058
059 public void dispose(IoSession session) throws Exception {
060 // do nothing
061 }
062 };
063 }
064
065 public ProtocolDecoder getDecoder() throws Exception {
066 return new ProtocolDecoder() {
067 public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception {
068 // convert to bytes to write, we can not pass in the byte buffer as it could be sent to
069 // multiple mina sessions so we must convert it to bytes
070 byte[] bytes = context.getTypeConverter().convertTo(byte[].class, in);
071 out.write(bytes);
072 }
073
074 public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
075 // do nothing
076 }
077
078 public void dispose(IoSession session) throws Exception {
079 // do nothing
080 }
081 };
082 }
083
084 private ByteBuffer toByteBuffer(Object message, CharsetEncoder encoder)
085 throws CharacterCodingException, NoTypeConversionAvailableException {
086 String value = context.getTypeConverter().convertTo(String.class, message);
087 if (value != null) {
088 ByteBuffer answer = ByteBuffer.allocate(value.length()).setAutoExpand(false);
089 answer.putString(value, encoder);
090 return answer;
091 }
092
093 // failback to use a byte buffer converter
094 return context.getTypeConverter().mandatoryConvertTo(ByteBuffer.class, message);
095 }
096
097 }