1. /*
  2. * @(#)SelectorProvider.java 1.20 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.nio.channels.spi;
  8. import java.io.FileDescriptor;
  9. import java.io.IOException;
  10. import java.net.ServerSocket;
  11. import java.net.Socket;
  12. import java.nio.channels.*;
  13. import java.security.AccessController;
  14. import java.security.PrivilegedAction;
  15. import java.util.Iterator;
  16. import sun.misc.Service;
  17. import sun.misc.ServiceConfigurationError;
  18. import sun.security.action.GetPropertyAction;
  19. /**
  20. * Service-provider class for selectors and selectable channels.
  21. *
  22. * <p> A selector provider is a concrete subclass of this class that has a
  23. * zero-argument constructor and implements the abstract methods specified
  24. * below. A given invocation of the Java virtual machine maintains a single
  25. * system-wide default provider instance, which is returned by the {@link
  26. * #provider provider} method. The first invocation of that method will locate
  27. * the default provider as specified below.
  28. *
  29. * <p> The system-wide default provider is used by the static <tt>open</tt>
  30. * methods of the {@link java.nio.channels.DatagramChannel#open
  31. * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link
  32. * java.nio.channels.Selector#open Selector}, {@link
  33. * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link
  34. * java.nio.channels.SocketChannel#open SocketChannel} classes. A program may
  35. * make use of a provider other than the default provider by instantiating that
  36. * provider and then directly invoking the <tt>open</tt> methods defined in
  37. * this class.
  38. *
  39. * <p> All of the methods in this class are safe for use by multiple concurrent
  40. * threads. </p>
  41. *
  42. *
  43. * @author Mark Reinhold
  44. * @author JSR-51 Expert Group
  45. * @version 1.20, 03/01/23
  46. * @since 1.4
  47. */
  48. public abstract class SelectorProvider {
  49. private static final Object lock = new Object();
  50. private static SelectorProvider provider = null;
  51. /**
  52. * Initializes a new instance of this class. </p>
  53. *
  54. * @throws SecurityException
  55. * If a security manager has been installed and it denies
  56. * {@link RuntimePermission}<tt>("selectorProvider")</tt>
  57. */
  58. protected SelectorProvider() {
  59. SecurityManager sm = System.getSecurityManager();
  60. if (sm != null)
  61. sm.checkPermission(new RuntimePermission("selectorProvider"));
  62. }
  63. private static boolean loadProviderFromProperty() {
  64. String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
  65. if (cn == null)
  66. return false;
  67. try {
  68. Class c = Class.forName(cn, true,
  69. ClassLoader.getSystemClassLoader());
  70. provider = (SelectorProvider)c.newInstance();
  71. return true;
  72. } catch (ClassNotFoundException x) {
  73. throw new ServiceConfigurationError(x);
  74. } catch (IllegalAccessException x) {
  75. throw new ServiceConfigurationError(x);
  76. } catch (InstantiationException x) {
  77. throw new ServiceConfigurationError(x);
  78. } catch (SecurityException x) {
  79. throw new ServiceConfigurationError(x);
  80. }
  81. }
  82. private static boolean loadProviderAsService() {
  83. Iterator i = Service.providers(SelectorProvider.class,
  84. ClassLoader.getSystemClassLoader());
  85. for (;;) {
  86. try {
  87. if (!i.hasNext())
  88. return false;
  89. provider = (SelectorProvider)i.next();
  90. return true;
  91. } catch (ServiceConfigurationError sce) {
  92. if (sce.getCause() instanceof SecurityException) {
  93. // Ignore the security exception, try the next provider
  94. continue;
  95. }
  96. throw sce;
  97. }
  98. }
  99. }
  100. /**
  101. * Returns the system-wide default selector provider for this invocation of
  102. * the Java virtual machine.
  103. *
  104. * <p> The first invocation of this method locates the default provider
  105. * object as follows: </p>
  106. *
  107. * <ol>
  108. *
  109. * <li><p> If the system property
  110. * <tt>java.nio.channels.spi.SelectorProvider</tt> is defined then it is
  111. * taken to be the fully-qualified name of a concrete provider class.
  112. * The class is loaded and instantiated; if this process fails then an
  113. * unspecified error is thrown. </p></li>
  114. *
  115. * <li><p> If a provider class has been installed in a jar file that is
  116. * visible to the system class loader, and that jar file contains a
  117. * provider-configuration file named
  118. * <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource
  119. * directory <tt>META-INF/services</tt>, then the first class name
  120. * specified in that file is taken. The class is loaded and
  121. * instantiated; if this process fails then an unspecified error is
  122. * thrown. </p></li>
  123. *
  124. * <li><p> Finally, if no provider has been specified by any of the above
  125. * means then the system-default provider class is instantiated and the
  126. * result is returned. </p></li>
  127. *
  128. * </ol>
  129. *
  130. * <p> Subsequent invocations of this method return the provider that was
  131. * returned by the first invocation. </p>
  132. *
  133. * @return The system-wide default selector provider
  134. */
  135. public static SelectorProvider provider() {
  136. synchronized (lock) {
  137. if (provider != null)
  138. return provider;
  139. return (SelectorProvider)AccessController
  140. .doPrivileged(new PrivilegedAction() {
  141. public Object run() {
  142. if (loadProviderFromProperty())
  143. return provider;
  144. if (loadProviderAsService())
  145. return provider;
  146. provider = sun.nio.ch.DefaultSelectorProvider.create();
  147. return provider;
  148. }
  149. });
  150. }
  151. }
  152. /**
  153. * Opens a datagram channel. </p>
  154. *
  155. * @return The new channel
  156. */
  157. public abstract DatagramChannel openDatagramChannel()
  158. throws IOException;
  159. /**
  160. * Opens a pipe. </p>
  161. *
  162. * @return The new pipe
  163. */
  164. public abstract Pipe openPipe()
  165. throws IOException;
  166. /**
  167. * Opens a selector. </p>
  168. *
  169. * @return The new selector
  170. */
  171. public abstract AbstractSelector openSelector()
  172. throws IOException;
  173. /**
  174. * Opens a server-socket channel. </p>
  175. *
  176. * @return The new channel
  177. */
  178. public abstract ServerSocketChannel openServerSocketChannel()
  179. throws IOException;
  180. /**
  181. * Opens a socket channel. </p>
  182. *
  183. * @return The new channel
  184. */
  185. public abstract SocketChannel openSocketChannel()
  186. throws IOException;
  187. }