001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package javax.tools;
027:
028: import java.io.File;
029: import java.net.URL;
030: import java.net.URLClassLoader;
031: import java.net.MalformedURLException;
032: import java.util.Locale;
033: import java.util.logging.Logger;
034: import java.util.logging.Level;
035: import static java.util.logging.Level.*;
036:
037: /**
038: * Provides methods for locating tool providers, for example,
039: * providers of compilers. This class complements the
040: * functionality of {@link java.util.ServiceLoader}.
041: *
042: * @author Peter von der Ahé
043: * @since 1.6
044: */
045: public class ToolProvider {
046:
047: private ToolProvider() {
048: }
049:
050: private static final String propertyName = "sun.tools.ToolProvider";
051: private static final String loggerName = "javax.tools";
052:
053: /*
054: * Define the system property "sun.tools.ToolProvider" to enable
055: * debugging:
056: *
057: * java ... -Dsun.tools.ToolProvider ...
058: */
059: static <T> T trace(Level level, Object reason) {
060: // NOTE: do not make this method private as it affects stack traces
061: try {
062: if (System.getProperty(propertyName) != null) {
063: StackTraceElement[] st = Thread.currentThread()
064: .getStackTrace();
065: String method = "???";
066: String cls = ToolProvider.class.getName();
067: if (st.length > 2) {
068: StackTraceElement frame = st[2];
069: method = String.format((Locale) null, "%s(%s:%s)",
070: frame.getMethodName(), frame.getFileName(),
071: frame.getLineNumber());
072: cls = frame.getClassName();
073: }
074: Logger logger = Logger.getLogger(loggerName);
075: if (reason instanceof Throwable) {
076: logger.logp(level, cls, method, reason.getClass()
077: .getName(), (Throwable) reason);
078: } else {
079: logger.logp(level, cls, method, String
080: .valueOf(reason));
081: }
082: }
083: } catch (SecurityException ex) {
084: System.err.format((Locale) null, "%s: %s; %s%n",
085: ToolProvider.class.getName(), reason, ex
086: .getLocalizedMessage());
087: }
088: return null;
089: }
090:
091: /**
092: * Gets the Java™ programming language compiler provided
093: * with this platform.
094: * @return the compiler provided with this platform or
095: * {@code null} if no compiler is provided
096: */
097: public static JavaCompiler getSystemJavaCompiler() {
098: if (Lazy.compilerClass == null)
099: return trace(WARNING, "Lazy.compilerClass == null");
100: try {
101: return Lazy.compilerClass.newInstance();
102: } catch (Throwable e) {
103: return trace(WARNING, e);
104: }
105: }
106:
107: /**
108: * Returns the class loader for tools provided with this platform.
109: * This does not include user-installed tools. Use the
110: * {@linkplain java.util.ServiceLoader service provider mechanism}
111: * for locating user installed tools.
112: *
113: * @return the class loader for tools provided with this platform
114: * or {@code null} if no tools are provided
115: */
116: public static ClassLoader getSystemToolClassLoader() {
117: if (Lazy.compilerClass == null)
118: return trace(WARNING, "Lazy.compilerClass == null");
119: return Lazy.compilerClass.getClassLoader();
120: }
121:
122: /**
123: * This class will not be initialized until one of the above
124: * methods are called. This ensures that searching for the
125: * compiler does not affect platform start up.
126: */
127: static class Lazy {
128: private static final String defaultJavaCompilerName = "com.sun.tools.javac.api.JavacTool";
129: private static final String[] defaultToolsLocation = { "lib",
130: "tools.jar" };
131: static final Class<? extends JavaCompiler> compilerClass;
132: static {
133: Class<? extends JavaCompiler> c = null;
134: try {
135: c = findClass().asSubclass(JavaCompiler.class);
136: } catch (Throwable t) {
137: trace(WARNING, t);
138: }
139: compilerClass = c;
140: }
141:
142: private static Class<?> findClass()
143: throws MalformedURLException, ClassNotFoundException {
144: try {
145: return enableAsserts(Class.forName(
146: defaultJavaCompilerName, false, null));
147: } catch (ClassNotFoundException e) {
148: trace(FINE, e);
149: }
150: File file = new File(System.getProperty("java.home"));
151: if (file.getName().equalsIgnoreCase("jre"))
152: file = file.getParentFile();
153: for (String name : defaultToolsLocation)
154: file = new File(file, name);
155: URL[] urls = { file.toURI().toURL() };
156: trace(FINE, urls[0].toString());
157: ClassLoader cl = URLClassLoader.newInstance(urls);
158: cl.setPackageAssertionStatus("com.sun.tools.javac", true);
159: return Class.forName(defaultJavaCompilerName, false, cl);
160: }
161:
162: private static Class<?> enableAsserts(Class<?> cls) {
163: try {
164: ClassLoader loader = cls.getClassLoader();
165: if (loader != null)
166: loader.setPackageAssertionStatus(
167: "com.sun.tools.javac", true);
168: else
169: trace(FINE, "loader == null");
170: } catch (SecurityException ex) {
171: trace(FINE, ex);
172: }
173: return cls;
174: }
175: }
176: }
|