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("localhost", 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 }