1 /* 2 * Copyright (c) 2009, 2011, 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 package sun.net.ftp; 26 27 import java.security.AccessController; 28 import java.security.PrivilegedAction; 29 import java.util.ServiceConfigurationError; 30 //import java.util.ServiceLoader; 31 32 /** 33 * Service provider class for FtpClient. 34 * Sub-classes of FtpClientProvider provide an implementation of {@link FtpClient} 35 * and associated classes. Applications do not normally use this class directly. 36 * See {@link #provider() } for how providers are found and loaded. 37 * 38 * @since 1.7 39 */ 40 public abstract class FtpClientProvider { 41 42 /** 43 * Creates a FtpClient from this provider. 44 * 45 * @return The created {@link FtpClient}. 46 */ createFtpClient()47 public abstract FtpClient createFtpClient(); 48 private static final Object lock = new Object(); 49 private static FtpClientProvider provider = null; 50 51 /** 52 * Initializes a new instance of this class. 53 * 54 * @throws SecurityException if a security manager is installed and it denies 55 * {@link RuntimePermission}<tt>("ftpClientProvider")</tt> 56 */ FtpClientProvider()57 protected FtpClientProvider() { 58 SecurityManager sm = System.getSecurityManager(); 59 if (sm != null) { 60 sm.checkPermission(new RuntimePermission("ftpClientProvider")); 61 } 62 } 63 loadProviderFromProperty()64 private static boolean loadProviderFromProperty() { 65 String cm = System.getProperty("sun.net.ftpClientProvider"); 66 if (cm == null) { 67 return false; 68 } 69 try { 70 Class<?> c = Class.forName(cm, true, null); 71 provider = (FtpClientProvider) c.newInstance(); 72 return true; 73 } catch (ClassNotFoundException | 74 IllegalAccessException | 75 InstantiationException | 76 SecurityException x) { 77 throw new ServiceConfigurationError(x.toString()); 78 } 79 } 80 loadProviderAsService()81 private static boolean loadProviderAsService() { 82 // Iterator<FtpClientProvider> i = 83 // ServiceLoader.load(FtpClientProvider.class, 84 // ClassLoader.getSystemClassLoader()).iterator(); 85 // 86 // while (i.hasNext()) { 87 // try { 88 // provider = i.next(); 89 // return true; 90 // } catch (ServiceConfigurationError sce) { 91 // if (sce.getCause() instanceof SecurityException) { 92 // // Ignore, try next provider, if any 93 // continue; 94 // } 95 // throw sce; 96 // } 97 // } 98 return false; 99 } 100 101 /** 102 * Returns the system wide default FtpClientProvider for this invocation of 103 * the Java virtual machine. 104 * 105 * <p> The first invocation of this method locates the default provider 106 * object as follows: </p> 107 * 108 * <ol> 109 * 110 * <li><p> If the system property 111 * <tt>java.net.FtpClientProvider</tt> is defined then it is 112 * taken to be the fully-qualified name of a concrete provider class. 113 * The class is loaded and instantiated; if this process fails then an 114 * unspecified unchecked error or exception is thrown. </p></li> 115 * 116 * <li><p> If a provider class has been installed in a jar file that is 117 * visible to the system class loader, and that jar file contains a 118 * provider-configuration file named 119 * <tt>java.net.FtpClientProvider</tt> in the resource 120 * directory <tt>META-INF/services</tt>, then the first class name 121 * specified in that file is taken. The class is loaded and 122 * instantiated; if this process fails then an unspecified unchecked error or exception is 123 * thrown. </p></li> 124 * 125 * <li><p> Finally, if no provider has been specified by any of the above 126 * means then the system-default provider class is instantiated and the 127 * result is returned. </p></li> 128 * 129 * </ol> 130 * 131 * <p> Subsequent invocations of this method return the provider that was 132 * returned by the first invocation. </p> 133 * 134 * @return The system-wide default FtpClientProvider 135 */ provider()136 public static FtpClientProvider provider() { 137 synchronized (lock) { 138 if (provider != null) { 139 return provider; 140 } 141 return (FtpClientProvider) AccessController.doPrivileged( 142 new PrivilegedAction<Object>() { 143 144 public Object run() { 145 if (loadProviderFromProperty()) { 146 return provider; 147 } 148 if (loadProviderAsService()) { 149 return provider; 150 } 151 provider = new sun.net.ftp.impl.DefaultFtpClientProvider(); 152 return provider; 153 } 154 }); 155 } 156 } 157 } 158