org.springframework.integration.ip.tcp.connection.AbstractTcpConnection.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.integration.ip.tcp.connection.AbstractTcpConnection.java

Source

/*
 * Copyright 2001-2011 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.integration.ip.tcp.connection;

import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.serializer.Deserializer;
import org.springframework.core.serializer.Serializer;
import org.springframework.integration.Message;
import org.springframework.integration.ip.tcp.serializer.AbstractByteArraySerializer;
import org.springframework.util.Assert;

/**
 * Base class for TcpConnections. TcpConnections are established by
 * client connection factories (outgoing) or server connection factories
 * (incoming).
 *
 * @author Gary Russell
 * @since 2.0
 *
 */
public abstract class AbstractTcpConnection implements TcpConnection {

    protected final Log logger = LogFactory.getLog(this.getClass());

    @SuppressWarnings("rawtypes")
    private volatile Deserializer deserializer;

    @SuppressWarnings("rawtypes")
    private volatile Serializer serializer;

    private volatile TcpMessageMapper mapper;

    private volatile TcpListener listener;

    private volatile TcpListener actualListener;

    private volatile TcpSender sender;

    private volatile boolean singleUse;

    private final boolean server;

    private volatile String connectionId;

    private final AtomicLong sequence = new AtomicLong();

    private volatile int soLinger = -1;

    private volatile String hostName = "unknown";

    private volatile String hostAddress = "unknown";

    public AbstractTcpConnection(Socket socket, boolean server, boolean lookupHost) {
        this.server = server;
        InetAddress inetAddress = socket.getInetAddress();
        if (inetAddress != null) {
            this.hostAddress = inetAddress.getHostAddress();
            if (lookupHost) {
                this.hostName = inetAddress.getHostName();
            } else {
                this.hostName = this.hostAddress;
            }
        }
        int port = socket.getPort();
        this.connectionId = this.hostName + ":" + port + ":" + UUID.randomUUID().toString();
        try {
            this.soLinger = socket.getSoLinger();
        } catch (SocketException e) {
        }
    }

    public void afterSend(Message<?> message) throws Exception {
        if (logger.isDebugEnabled()) {
            logger.debug("Message sent " + message);
        }
        if (this.singleUse) {
            // if (we're a server socket, or a send-only socket), and soLinger <> 0, close
            if ((this.isServer() || this.actualListener == null) && this.soLinger != 0) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Closing single-use connection" + this.getConnectionId());
                }
                this.closeConnection();
            }
        }
    }

    /**
     * Closes this connection.
     */
    public void close() {
        if (this.sender != null) {
            this.sender.removeDeadConnection(this);
        }
    }

    /**
     * If we have been intercepted, propagate the close from the outermost interceptor;
     * otherwise, just call close().
     */
    protected void closeConnection() {
        if (!(this.listener instanceof TcpConnectionInterceptor)) {
            close();
            return;
        }
        TcpConnectionInterceptor outerInterceptor = (TcpConnectionInterceptor) this.listener;
        while (outerInterceptor.getListener() instanceof TcpConnectionInterceptor) {
            outerInterceptor = (TcpConnectionInterceptor) outerInterceptor.getListener();
        }
        outerInterceptor.close();
    }

    /**
     * @return the mapper
     */
    public TcpMessageMapper getMapper() {
        return mapper;
    }

    /**
     * @param mapper the mapper to set
     */
    public void setMapper(TcpMessageMapper mapper) {
        Assert.notNull(mapper, this.getClass().getName() + " Mapper may not be null");
        this.mapper = mapper;
        if (this.serializer != null && !(this.serializer instanceof AbstractByteArraySerializer)) {
            mapper.setStringToBytes(false);
        }
    }

    /**
     *
     * @return the deserializer
     */
    public Deserializer<?> getDeserializer() {
        return this.deserializer;
    }

    /**
     * @param deserializer the deserializer to set
     */
    public void setDeserializer(Deserializer<?> deserializer) {
        this.deserializer = deserializer;
    }

    /**
     *
     * @return the serializer
     */
    public Serializer<?> getSerializer() {
        return this.serializer;
    }

    /**
     * @param serializer the serializer to set
     */
    public void setSerializer(Serializer<?> serializer) {
        this.serializer = serializer;
        if (!(serializer instanceof AbstractByteArraySerializer)) {
            this.mapper.setStringToBytes(false);
        }
    }

    /**
     * @param listener the listener to set
     */
    public void registerListener(TcpListener listener) {
        this.listener = listener;
        // Determine the actual listener for this connection
        if (!(this.listener instanceof TcpConnectionInterceptor)) {
            this.actualListener = this.listener;
        } else {
            TcpConnectionInterceptor outerInterceptor = (TcpConnectionInterceptor) this.listener;
            while (outerInterceptor.getListener() instanceof TcpConnectionInterceptor) {
                outerInterceptor = (TcpConnectionInterceptor) outerInterceptor.getListener();
            }
            this.actualListener = outerInterceptor.getListener();
        }
    }

    /**
     * @param sender the sender to set
     */
    public void registerSender(TcpSender sender) {
        this.sender = sender;
        if (sender != null) {
            sender.addNewConnection(this);
        }
    }

    /**
     * @return the listener
     */
    public TcpListener getListener() {
        return this.listener;
    }

    /**
     * @return the sender
     */
    public TcpSender getSender() {
        return sender;
    }

    /**
     * @param singleUse true if this socket is to used once and
     * discarded.
     */
    public void setSingleUse(boolean singleUse) {
        this.singleUse = singleUse;
    }

    /**
     *
     * @return True if connection is used once.
     */
    public boolean isSingleUse() {
        return this.singleUse;
    }

    public boolean isServer() {
        return server;
    }

    public long incrementAndGetConnectionSequence() {
        return this.sequence.incrementAndGet();
    }

    public String getHostAddress() {
        return this.hostAddress;
    }

    public String getHostName() {
        return this.hostName;
    }

    public String getConnectionId() {
        return this.connectionId;
    }

}