1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  package org.newsclub.net.unix;
19  
20  import static java.util.Objects.requireNonNull;
21  
22  import java.io.FileDescriptor;
23  import java.io.IOException;
24  import java.net.ProtocolFamily;
25  import java.net.ServerSocket;
26  import java.net.SocketAddress;
27  import java.net.SocketOption;
28  import java.net.StandardProtocolFamily;
29  import java.nio.channels.ServerSocketChannel;
30  import java.nio.channels.spi.SelectorProvider;
31  import java.util.Objects;
32  import java.util.Set;
33  
34  import org.eclipse.jdt.annotation.NonNull;
35  import org.eclipse.jdt.annotation.Nullable;
36  
37  import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
38  
39  
40  
41  
42  
43  
44  
45  public abstract class AFServerSocketChannel<A extends AFSocketAddress> extends ServerSocketChannel
46      implements FileDescriptorAccess, AFSomeSocketChannel {
47    private final @NonNull AFServerSocket<A> afSocket;
48  
49    
50  
51  
52  
53  
54  
55    @SuppressWarnings("all") 
56    protected AFServerSocketChannel(AFServerSocket<A> socket, AFSelectorProvider<A> sp) {
57      super(sp);
58      this.afSocket = Objects.requireNonNull(socket);
59    }
60  
61    
62  
63    @SuppressWarnings("unchecked")
64    @Override
65    public <T> T getOption(SocketOption<T> name) throws IOException {
66      if (name instanceof AFSocketOption<?>) {
67        return getAFCore().getOption((AFSocketOption<T>) name);
68      }
69      Integer optionId = SocketOptionsMapper.resolve(name);
70      if (optionId == null) {
71        throw new UnsupportedOperationException("unsupported option");
72      } else {
73        return (T) afSocket.getAFImpl().getOption(optionId);
74      }
75    }
76  
77    @Override
78    public <T> AFServerSocketChannel<A> setOption(SocketOption<T> name, T value) throws IOException {
79      if (name instanceof AFSocketOption<?>) {
80        getAFCore().setOption((AFSocketOption<T>) name, value);
81        return this;
82      }
83      Integer optionId = SocketOptionsMapper.resolve(name);
84      if (optionId == null) {
85        throw new UnsupportedOperationException("unsupported option");
86      } else {
87        afSocket.getAFImpl().setOption(optionId, value);
88      }
89      return this;
90    }
91  
92    @Override
93    public final Set<SocketOption<?>> supportedOptions() {
94      return SocketOptionsMapper.SUPPORTED_SOCKET_OPTIONS;
95    }
96  
97    
98  
99    @Override
100   public final AFServerSocketChannel<A> bind(SocketAddress local, int backlog) throws IOException {
101     afSocket.bind(local, backlog);
102     return this;
103   }
104 
105   @SuppressFBWarnings("EI_EXPOSE_REP")
106   @Override
107   public final AFServerSocket<A> socket() {
108     return afSocket;
109   }
110 
111   @Override
112   public AFSocketChannel<A> accept() throws IOException {
113     boolean complete = false;
114     Exception exception = null;
115     try {
116       begin();
117       AFSocket<A> socket = afSocket.accept1(false);
118       complete = true;
119       return socket == null ? null : socket.getChannel();
120     } catch (IOException e) {
121       throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( 
122           (exception = InterruptibleChannelUtil.handleException(this, e)));
123     } finally {
124       InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
125     }
126   }
127 
128   @Override
129   public final @Nullable A getLocalAddress() {
130     return getLocalSocketAddress();
131   }
132 
133   @Override
134   public final @Nullable A getLocalSocketAddress() {
135     return afSocket.getLocalSocketAddress();
136   }
137 
138   
139 
140 
141 
142 
143 
144 
145 
146   public final boolean isLocalSocketAddressValid() {
147     return afSocket.isLocalSocketAddressValid();
148   }
149 
150   @Override
151   protected final void implCloseSelectableChannel() throws IOException {
152     afSocket.close();
153   }
154 
155   @Override
156   protected final void implConfigureBlocking(boolean block) throws IOException {
157     getAFCore().implConfigureBlocking(block);
158   }
159 
160   final AFSocketCore getAFCore() {
161     return afSocket.getAFImpl().getCore();
162   }
163 
164   @Override
165   public final FileDescriptor getFileDescriptor() throws IOException {
166     return afSocket.getFileDescriptor();
167   }
168 
169   
170 
171 
172 
173 
174 
175 
176 
177   public final boolean isDeleteOnClose() {
178     return socket().isDeleteOnClose();
179   }
180 
181   
182 
183 
184 
185 
186 
187 
188 
189 
190   public final void setDeleteOnClose(boolean b) {
191     socket().setDeleteOnClose(b);
192   }
193 
194   @Override
195   public void setShutdownOnClose(boolean enabled) {
196     socket().setShutdownOnClose(enabled);
197   }
198 
199   
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211   public static ServerSocketChannel open(ProtocolFamily family) throws IOException {
212     requireNonNull(family);
213 
214     if (family instanceof AFProtocolFamily) {
215       return ((AFProtocolFamily) family).openServerSocketChannel();
216     } else if ("UNIX".equals(family.name())) {
217       return AFUNIXServerSocketChannel.open();
218     } else if (family instanceof StandardProtocolFamily) {
219       return ServerSocketChannel.open();
220     } else {
221       throw new UnsupportedOperationException("Protocol family not supported");
222     }
223   }
224 }