1 /* 2 * Copyright (c) 2009, 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 sun.misc.Service; 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 x) { 74 throw new ServiceConfigurationError(x.toString()); 75 } catch (IllegalAccessException x) { 76 throw new ServiceConfigurationError(x.toString()); 77 } catch (InstantiationException x) { 78 throw new ServiceConfigurationError(x.toString()); 79 } catch (SecurityException x) { 80 throw new ServiceConfigurationError(x.toString()); 81 } 82 } 83 loadProviderAsService()84 private static boolean loadProviderAsService() { 85 // Iterator i = Service.providers(FtpClientProvider.class, 86 // ClassLoader.getSystemClassLoader()); 87 // while (i.hasNext()) { 88 // try { 89 // provider = (FtpClientProvider) i.next(); 90 // return true; 91 // } catch (ServiceConfigurationError sce) { 92 // if (sce.getCause() instanceof SecurityException) { 93 // // Ignore, try next provider, if any 94 // continue; 95 // } 96 // throw sce; 97 // } 98 // } 99 return false; 100 } 101 102 /** 103 * Returns the system wide default FtpClientProvider for this invocation of 104 * the Java virtual machine. 105 * 106 * <p> The first invocation of this method locates the default provider 107 * object as follows: </p> 108 * 109 * <ol> 110 * 111 * <li><p> If the system property 112 * <tt>java.net.FtpClientProvider</tt> is defined then it is 113 * taken to be the fully-qualified name of a concrete provider class. 114 * The class is loaded and instantiated; if this process fails then an 115 * unspecified unchecked error or exception is thrown. </p></li> 116 * 117 * <li><p> If a provider class has been installed in a jar file that is 118 * visible to the system class loader, and that jar file contains a 119 * provider-configuration file named 120 * <tt>java.net.FtpClientProvider</tt> in the resource 121 * directory <tt>META-INF/services</tt>, then the first class name 122 * specified in that file is taken. The class is loaded and 123 * instantiated; if this process fails then an unspecified unchecked error or exception is 124 * thrown. </p></li> 125 * 126 * <li><p> Finally, if no provider has been specified by any of the above 127 * means then the system-default provider class is instantiated and the 128 * result is returned. </p></li> 129 * 130 * </ol> 131 * 132 * <p> Subsequent invocations of this method return the provider that was 133 * returned by the first invocation. </p> 134 * 135 * @return The system-wide default FtpClientProvider 136 */ provider()137 public static FtpClientProvider provider() { 138 synchronized (lock) { 139 if (provider != null) { 140 return provider; 141 } 142 return (FtpClientProvider) AccessController.doPrivileged( 143 new PrivilegedAction<Object>() { 144 145 public Object run() { 146 if (loadProviderFromProperty()) { 147 return provider; 148 } 149 if (loadProviderAsService()) { 150 return provider; 151 } 152 provider = new sun.net.ftp.impl.DefaultFtpClientProvider(); 153 return provider; 154 } 155 }); 156 } 157 } 158 } 159