1789N/A/*
2362N/A * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
1789N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1789N/A *
1789N/A * This code is free software; you can redistribute it and/or modify it
1789N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
1789N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
1789N/A *
1789N/A * This code is distributed in the hope that it will be useful, but WITHOUT
1789N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1789N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1789N/A * version 2 for more details (a copy is included in the LICENSE file that
1789N/A * accompanied this code).
1789N/A *
1789N/A * You should have received a copy of the GNU General Public License version
1789N/A * 2 along with this work; if not, write to the Free Software Foundation,
1789N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1789N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
1789N/A */
1789N/Apackage sun.net.ftp;
1789N/A
1789N/Aimport java.security.AccessController;
1789N/Aimport java.security.PrivilegedAction;
1789N/Aimport java.util.ServiceConfigurationError;
1789N/A//import sun.misc.Service;
1789N/A
1789N/A/**
1789N/A * Service provider class for FtpClient.
1789N/A * Sub-classes of FtpClientProvider provide an implementation of {@link FtpClient}
1789N/A * and associated classes. Applications do not normally use this class directly.
1789N/A * See {@link #provider() } for how providers are found and loaded.
1789N/A *
1789N/A * @since 1.7
1789N/A */
1789N/Apublic abstract class FtpClientProvider {
1789N/A
1789N/A /**
1789N/A * Creates a FtpClient from this provider.
1789N/A *
1789N/A * @return The created {@link FtpClient}.
1789N/A */
1789N/A public abstract FtpClient createFtpClient();
1789N/A private static final Object lock = new Object();
1789N/A private static FtpClientProvider provider = null;
1789N/A
1789N/A /**
1789N/A * Initializes a new instance of this class.
1789N/A *
1789N/A * @throws SecurityException if a security manager is installed and it denies
1789N/A * {@link RuntimePermission}<tt>("ftpClientProvider")</tt>
1789N/A */
1789N/A protected FtpClientProvider() {
1789N/A SecurityManager sm = System.getSecurityManager();
1789N/A if (sm != null) {
1789N/A sm.checkPermission(new RuntimePermission("ftpClientProvider"));
1789N/A }
1789N/A }
1789N/A
1789N/A private static boolean loadProviderFromProperty() {
1789N/A String cm = System.getProperty("sun.net.ftpClientProvider");
1789N/A if (cm == null) {
1789N/A return false;
1789N/A }
1789N/A try {
1789N/A Class c = Class.forName(cm, true, null);
1789N/A provider = (FtpClientProvider) c.newInstance();
1789N/A return true;
1789N/A } catch (ClassNotFoundException x) {
1789N/A throw new ServiceConfigurationError(x.toString());
1789N/A } catch (IllegalAccessException x) {
1789N/A throw new ServiceConfigurationError(x.toString());
1789N/A } catch (InstantiationException x) {
1789N/A throw new ServiceConfigurationError(x.toString());
1789N/A } catch (SecurityException x) {
1789N/A throw new ServiceConfigurationError(x.toString());
1789N/A }
1789N/A }
1789N/A
1789N/A private static boolean loadProviderAsService() {
1789N/A // Iterator i = Service.providers(FtpClientProvider.class,
1789N/A // ClassLoader.getSystemClassLoader());
1789N/A // while (i.hasNext()) {
1789N/A // try {
1789N/A // provider = (FtpClientProvider) i.next();
1789N/A // return true;
1789N/A // } catch (ServiceConfigurationError sce) {
1789N/A // if (sce.getCause() instanceof SecurityException) {
1789N/A // // Ignore, try next provider, if any
1789N/A // continue;
1789N/A // }
1789N/A // throw sce;
1789N/A // }
1789N/A // }
1789N/A return false;
1789N/A }
1789N/A
1789N/A /**
1789N/A * Returns the system wide default FtpClientProvider for this invocation of
1789N/A * the Java virtual machine.
1789N/A *
1789N/A * <p> The first invocation of this method locates the default provider
1789N/A * object as follows: </p>
1789N/A *
1789N/A * <ol>
1789N/A *
1789N/A * <li><p> If the system property
1789N/A * <tt>java.net.FtpClientProvider</tt> is defined then it is
1789N/A * taken to be the fully-qualified name of a concrete provider class.
1789N/A * The class is loaded and instantiated; if this process fails then an
1789N/A * unspecified unchecked error or exception is thrown. </p></li>
1789N/A *
1789N/A * <li><p> If a provider class has been installed in a jar file that is
1789N/A * visible to the system class loader, and that jar file contains a
1789N/A * provider-configuration file named
1789N/A * <tt>java.net.FtpClientProvider</tt> in the resource
1789N/A * directory <tt>META-INF/services</tt>, then the first class name
1789N/A * specified in that file is taken. The class is loaded and
1789N/A * instantiated; if this process fails then an unspecified unchecked error or exception is
1789N/A * thrown. </p></li>
1789N/A *
1789N/A * <li><p> Finally, if no provider has been specified by any of the above
1789N/A * means then the system-default provider class is instantiated and the
1789N/A * result is returned. </p></li>
1789N/A *
1789N/A * </ol>
1789N/A *
1789N/A * <p> Subsequent invocations of this method return the provider that was
1789N/A * returned by the first invocation. </p>
1789N/A *
1789N/A * @return The system-wide default FtpClientProvider
1789N/A */
1789N/A public static FtpClientProvider provider() {
1789N/A synchronized (lock) {
1789N/A if (provider != null) {
1789N/A return provider;
1789N/A }
1789N/A return (FtpClientProvider) AccessController.doPrivileged(
1789N/A new PrivilegedAction<Object>() {
1789N/A
1789N/A public Object run() {
1789N/A if (loadProviderFromProperty()) {
1789N/A return provider;
1789N/A }
1789N/A if (loadProviderAsService()) {
1789N/A return provider;
1789N/A }
1789N/A provider = new sun.net.ftp.impl.DefaultFtpClientProvider();
1789N/A return provider;
1789N/A }
1789N/A });
1789N/A }
1789N/A }
1789N/A}