1 /* 2 * Copyright (c) 2005, 2019, 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 26 package javax.tools; 27 28 import java.security.AccessController; 29 import java.security.PrivilegedAction; 30 import java.util.Iterator; 31 import java.util.ServiceConfigurationError; 32 import java.util.ServiceLoader; 33 34 /** 35 * Provides methods for locating tool providers, for example, 36 * providers of compilers. This class complements the 37 * functionality of {@link java.util.ServiceLoader}. 38 * 39 * @author Peter von der Ahé 40 * @since 1.6 41 */ 42 public class ToolProvider { 43 44 private static final String systemJavaCompilerModule = "jdk.compiler"; 45 private static final String systemJavaCompilerName = "com.sun.tools.javac.api.JavacTool"; 46 47 /** 48 * Do not call. 49 */ 50 @Deprecated(forRemoval=true, since="14") 51 public ToolProvider() {} 52 53 /** 54 * Returns the Java programming language compiler provided 55 * with this platform. 56 * <p>The file manager returned by calling 57 * {@link JavaCompiler#getStandardFileManager getStandardFileManager} 58 * on this compiler supports paths provided by any 59 * {@linkplain java.nio.file.FileSystem filesystem}.</p> 60 * @return the compiler provided with this platform or 61 * {@code null} if no compiler is provided 62 * @implNote This implementation returns the compiler provided 63 * by the {@code jdk.compiler} module if that module is available, 64 * and {@code null} otherwise. 65 */ 66 public static JavaCompiler getSystemJavaCompiler() { 67 return getSystemTool(JavaCompiler.class, 68 systemJavaCompilerModule, systemJavaCompilerName); 69 } 70 71 private static final String systemDocumentationToolModule = "jdk.javadoc"; 72 private static final String systemDocumentationToolName = "jdk.javadoc.internal.api.JavadocTool"; 73 74 /** 75 * Returns the Java programming language documentation tool provided 76 * with this platform. 77 * <p>The file manager returned by calling 78 * {@link DocumentationTool#getStandardFileManager getStandardFileManager} 79 * on this tool supports paths provided by any 80 * {@linkplain java.nio.file.FileSystem filesystem}.</p> 81 * @return the documentation tool provided with this platform or 82 * {@code null} if no documentation tool is provided 83 * @implNote This implementation returns the tool provided 84 * by the {@code jdk.javadoc} module if that module is available, 85 * and {@code null} otherwise. 86 */ 87 public static DocumentationTool getSystemDocumentationTool() { 88 return getSystemTool(DocumentationTool.class, 89 systemDocumentationToolModule, systemDocumentationToolName); 90 } 91 92 /** 93 * Returns a class loader that may be used to load system tools, 94 * or {@code null} if no such special loader is provided. 95 * @implSpec This implementation always returns {@code null}. 96 * @deprecated This method is subject to removal in a future version of 97 * Java SE. 98 * Use the {@link java.util.spi.ToolProvider system tool provider} or 99 * {@link java.util.ServiceLoader service loader} mechanisms to 100 * locate system tools as well as user-installed tools. 101 * @return a class loader, or {@code null} 102 */ 103 @Deprecated(since="9") 104 public static ClassLoader getSystemToolClassLoader() { 105 return null; 106 } 107 108 /** 109 * Get an instance of a system tool using the service loader. 110 * @implNote By default, this returns the implementation in the specified module. 111 * For limited backward compatibility, if this code is run on an older version 112 * of the Java platform that does not support modules, this method will 113 * try and create an instance of the named class. Note that implies the 114 * class must be available on the system class path. 115 * @param <T> the interface of the tool 116 * @param clazz the interface of the tool 117 * @param moduleName the name of the module containing the desired implementation 118 * @param className the class name of the desired implementation 119 * @return the specified implementation of the tool 120 */ 121 private static <T> T getSystemTool(Class<T> clazz, String moduleName, String className) { 122 123 try { 124 ServiceLoader<T> sl = ServiceLoader.load(clazz, ClassLoader.getSystemClassLoader()); 125 for (Iterator<T> iter = sl.iterator(); iter.hasNext(); ) { 126 T tool = iter.next(); 127 if (matches(tool, moduleName)) 128 return tool; 129 } 130 } catch (ServiceConfigurationError e) { 131 throw new Error(e); 132 } 133 return null; 134 } 135 136 /** 137 * Determine if this is the desired tool instance. 138 * @param <T> the interface of the tool 139 * @param tool the instance of the tool 140 * @param moduleName the name of the module containing the desired implementation 141 * @return true if and only if the tool matches the specified criteria 142 */ 143 private static <T> boolean matches(T tool, String moduleName) { 144 PrivilegedAction<Boolean> pa = () -> { 145 Module toolModule = tool.getClass().getModule(); 146 String toolModuleName = toolModule.getName(); 147 return toolModuleName.equals(moduleName); 148 }; 149 return AccessController.doPrivileged(pa); 150 } 151 }