/* * Copyright 2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.ws.transport.tcp; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import org.springframework.scheduling.SchedulingAwareRunnable; import org.springframework.ws.transport.WebServiceConnection; import org.springframework.ws.transport.support.AbstractAsyncStandaloneMessageReceiver; /** @author Arjen Poutsma */ public class TcpMessageReceiver extends AbstractAsyncStandaloneMessageReceiver { public static final int DEFAULT_PORT = 8081; private ServerSocket serverSocket; private InetAddress bindAddress; private int backlog = -1; private int port = DEFAULT_PORT; /** Sets the port the server will bind to. */ public void setPort(int port) { this.port = port; } /** Sets the server back log. */ public void setBacklog(int backlog) { this.backlog = backlog; } /** * Sets the local internet address the server will bind to. By default, it will accept connections on any/all local * addresses. * * @throws UnknownHostException when the given address is not known * @see ServerSocket#ServerSocket(int,int,java.net.InetAddress) */ public void setBindAddress(String bindAddress) throws UnknownHostException { this.bindAddress = InetAddress.getByName(bindAddress); } protected void onActivate() throws IOException { openServerSocket(); } protected void onStart() { if (logger.isInfoEnabled()) { logger.info("Starting tcp receiver [" + serverSocket.getLocalSocketAddress() + "]"); } execute(new SocketAcceptingRunnable()); } protected void onStop() { if (logger.isInfoEnabled()) { logger.info("Stopping tcp receiver [" + serverSocket.getLocalSocketAddress() + "]"); } } protected void onShutdown() { if (logger.isInfoEnabled()) { logger.info("Shutting down tcp receiver [" + serverSocket.getLocalSocketAddress() + "]"); } closeServerSocket(); } /** Establish a <code>ServerSocket</code> for this receiver. */ protected void openServerSocket() throws IOException { closeServerSocket(); serverSocket = new ServerSocket(port, backlog, bindAddress); } protected void closeServerSocket() { if (serverSocket == null) { return; } try { serverSocket.close(); } catch (IOException ex) { logger.debug("Could not close ServerSocket", ex); } } private class SocketAcceptingRunnable implements SchedulingAwareRunnable { public void run() { while (isRunning()) { try { Socket socket = serverSocket.accept(); TcpRequestHandler handler = new TcpRequestHandler(socket); execute(handler); } catch (InterruptedIOException ex) { logger.warn(ex); } catch (IOException ex) { logger.warn("Could not accept incoming connection: " + ex.getMessage()); } } } public boolean isLongLived() { return true; } } private class TcpRequestHandler implements SchedulingAwareRunnable { private final Socket socket; public TcpRequestHandler(Socket socket) { this.socket = socket; } public void run() { WebServiceConnection connection = new TcpReceiverConnection(socket); try { handleConnection(connection); } catch (Exception ex) { logger.warn("Could not handle request", ex); } } public boolean isLongLived() { return false; } } }