1 /*
2  * Copyright (c) 2000, 2013, 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.net.ProtocolFamily;
30 import java.nio.channels.*;
31 import java.security.AccessController;
32 import java.security.PrivilegedAction;
33 import java.util.Iterator;
34 import java.util.ServiceLoader;
35 import java.util.ServiceConfigurationError;
36 import sun.security.action.GetPropertyAction;
37 
38 
39 /**
40  * Service-provider class for selectors and selectable channels.
41  *
42  * <p> A selector provider is a concrete subclass of this class that has a
43  * zero-argument constructor and implements the abstract methods specified
44  * below.  A given invocation of the Java virtual machine maintains a single
45  * system-wide default provider instance, which is returned by the {@link
46  * #provider() provider} method.  The first invocation of that method will locate
47  * the default provider as specified below.
48  *
49  * <p> The system-wide default provider is used by the static {@code open}
50  * methods of the {@link java.nio.channels.DatagramChannel#open
51  * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link
52  * java.nio.channels.Selector#open Selector}, {@link
53  * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link
54  * java.nio.channels.SocketChannel#open SocketChannel} classes.  It is also
55  * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()}
56  * method. A program may make use of a provider other than the default provider
57  * by instantiating that provider and then directly invoking the {@code open}
58  * methods defined in this class.
59  *
60  * <p> All of the methods in this class are safe for use by multiple concurrent
61  * threads.  </p>
62  *
63  *
64  * @author Mark Reinhold
65  * @author JSR-51 Expert Group
66  * @since 1.4
67  */
68 
69 public abstract class SelectorProvider {
70 
71     private static final Object lock = new Object();
72     private static SelectorProvider provider = null;
73 
checkPermission()74     private static Void checkPermission() {
75         SecurityManager sm = System.getSecurityManager();
76         if (sm != null)
77             sm.checkPermission(new RuntimePermission("selectorProvider"));
78         return null;
79     }
SelectorProvider(Void ignore)80     private SelectorProvider(Void ignore) { }
81 
82     /**
83      * Initializes a new instance of this class.
84      *
85      * @throws  SecurityException
86      *          If a security manager has been installed and it denies
87      *          {@link RuntimePermission}{@code ("selectorProvider")}
88      */
SelectorProvider()89     protected SelectorProvider() {
90         this(checkPermission());
91     }
92 
loadProviderFromProperty()93     private static boolean loadProviderFromProperty() {
94         String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
95         if (cn == null)
96             return false;
97         try {
98             @SuppressWarnings("deprecation")
99             Object tmp = Class.forName(cn, true,
100                                        ClassLoader.getSystemClassLoader()).newInstance();
101             provider = (SelectorProvider)tmp;
102             return true;
103         } catch (ClassNotFoundException x) {
104             throw new ServiceConfigurationError(null, x);
105         } catch (IllegalAccessException x) {
106             throw new ServiceConfigurationError(null, x);
107         } catch (InstantiationException x) {
108             throw new ServiceConfigurationError(null, x);
109         } catch (SecurityException x) {
110             throw new ServiceConfigurationError(null, x);
111         }
112     }
113 
loadProviderAsService()114     private static boolean loadProviderAsService() {
115 
116         ServiceLoader<SelectorProvider> sl =
117             ServiceLoader.load(SelectorProvider.class,
118                                ClassLoader.getSystemClassLoader());
119         Iterator<SelectorProvider> i = sl.iterator();
120         for (;;) {
121             try {
122                 if (!i.hasNext())
123                     return false;
124                 provider = i.next();
125                 return true;
126             } catch (ServiceConfigurationError sce) {
127                 if (sce.getCause() instanceof SecurityException) {
128                     // Ignore the security exception, try the next provider
129                     continue;
130                 }
131                 throw sce;
132             }
133         }
134     }
135 
136     /**
137      * Returns the system-wide default selector provider for this invocation of
138      * the Java virtual machine.
139      *
140      * <p> The first invocation of this method locates the default provider
141      * object as follows: </p>
142      *
143      * <ol>
144      *
145      *   <li><p> If the system property
146      *   {@code java.nio.channels.spi.SelectorProvider} is defined then it is
147      *   taken to be the fully-qualified name of a concrete provider class.
148      *   The class is loaded and instantiated; if this process fails then an
149      *   unspecified error is thrown.  </p></li>
150      *
151      *   <li><p> If a provider class has been installed in a jar file that is
152      *   visible to the system class loader, and that jar file contains a
153      *   provider-configuration file named
154      *   {@code java.nio.channels.spi.SelectorProvider} in the resource
155      *   directory {@code META-INF/services}, then the first class name
156      *   specified in that file is taken.  The class is loaded and
157      *   instantiated; if this process fails then an unspecified error is
158      *   thrown.  </p></li>
159      *
160      *   <li><p> Finally, if no provider has been specified by any of the above
161      *   means then the system-default provider class is instantiated and the
162      *   result is returned.  </p></li>
163      *
164      * </ol>
165      *
166      * <p> Subsequent invocations of this method return the provider that was
167      * returned by the first invocation.  </p>
168      *
169      * @return  The system-wide default selector provider
170      */
provider()171     public static SelectorProvider provider() {
172         synchronized (lock) {
173             if (provider != null)
174                 return provider;
175             return AccessController.doPrivileged(
176                 new PrivilegedAction<>() {
177                     public SelectorProvider run() {
178                             if (loadProviderFromProperty())
179                                 return provider;
180                             if (loadProviderAsService())
181                                 return provider;
182                             provider = sun.nio.ch.DefaultSelectorProvider.create();
183                             return provider;
184                         }
185                     });
186         }
187     }
188 
189     /**
190      * Opens a datagram channel.
191      *
192      * @return  The new channel
193      *
194      * @throws  IOException
195      *          If an I/O error occurs
196      */
197     public abstract DatagramChannel openDatagramChannel()
198         throws IOException;
199 
200     /**
201      * Opens a datagram channel.
202      *
203      * @param   family
204      *          The protocol family
205      *
206      * @return  A new datagram channel
207      *
208      * @throws  UnsupportedOperationException
209      *          If the specified protocol family is not supported
210      * @throws  IOException
211      *          If an I/O error occurs
212      *
213      * @since 1.7
214      */
215     public abstract DatagramChannel openDatagramChannel(ProtocolFamily family)
216         throws IOException;
217 
218     /**
219      * Opens a pipe.
220      *
221      * @return  The new pipe
222      *
223      * @throws  IOException
224      *          If an I/O error occurs
225      */
226     public abstract Pipe openPipe()
227         throws IOException;
228 
229     /**
230      * Opens a selector.
231      *
232      * @return  The new selector
233      *
234      * @throws  IOException
235      *          If an I/O error occurs
236      */
237     public abstract AbstractSelector openSelector()
238         throws IOException;
239 
240     /**
241      * Opens a server-socket channel.
242      *
243      * @return  The new channel
244      *
245      * @throws  IOException
246      *          If an I/O error occurs
247      */
248     public abstract ServerSocketChannel openServerSocketChannel()
249         throws IOException;
250 
251     /**
252      * Opens a socket channel.
253      *
254      * @return  The new channel
255      *
256      * @throws  IOException
257      *          If an I/O error occurs
258      */
259     public abstract SocketChannel openSocketChannel()
260         throws IOException;
261 
262     /**
263      * Returns the channel inherited from the entity that created this
264      * Java virtual machine.
265      *
266      * <p> On many operating systems a process, such as a Java virtual
267      * machine, can be started in a manner that allows the process to
268      * inherit a channel from the entity that created the process. The
269      * manner in which this is done is system dependent, as are the
270      * possible entities to which the channel may be connected. For example,
271      * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
272      * start programs to service requests when a request arrives on an
273      * associated network port. In this example, the process that is started,
274      * inherits a channel representing a network socket.
275      *
276      * <p> In cases where the inherited channel represents a network socket
277      * then the {@link java.nio.channels.Channel Channel} type returned
278      * by this method is determined as follows:
279      *
280      * <ul>
281      *
282      *  <li><p> If the inherited channel represents a stream-oriented connected
283      *  socket then a {@link java.nio.channels.SocketChannel SocketChannel} is
284      *  returned. The socket channel is, at least initially, in blocking
285      *  mode, bound to a socket address, and connected to a peer.
286      *  </p></li>
287      *
288      *  <li><p> If the inherited channel represents a stream-oriented listening
289      *  socket then a {@link java.nio.channels.ServerSocketChannel
290      *  ServerSocketChannel} is returned. The server-socket channel is, at
291      *  least initially, in blocking mode, and bound to a socket address.
292      *  </p></li>
293      *
294      *  <li><p> If the inherited channel is a datagram-oriented socket
295      *  then a {@link java.nio.channels.DatagramChannel DatagramChannel} is
296      *  returned. The datagram channel is, at least initially, in blocking
297      *  mode, and bound to a socket address.
298      *  </p></li>
299      *
300      * </ul>
301      *
302      * <p> In addition to the network-oriented channels described, this method
303      * may return other kinds of channels in the future.
304      *
305      * <p> The first invocation of this method creates the channel that is
306      * returned. Subsequent invocations of this method return the same
307      * channel. </p>
308      *
309      * @return  The inherited channel, if any, otherwise {@code null}.
310      *
311      * @throws  IOException
312      *          If an I/O error occurs
313      *
314      * @throws  SecurityException
315      *          If a security manager has been installed and it denies
316      *          {@link RuntimePermission}{@code ("inheritedChannel")}
317      *
318      * @since 1.5
319      */
320    public Channel inheritedChannel() throws IOException {
321         return null;
322    }
323 
324 }
325