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.netty; 018 019 import java.net.SocketAddress; 020 021 import org.apache.camel.CamelExchangeException; 022 import org.apache.camel.Exchange; 023 import org.apache.camel.NoTypeConversionAvailableException; 024 import org.apache.commons.logging.Log; 025 import org.apache.commons.logging.LogFactory; 026 import org.jboss.netty.channel.Channel; 027 import org.jboss.netty.channel.ChannelFuture; 028 029 /** 030 * Helper class used internally by camel-netty using Netty. 031 * 032 * @version $Revision: 960792 $ 033 */ 034 public final class NettyHelper { 035 036 private static final transient Log LOG = LogFactory.getLog(NettyHelper.class); 037 038 private NettyHelper() { 039 // Utility class 040 } 041 042 /** 043 * Gets the string body to be used when sending with the textline codec. 044 * 045 * @param body the current body 046 * @param exchange the exchange 047 * @param delimiter the textline delimiter 048 * @param autoAppendDelimiter whether absent delimiter should be auto appended 049 * @return the string body to send 050 * @throws NoTypeConversionAvailableException is thrown if the current body could not be converted to a String type 051 */ 052 public static String getTextlineBody(Object body, Exchange exchange, TextLineDelimiter delimiter, boolean autoAppendDelimiter) throws NoTypeConversionAvailableException { 053 String s = exchange.getContext().getTypeConverter().mandatoryConvertTo(String.class, exchange, body); 054 055 // auto append delimiter if missing? 056 if (autoAppendDelimiter) { 057 if (TextLineDelimiter.LINE.equals(delimiter)) { 058 // line delimiter so ensure it ends with newline 059 if (!s.endsWith("\n")) { 060 if (LOG.isTraceEnabled()) { 061 LOG.trace("Auto appending missing newline delimiter to body"); 062 } 063 s = s + "\n"; 064 } 065 } else { 066 // null delimiter so ensure it ends with null 067 if (!s.endsWith("\u0000")) { 068 if (LOG.isTraceEnabled()) { 069 LOG.trace("Auto appending missing null delimiter to body"); 070 } 071 s = s + "\u0000"; 072 } 073 } 074 } 075 076 return s; 077 } 078 079 /** 080 * Writes the given body to Netty channel. Will wait until the body has been written. 081 * 082 * @param channel the Netty channel 083 * @param remoteAddress the remote address when using UDP 084 * @param body the body to write (send) 085 * @param exchange the exchange 086 * @throws CamelExchangeException is thrown if the body could not be written for some reasons 087 * (eg remote connection is closed etc.) 088 */ 089 public static void writeBodySync(Channel channel, SocketAddress remoteAddress, Object body, Exchange exchange) throws CamelExchangeException { 090 // the write operation is asynchronous. Use future to wait until the session has been written 091 ChannelFuture future; 092 if (remoteAddress != null) { 093 future = channel.write(body, remoteAddress); 094 } else { 095 future = channel.write(body); 096 } 097 098 // wait for the write 099 if (LOG.isTraceEnabled()) { 100 LOG.trace("Waiting for write to complete"); 101 } 102 future.awaitUninterruptibly(); 103 104 // if it was not a success then thrown an exception 105 if (!future.isSuccess()) { 106 LOG.warn("Cannot write body: " + body + " using channel: " + channel); 107 throw new CamelExchangeException("Cannot write body", exchange, future.getCause()); 108 } 109 } 110 111 /** 112 * Closes the given channel 113 * 114 * @param channel the channel to close 115 */ 116 public static void close(Channel channel) { 117 if (channel != null) { 118 if (LOG.isTraceEnabled()) { 119 LOG.trace("Closing channel: " + channel); 120 } 121 channel.close().awaitUninterruptibly(); 122 } 123 } 124 125 }