Package java.nio.channels.spi

Source Code of java.nio.channels.spi.SelectorProvider

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package java.nio.channels.spi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.channels.Channel;
import java.nio.channels.DatagramChannel;
import java.nio.channels.Pipe;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Enumeration;

import org.apache.harmony.luni.platform.Platform;
import org.apache.harmony.nio.internal.SelectorProviderImpl;

/**
* Provider for nio selector and selectable channel.
* <p>
* The provider can be got by system property or the configuration file in a jar
* file, if not, the system default provider will return. The main function of
* this class is to return the instance of implementation class of
* <code>DatagramChannel</code>, <code>Pipe</code>, <code>Selector</code> ,
* <code>ServerSocketChannel</code>, and <code>SocketChannel</code>. All
* the methods of this class are multi-thread safe.
* </p>
*
*/
public abstract class SelectorProvider extends Object {

    private static final String SYMBOL_COMMENT = "#"; //$NON-NLS-1$

    private static final String PROVIDER_IN_SYSTEM_PROPERTY = "java.nio.channels.spi.SelectorProvider"; //$NON-NLS-1$

    private static final String PROVIDER_IN_JAR_RESOURCE = "META-INF/services/java.nio.channels.spi.SelectorProvider"; //$NON-NLS-1$

    private static SelectorProvider provider = null;
   
    private static Channel inheritedChannel;

    /**
     * Constructor for this class.
     *
     * @throws SecurityException
     *             If there is a security manager, and it denies
     *             RuntimePermission("selectorProvider").
     */
    protected SelectorProvider() {
        super();
        if (null != System.getSecurityManager()) {
            System.getSecurityManager().checkPermission(
                    new RuntimePermission("selectorProvider")); //$NON-NLS-1$
        }
    }

    /**
     * Get the provider by following steps in the first calling.
     * <p>
     * <ul>
     * <li> If the system property "java.nio.channels.spi.SelectorProvider" is
     * set, the value of this property is the class name of the return provider.
     * </li>
     * <li>If there is a provider-configuration file named
     * "java.nio.channels.spi.SelectorProvider" in META-INF/services of some jar
     * file valid in the system class loader, the first class name is the return
     * provider's class name. </li>
     * <li> Otherwise, a system default provider will be returned. </li>
     * </ul>
     * </p>
     *
     * @return The provider.
     */
    synchronized public static SelectorProvider provider() {
        if (null == provider) {
            provider = loadProviderByProperty();
            if (null == provider) {
                provider = loadProviderByJar();
            }
            if (null == provider) {
                provider = AccessController
                        .doPrivileged(new PrivilegedAction<SelectorProvider>() {
                            public SelectorProvider run() {
                                return new SelectorProviderImpl();
                            }
                        });
            }
        }
        return provider;
    }

    /*
     * load the provider in the jar file of class path.
     */
    static SelectorProvider loadProviderByJar() {
        Enumeration<URL> enumeration = null;

        ClassLoader classLoader = AccessController.doPrivileged(
                new PrivilegedAction<ClassLoader>() {
                    public ClassLoader run() {
                        return ClassLoader.getSystemClassLoader();
                    }
                });
        try {
            enumeration = classLoader.getResources(PROVIDER_IN_JAR_RESOURCE);
        } catch (IOException e) {
            throw new Error(e);
        }
        if (null == enumeration) {
            return null;
        }
        // for every jar, read until we find the provider name.
        while (enumeration.hasMoreElements()) {
            BufferedReader br = null;
            String className = null;
            try {
                br = new BufferedReader(new InputStreamReader(
                        (enumeration.nextElement()).openStream()));
            } catch (Exception e) {
                continue;
            }
            try {
                // only the first class is loaded ,as spec says, not the same as
                // we do before.
                while ((className = br.readLine()) != null) {
                    className = className.trim();
                    int siteComment = className.indexOf(SYMBOL_COMMENT);
                    className = (-1 == siteComment) ? className : className
                            .substring(0, siteComment);
                    if (0 < className.length()) {
                        return (SelectorProvider) classLoader.loadClass(
                                className).newInstance();                 
                    }
                }
            } catch (Exception e) {
                throw new Error(e);
            }
        }
        return null;
    }

    /*
     * load by system property.
     */
    static SelectorProvider loadProviderByProperty() {
        return AccessController.doPrivileged(
                new PrivilegedAction<SelectorProvider>() {
                    public SelectorProvider run() {
                        try {
                            final String className =
                                System.getProperty(PROVIDER_IN_SYSTEM_PROPERTY);
                            if (null != className) {
                                Class<?> spClass = ClassLoader
                                        .getSystemClassLoader().loadClass(
                                                className);
                                return (SelectorProvider)spClass.newInstance();
                            }
                            return null;
                        } catch (Exception e) {
                            throw new Error(e);
                        }
                    }
                });
    }

    /**
     * Create a new open <code>DatagramChannel</code>.
     *
     * @return The channel.
     * @throws IOException
     *             If some I/O exception occurred.
     */
    public abstract DatagramChannel openDatagramChannel() throws IOException;

    /**
     * Create a new <code>Pipe</code>.
     *
     * @return The pipe.
     * @throws IOException
     *             If some I/O exception occurred.
     */
    public abstract Pipe openPipe() throws IOException;

    /**
     * Create a new selector.
     *
     * @return The selector.
     * @throws IOException
     *             If some I/O exception occurred.
     */
    public abstract AbstractSelector openSelector() throws IOException;

    /**
     * Create a new open <code>ServerSocketChannel</code>.
     *
     * @return The channel.
     * @throws IOException
     *             If some I/O exception occurred.
     */
    public abstract ServerSocketChannel openServerSocketChannel()
            throws IOException;

    /**
     * Create a new open <code>SocketChannel</code>.
     *
     * @return The channel.
     * @throws IOException
     *             If some I/O exception occurred.
     */
    public abstract SocketChannel openSocketChannel() throws IOException;

    /**
     * Answer the channel inherited from the instance which created this JVM.
     *
     * @return The channel.
     * @throws IOException
     *             If some I/O exception occurred.
     * @throws SecurityException
     *             If there is a security manager, and it denies
     *             RuntimePermission("selectorProvider").
     */
    public Channel inheritedChannel() throws IOException {
        if (null == inheritedChannel) {
            inheritedChannel = Platform.getNetworkSystem().inheritedChannel();
        }
        return inheritedChannel;
    }
}
TOP

Related Classes of java.nio.channels.spi.SelectorProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.