src/share/classes/javax/tools/ToolProvider.java

Thu, 15 Nov 2012 23:07:24 -0800

author
jjg
date
Thu, 15 Nov 2012 23:07:24 -0800
changeset 1413
bdcef2ef52d2
parent 816
7c537f4298fb
child 2525
2eb010b6cb22
permissions
-rw-r--r--

6493690: javadoc should have a javax.tools.Tool service provider installed in tools.jar
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 2005, 2012, 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  */
    26 package javax.tools;
    28 import java.io.File;
    29 import java.lang.ref.Reference;
    30 import java.lang.ref.WeakReference;
    31 import java.net.URL;
    32 import java.net.URLClassLoader;
    33 import java.net.MalformedURLException;
    34 import java.util.HashMap;
    35 import java.util.Locale;
    36 import java.util.Map;
    37 import java.util.logging.Logger;
    38 import java.util.logging.Level;
    39 import static java.util.logging.Level.*;
    41 /**
    42  * Provides methods for locating tool providers, for example,
    43  * providers of compilers.  This class complements the
    44  * functionality of {@link java.util.ServiceLoader}.
    45  *
    46  * @author Peter von der Ahé
    47  * @since 1.6
    48  */
    49 public class ToolProvider {
    51     private static final String propertyName = "sun.tools.ToolProvider";
    52     private static final String loggerName   = "javax.tools";
    54     /*
    55      * Define the system property "sun.tools.ToolProvider" to enable
    56      * debugging:
    57      *
    58      *     java ... -Dsun.tools.ToolProvider ...
    59      */
    60     static <T> T trace(Level level, Object reason) {
    61         // NOTE: do not make this method private as it affects stack traces
    62         try {
    63             if (System.getProperty(propertyName) != null) {
    64                 StackTraceElement[] st = Thread.currentThread().getStackTrace();
    65                 String method = "???";
    66                 String cls = ToolProvider.class.getName();
    67                 if (st.length > 2) {
    68                     StackTraceElement frame = st[2];
    69                     method = String.format((Locale)null, "%s(%s:%s)",
    70                                            frame.getMethodName(),
    71                                            frame.getFileName(),
    72                                            frame.getLineNumber());
    73                     cls = frame.getClassName();
    74                 }
    75                 Logger logger = Logger.getLogger(loggerName);
    76                 if (reason instanceof Throwable) {
    77                     logger.logp(level, cls, method,
    78                                 reason.getClass().getName(), (Throwable)reason);
    79                 } else {
    80                     logger.logp(level, cls, method, String.valueOf(reason));
    81                 }
    82             }
    83         } catch (SecurityException ex) {
    84             System.err.format((Locale)null, "%s: %s; %s%n",
    85                               ToolProvider.class.getName(),
    86                               reason,
    87                               ex.getLocalizedMessage());
    88         }
    89         return null;
    90     }
    92     private static final String defaultJavaCompilerName
    93         = "com.sun.tools.javac.api.JavacTool";
    95     /**
    96      * Gets the Java&trade; programming language compiler provided
    97      * with this platform.
    98      * @return the compiler provided with this platform or
    99      * {@code null} if no compiler is provided
   100      */
   101     public static JavaCompiler getSystemJavaCompiler() {
   102         return instance().getSystemTool(JavaCompiler.class, defaultJavaCompilerName);
   103     }
   105     private static final String defaultDocumentationToolName
   106         = "com.sun.tools.javadoc.api.JavadocTool";
   108     /**
   109      * Gets the Java&trade; programming language documentation tool provided
   110      * with this platform.
   111      * @return the documentation tool provided with this platform or
   112      * {@code null} if no documentation tool is provided
   113      */
   114     public static DocumentationTool getSystemDocumentationTool() {
   115         return instance().getSystemTool(DocumentationTool.class, defaultDocumentationToolName);
   116     }
   118     /**
   119      * Returns the class loader for tools provided with this platform.
   120      * This does not include user-installed tools.  Use the
   121      * {@linkplain java.util.ServiceLoader service provider mechanism}
   122      * for locating user installed tools.
   123      *
   124      * @return the class loader for tools provided with this platform
   125      * or {@code null} if no tools are provided
   126      */
   127     public static ClassLoader getSystemToolClassLoader() {
   128         try {
   129             Class<? extends JavaCompiler> c =
   130                     instance().getSystemToolClass(JavaCompiler.class, defaultJavaCompilerName);
   131             return c.getClassLoader();
   132         } catch (Throwable e) {
   133             return trace(WARNING, e);
   134         }
   135     }
   138     private static ToolProvider instance;
   140     private static synchronized ToolProvider instance() {
   141         if (instance == null)
   142             instance = new ToolProvider();
   143         return instance;
   144     }
   146     // Cache for tool classes.
   147     // Use weak references to avoid keeping classes around unnecessarily
   148     private Map<String, Reference<Class<?>>> toolClasses = new HashMap<String, Reference<Class<?>>>();
   150     // Cache for tool classloader.
   151     // Use a weak reference to avoid keeping it around unnecessarily
   152     private Reference<ClassLoader> refToolClassLoader = null;
   155     private ToolProvider() { }
   157     private <T> T getSystemTool(Class<T> clazz, String name) {
   158         Class<? extends T> c = getSystemToolClass(clazz, name);
   159         try {
   160             return c.asSubclass(clazz).newInstance();
   161         } catch (Throwable e) {
   162             trace(WARNING, e);
   163             return null;
   164         }
   165     }
   167     private <T> Class<? extends T> getSystemToolClass(Class<T> clazz, String name) {
   168         Reference<Class<?>> refClass = toolClasses.get(name);
   169         Class<?> c = (refClass == null ? null : refClass.get());
   170         if (c == null) {
   171             try {
   172                 c = findSystemToolClass(name);
   173             } catch (Throwable e) {
   174                 return trace(WARNING, e);
   175             }
   176             toolClasses.put(name, new WeakReference<Class<?>>(c));
   177         }
   178         return c.asSubclass(clazz);
   179     }
   181     private static final String[] defaultToolsLocation = { "lib", "tools.jar" };
   183     private Class<?> findSystemToolClass(String toolClassName)
   184         throws MalformedURLException, ClassNotFoundException
   185     {
   186         // try loading class directly, in case tool is on the bootclasspath
   187         try {
   188             return Class.forName(toolClassName, false, null);
   189         } catch (ClassNotFoundException e) {
   190             trace(FINE, e);
   192             // if tool not on bootclasspath, look in default tools location (tools.jar)
   193             ClassLoader cl = (refToolClassLoader == null ? null : refToolClassLoader.get());
   194             if (cl == null) {
   195                 File file = new File(System.getProperty("java.home"));
   196                 if (file.getName().equalsIgnoreCase("jre"))
   197                     file = file.getParentFile();
   198                 for (String name : defaultToolsLocation)
   199                     file = new File(file, name);
   201                 // if tools not found, no point in trying a URLClassLoader
   202                 // so rethrow the original exception.
   203                 if (!file.exists())
   204                     throw e;
   206                 URL[] urls = { file.toURI().toURL() };
   207                 trace(FINE, urls[0].toString());
   209                 cl = URLClassLoader.newInstance(urls);
   210                 refToolClassLoader = new WeakReference<ClassLoader>(cl);
   211             }
   213             return Class.forName(toolClassName, false, cl);
   214         }
   215     }
   216 }

mercurial