1 /*
  2  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package java.nio.channels.spi;
 27 
 28 import java.io.IOException;
 29 import java.lang.reflect.InvocationTargetException;
 30 import java.net.ProtocolFamily;
 31 import java.nio.channels.Channel;
 32 import java.nio.channels.DatagramChannel;
 33 import java.nio.channels.Pipe;
 34 import java.nio.channels.ServerSocketChannel;
 35 import java.nio.channels.SocketChannel;
 36 import java.security.AccessController;
 37 import java.security.PrivilegedAction;
 38 import java.util.Iterator;
 39 import java.util.Objects;
 40 import java.util.ServiceLoader;
 41 import java.util.ServiceConfigurationError;
 42 
 43 /**
 44  * Service-provider class for selectors and selectable channels.
 45  *
 46  * <p> A selector provider is a concrete subclass of this class that has a
 47  * zero-argument constructor and implements the abstract methods specified
 48  * below.  A given invocation of the Java virtual machine maintains a single
 49  * system-wide default provider instance, which is returned by the {@link
 50  * #provider() provider} method.  The first invocation of that method will locate
 51  * the default provider as specified below.
 52  *
 53  * <p> The system-wide default provider is used by the static {@code open}
 54  * methods of the {@link java.nio.channels.DatagramChannel#open
 55  * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link
 56  * java.nio.channels.Selector#open Selector}, {@link
 57  * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link
 58  * java.nio.channels.SocketChannel#open SocketChannel} classes.  It is also
 59  * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()}
 60  * method. A program may make use of a provider other than the default provider
 61  * by instantiating that provider and then directly invoking the {@code open}
 62  * methods defined in this class.
 63  *
 64  * <p> All of the methods in this class are safe for use by multiple concurrent
 65  * threads.  </p>
 66  *
 67  *
 68  * @author Mark Reinhold
 69  * @author JSR-51 Expert Group
 70  * @since 1.4
 71  */
 72 
 73 public abstract class SelectorProvider {
 74 
 75     private static Void checkPermission() {
 76         SecurityManager sm = System.getSecurityManager();
 77         if (sm != null)
 78             sm.checkPermission(new RuntimePermission("selectorProvider"));
 79         return null;
 80     }
 81     private SelectorProvider(Void ignore) { }
 82 
 83     /**
 84      * Initializes a new instance of this class.
 85      *
 86      * @throws  SecurityException
 87      *          If a security manager has been installed and it denies
 88      *          {@link RuntimePermission}{@code ("selectorProvider")}
 89      */
 90     protected SelectorProvider() {
 91         this(checkPermission());
 92     }
 93 
 94     private static class Holder {
 95         static final SelectorProvider INSTANCE = provider();
 96 
 97         static SelectorProvider provider() {
 98             PrivilegedAction<SelectorProvider> pa = () -> {
 99                 SelectorProvider sp;
100                 if ((sp = loadProviderFromProperty()) != null)
101                     return sp;
102                 if ((sp = loadProviderAsService()) != null)
103                     return sp;
104                 return sun.nio.ch.DefaultSelectorProvider.get();
105             };
106             return AccessController.doPrivileged(pa);
107         }
108 
109         private static SelectorProvider loadProviderFromProperty() {
110             String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
111             if (cn == null)
112                 return null;
113             try {
114                 Class<?> clazz = Class.forName(cn, true, ClassLoader.getSystemClassLoader());
115                 return (SelectorProvider) clazz.getConstructor().newInstance();
116             } catch (ClassNotFoundException |
117                     NoSuchMethodException |
118                     IllegalAccessException |
119                     InvocationTargetException |
120                     InstantiationException |
121                     SecurityException x) {
122                 throw new ServiceConfigurationError(null, x);
123             }
124         }
125 
126         private static SelectorProvider loadProviderAsService() {
127             ServiceLoader<SelectorProvider> sl =
128                 ServiceLoader.load(SelectorProvider.class,
129                                    ClassLoader.getSystemClassLoader());
130             Iterator<SelectorProvider> i = sl.iterator();
131             for (;;) {
132                 try {
133                     return i.hasNext() ? i.next() : null;
134                 } catch (ServiceConfigurationError sce) {
135                     if (sce.getCause() instanceof SecurityException) {
136                         // Ignore the security exception, try the next provider
137                         continue;
138                     }
139                     throw sce;
140                 }
141             }
142         }
143     }
144 
145     /**
146      * Returns the system-wide default selector provider for this invocation of
147      * the Java virtual machine.
148      *
149      * <p> The first invocation of this method locates the default provider
150      * object as follows: </p>
151      *
152      * <ol>
153      *
154      *   <li><p> If the system property
155      *   {@systemProperty java.nio.channels.spi.SelectorProvider} is defined
156      *   then it is taken to be the fully-qualified name of a concrete provider
157      *   class. The class is loaded and instantiated; if this process fails then
158      *   an unspecified error is thrown.  </p></li>
159      *
160      *   <li><p> If a provider class has been installed in a jar file that is
161      *   visible to the system class loader, and that jar file contains a
162      *   provider-configuration file named
163      *   {@code java.nio.channels.spi.SelectorProvider} in the resource
164      *   directory {@code META-INF/services}, then the first class name
165      *   specified in that file is taken.  The class is loaded and
166      *   instantiated; if this process fails then an unspecified error is
167      *   thrown.  </p></li>
168      *
169      *   <li><p> Finally, if no provider has been specified by any of the above
170      *   means then the system-default provider class is instantiated and the
171      *   result is returned.  </p></li>
172      *
173      * </ol>
174      *
175      * <p> Subsequent invocations of this method return the provider that was
176      * returned by the first invocation.  </p>
177      *
178      * @return  The system-wide default selector provider
179      */
180     public static SelectorProvider provider() {
181         return Holder.INSTANCE;
182     }
183 
184     /**
185      * Opens a datagram channel.
186      *
187      * @return  The new channel
188      *
189      * @throws  IOException
190      *          If an I/O error occurs
191      */
192     public abstract DatagramChannel openDatagramChannel()
193         throws IOException;
194 
195     /**
196      * Opens a datagram channel.
197      *
198      * @param   family
199      *          The protocol family
200      *
201      * @return  A new datagram channel
202      *
203      * @throws  UnsupportedOperationException
204      *          If the specified protocol family is not supported
205      * @throws  IOException
206      *          If an I/O error occurs
207      *
208      * @since 1.7
209      */
210     public abstract DatagramChannel openDatagramChannel(ProtocolFamily family)
211         throws IOException;
212 
213     /**
214      * Opens a pipe.
215      *
216      * @return  The new pipe
217      *
218      * @throws  IOException
219      *          If an I/O error occurs
220      */
221     public abstract Pipe openPipe()
222         throws IOException;
223 
224     /**
225      * Opens a selector.
226      *
227      * @return  The new selector
228      *
229      * @throws  IOException
230      *          If an I/O error occurs
231      */
232     public abstract AbstractSelector openSelector()
233         throws IOException;
234 
235     /**
236      * Opens a server-socket channel.
237      *
238      * @return  The new channel
239      *
240      * @throws  IOException
241      *          If an I/O error occurs
242      */
243     public abstract ServerSocketChannel openServerSocketChannel()
244         throws IOException;
245 
246     /**
247      * Opens a socket channel.
248      *
249      * @return  The new channel
250      *
251      * @throws  IOException
252      *          If an I/O error occurs
253      */
254     public abstract SocketChannel openSocketChannel()
255         throws IOException;
256 
257     /**
258      * Returns the channel inherited from the entity that created this
259      * Java virtual machine.
260      *
261      * <p> On many operating systems a process, such as a Java virtual
262      * machine, can be started in a manner that allows the process to
263      * inherit a channel from the entity that created the process. The
264      * manner in which this is done is system dependent, as are the
265      * possible entities to which the channel may be connected. For example,
266      * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
267      * start programs to service requests when a request arrives on an
268      * associated network port. In this example, the process that is started,
269      * inherits a channel representing a network socket.
270      *
271      * <p> In cases where the inherited channel is for an <i>Internet protocol</i>
272      * socket then the {@link Channel Channel} type returned
273      * by this method is determined as follows:
274      *
275      * <ul>
276      *
277      *  <li><p> If the inherited channel is for a stream-oriented connected
278      *  socket then a {@link SocketChannel SocketChannel} is returned. The
279      *  socket channel is, at least initially, in blocking mode, bound
280      *  to a socket address, and connected to a peer.
281      *  </p></li>
282      *
283      *  <li><p> If the inherited channel is for a stream-oriented listening
284      *  socket then a {@link ServerSocketChannel ServerSocketChannel} is returned.
285      *  The server-socket channel is, at least initially, in blocking mode,
286      *  and bound to a socket address.
287      *  </p></li>
288      *
289      *  <li><p> If the inherited channel is a datagram-oriented socket then a
290      *  {@link DatagramChannel DatagramChannel} is returned. The datagram channel
291      *  is, at least initially, in blocking mode, and bound to a socket address.
292      *  </p></li>
293      *
294      * </ul>
295      *
296      * <p> In cases where the inherited channel is for a <i>Unix domain</i>
297      * socket then the {@link Channel} type returned is the same as for
298      * <i>Internet protocol</i> sockets as described above, except that
299      * datagram-oriented sockets are not supported.
300      *
301      * <p> In addition to the two types of socket just described, this method
302      * may return other types in the future.
303      *
304      * <p> The first invocation of this method creates the channel that is
305      * returned. Subsequent invocations of this method return the same
306      * channel. </p>
307      *
308      * @return  The inherited channel, if any, otherwise {@code null}.
309      *
310      * @throws  IOException
311      *          If an I/O error occurs
312      *
313      * @throws  SecurityException
314      *          If a security manager has been installed and it denies
315      *          {@link RuntimePermission}{@code ("inheritedChannel")}
316      *
317      * @since 1.5
318      */
319     public Channel inheritedChannel() throws IOException {
320         return null;
321     }
322 
323     /**
324      * Opens a socket channel.
325      *
326      * @implSpec The default implementation of this method first checks that
327      * the given protocol {@code family} is not {@code null},
328      * then throws {@link UnsupportedOperationException}.
329      *
330      * @param   family
331      *          The protocol family
332      *
333      * @return  The new channel
334      *
335      * @throws  UnsupportedOperationException
336      *          If the specified protocol family is not supported
337      * @throws  IOException
338      *          If an I/O error occurs
339      *
340      * @since 15
341      */
342     public SocketChannel openSocketChannel(ProtocolFamily family) throws IOException {
343         Objects.requireNonNull(family);
344         throw new UnsupportedOperationException("Protocol family not supported");
345     }
346 
347     /**
348      * Opens a server-socket channel.
349      *
350      * @implSpec The default implementation of this method first checks that
351      * the given protocol {@code family} is not {@code null},
352      * then throws {@link UnsupportedOperationException}.
353      *
354      * @param   family
355      *          The protocol family
356      *
357      * @return  The new channel
358      *
359      * @throws  UnsupportedOperationException
360      *          If the specified protocol family is not supported
361      * @throws  IOException
362      *          If an I/O error occurs
363      *
364      * @since 15
365      */
366     public ServerSocketChannel openServerSocketChannel(ProtocolFamily family) throws IOException {
367         Objects.requireNonNull(family);
368         throw new UnsupportedOperationException("Protocol family not supported");
369     }
370 }