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