ToolProvider.java revision 3260:f04e97a97930
1/* 2 * Copyright (c) 2005, 2016, 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 26package javax.tools; 27 28import java.lang.ref.Reference; 29import java.lang.ref.WeakReference; 30import java.util.HashMap; 31import java.util.Map; 32 33/** 34 * Provides methods for locating tool providers, for example, 35 * providers of compilers. This class complements the 36 * functionality of {@link java.util.ServiceLoader}. 37 * 38 * @author Peter von der Ahé 39 * @since 1.6 40 */ 41public class ToolProvider { 42 43 private static final String systemJavaCompilerName 44 = "com.sun.tools.javac.api.JavacTool"; 45 46 /** 47 * Returns the Java™ programming language compiler provided 48 * with this platform. 49 * <p>The file manager returned by calling 50 * {@link JavaCompiler#getStandardFileManager getStandardFileManager} 51 * on this compiler supports paths provided by any 52 * {@linkplain java.nio.file.FileSystem filesystem}.</p> 53 * @return the compiler provided with this platform or 54 * {@code null} if no compiler is provided 55 */ 56 public static JavaCompiler getSystemJavaCompiler() { 57 return instance().getSystemTool(JavaCompiler.class, systemJavaCompilerName); 58 } 59 60 private static final String systemDocumentationToolName 61 = "jdk.javadoc.internal.api.JavadocTool"; 62 63 /** 64 * Returns the Java™ programming language documentation tool provided 65 * with this platform. 66 * <p>The file manager returned by calling 67 * {@link DocumentationTool#getStandardFileManager getStandardFileManager} 68 * on this tool supports paths provided by any 69 * {@linkplain java.nio.file.FileSystem filesystem}.</p> 70 * @return the documentation tool provided with this platform or 71 * {@code null} if no documentation tool is provided 72 */ 73 public static DocumentationTool getSystemDocumentationTool() { 74 return instance().getSystemTool(DocumentationTool.class, systemDocumentationToolName); 75 } 76 77 /** 78 * Returns the class loader for tools provided with this platform. 79 * This does not include user-installed tools. Use the 80 * {@linkplain java.util.ServiceLoader service provider mechanism} 81 * for locating user installed tools. 82 * 83 * @return the class loader for tools provided with this platform 84 * or {@code null} if no tools are provided 85 */ 86 public static ClassLoader getSystemToolClassLoader() { 87 return ClassLoader.getSystemClassLoader(); 88 } 89 90 91 private static ToolProvider instance; 92 93 private static synchronized ToolProvider instance() { 94 if (instance == null) 95 instance = new ToolProvider(); 96 return instance; 97 } 98 99 // Cache for tool classes. 100 // Use weak references to avoid keeping classes around unnecessarily 101 private final Map<String, Reference<Class<?>>> toolClasses = new HashMap<>(); 102 103 private ToolProvider() { } 104 105 private <T> T getSystemTool(Class<T> clazz, String name) { 106 Class<? extends T> c = getSystemToolClass(clazz, name); 107 try { 108 return c.asSubclass(clazz).newInstance(); 109 } catch (InstantiationException | IllegalAccessException | RuntimeException | Error e) { 110 throw new Error(e); 111 } 112 } 113 114 private <T> Class<? extends T> getSystemToolClass(Class<T> clazz, String name) { 115 Reference<Class<?>> refClass = toolClasses.get(name); 116 Class<?> c = (refClass == null ? null : refClass.get()); 117 if (c == null) { 118 try { 119 c = Class.forName(name, false, ClassLoader.getSystemClassLoader()); 120 } catch (ClassNotFoundException | RuntimeException | Error e) { 121 throw new Error(e); 122 } 123 toolClasses.put(name, new WeakReference<>(c)); 124 } 125 return c.asSubclass(clazz); 126 } 127} 128