001    /**
002     * Copyright (C) 2009-2013 Barchart, Inc. <http://www.barchart.com/>
003     *
004     * All rights reserved. Licensed under the OSI BSD License.
005     *
006     * http://www.opensource.org/licenses/bsd-license.php
007     */
008    package com.barchart.udt.nio;
009    
010    import java.io.IOException;
011    import java.nio.channels.ServerSocketChannel;
012    
013    import org.slf4j.Logger;
014    import org.slf4j.LoggerFactory;
015    
016    import com.barchart.udt.SocketUDT;
017    import com.barchart.udt.TypeUDT;
018    import com.barchart.udt.anno.ThreadSafe;
019    
020    /**
021     * {@link ServerSocketChannel}-like wrapper for {@link SocketUDT} can be either
022     * stream or message oriented, depending on {@link TypeUDT}
023     * <p>
024     * you must use {@link SelectorProviderUDT#openServerSocketChannel()} to obtain
025     * instance of this class; do not use JDK
026     * {@link java.nio.channels.ServerSocketChannel#open()};
027     * <p>
028     * example:
029     * 
030     * <pre>
031     * SelectorProvider provider = SelectorProviderUDT.DATAGRAM;
032     * ServerSocketChannel acceptChannel = provider.openServerSocketChannel();
033     * ServerSocket acceptSocket = acceptChannel.socket();
034     * InetSocketAddress acceptAddress = new InetSocketAddress(&quot;localhost&quot;, 12345);
035     * acceptorSocket.bind(acceptAddress);
036     * assert acceptSocket.isBound();
037     * SocketChannel connectChannel = acceptChannel.accept();
038     * assert connectChannel.isConnected();
039     * </pre>
040     */
041    public class ServerSocketChannelUDT extends ServerSocketChannel implements
042                    ChannelUDT {
043    
044            protected static final Logger log = LoggerFactory
045                            .getLogger(ServerSocketChannelUDT.class);
046    
047            @ThreadSafe("this")
048            protected NioServerSocketUDT socketAdapter;
049    
050            protected final SocketUDT socketUDT;
051    
052            protected ServerSocketChannelUDT( //
053                            final SelectorProviderUDT provider, //
054                            final SocketUDT socketUDT //
055            ) {
056    
057                    super(provider);
058                    this.socketUDT = socketUDT;
059    
060            }
061    
062            @Override
063            public SocketChannelUDT accept() throws IOException {
064                    try {
065    
066                            begin();
067    
068                            final SocketUDT clientUDT = socketUDT.accept();
069    
070                            if (clientUDT == null) {
071    
072                                    return null;
073    
074                            } else {
075    
076                                    return new SocketChannelUDT( //
077                                                    providerUDT(), //
078                                                    clientUDT, //
079                                                    clientUDT.isConnected() //
080                                    );
081    
082                            }
083                    } finally {
084                            end(true);
085                    }
086            }
087    
088            @Override
089            protected void implCloseSelectableChannel() throws IOException {
090                    socketUDT.close();
091            }
092    
093            @Override
094            protected void implConfigureBlocking(final boolean block)
095                            throws IOException {
096                    socketUDT.setBlocking(block);
097            }
098    
099            @Override
100            public boolean isConnectFinished() {
101                    return true;
102            }
103    
104            @Override
105            public KindUDT kindUDT() {
106                    return KindUDT.ACCEPTOR;
107            }
108    
109            @Override
110            public SelectorProviderUDT providerUDT() {
111                    return (SelectorProviderUDT) super.provider();
112            }
113    
114            @Override
115            public synchronized NioServerSocketUDT socket() {
116                    if (socketAdapter == null) {
117                            try {
118                                    socketAdapter = new NioServerSocketUDT(this);
119                            } catch (final Exception e) {
120                                    log.error("failed to make socket", e);
121                                    return null;
122                            }
123                    }
124                    return socketAdapter;
125            }
126    
127            @Override
128            public SocketUDT socketUDT() {
129                    return socketUDT;
130            }
131    
132            @Override
133            public String toString() {
134                    return socketUDT.toString();
135            }
136    
137            @Override
138            public TypeUDT typeUDT() {
139                    return providerUDT().type();
140            }
141    
142    }