KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > model > compiler > CompilerRegistry


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32  * END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.model.compiler;
35
36 import java.util.LinkedList JavaDoc;
37 import java.lang.reflect.Field JavaDoc;
38
39 import edu.rice.cs.util.Log;
40
41 import edu.rice.cs.util.swing.Utilities;
42 import edu.rice.cs.util.UnexpectedException;
43
44 /** Registry for all CompilerInterface implementations. Allows registration, by class name, of {@link CompilerInterface}
45  * implementations. Later, the list of these registered compilers (but only those that successfully loaded) can be
46  * retrieved.
47  * @version $Id: CompilerRegistry.java 3877 2006-06-08 22:29:32Z rcartwright $
48  */

49 public class CompilerRegistry {
50   
51   /* classes that load and adapt various compilers */
52   
53   public static final String JavaDoc[] JAVA_16_COMPILERS = {
54     // javac 1.6 "compiler interfaces"
55
"edu.rice.cs.drjava.model.compiler.Javac160FromSetLocation",
56     "edu.rice.cs.drjava.model.compiler.Javac160FromClasspath",
57     "edu.rice.cs.drjava.model.compiler.Javac160FromToolsJar"
58   };
59   
60   public static final String JavaDoc[] JAVA_15_COMPILERS = {
61     // javac 1.5 "compiler interfaces"
62
"edu.rice.cs.drjava.model.compiler.Javac150FromSetLocation",
63     "edu.rice.cs.drjava.model.compiler.Javac150FromClasspath",
64     "edu.rice.cs.drjava.model.compiler.Javac150FromToolsJar"
65   };
66
67   /** A subset of DEFAULT_COMPILERS that support Raw (non-generic) Java. */
68   public static final String JavaDoc[] JAVA_14_COMPILERS = {
69     // javac 1.4 "compiler interfaces"
70
"edu.rice.cs.drjava.model.compiler.Javac141FromSetLocation",
71     "edu.rice.cs.drjava.model.compiler.Javac141FromClasspath",
72     "edu.rice.cs.drjava.model.compiler.Javac141FromToolsJar"
73   };
74
75   /** The list of compiler loading classes that are distributed with DrJava. */
76   static final String JavaDoc[][] DEFAULT_COMPILERS = {
77     // javac 1.6
78
JAVA_16_COMPILERS,
79     // javac 1.5
80
JAVA_15_COMPILERS,
81     // javac 1.4
82
JAVA_14_COMPILERS
83   };
84     
85   /** Singleton instance. */
86   public static final CompilerRegistry ONLY = new CompilerRegistry();
87   
88   private final static Log _log = new Log("CompilerTest.txt", false);
89
90   /** Class loader to use to fetch compiler classes. */
91   private volatile ClassLoader JavaDoc _baseClassLoader;
92   
93   /** The candidate compilers give the version of Java being executed */
94   private final String JavaDoc[] _candidateCompilers;
95
96   /** The active compiler. Must never be null. */
97   private CompilerInterface _activeCompiler = NoCompilerAvailable.ONLY;
98
99   /** Private constructor due to singleton. */
100   private CompilerRegistry() {
101     _baseClassLoader = getClass().getClassLoader();
102     
103     String JavaDoc version = CompilerProxy.VERSION; // version of executing JVM: 1.4, 1.5, 1.6
104

105     if (version.equals("1.4")) _candidateCompilers = JAVA_14_COMPILERS;
106     else if (version.equals("1.5")) _candidateCompilers = JAVA_15_COMPILERS;
107     else if (version.equals("1.6")) _candidateCompilers = JAVA_16_COMPILERS;
108     else _candidateCompilers = null;
109   }
110     
111   /** Sets the base class loader used to load compiler classes. */
112   public void setBaseClassLoader(ClassLoader JavaDoc l) { _baseClassLoader = l; }
113
114   /** Gets the base class loader used to load compiler classes. */
115   public ClassLoader JavaDoc getBaseClassLoader() { return _baseClassLoader; }
116
117   /** Returns all registered compilers that are actually available. That is, for all elements in the returned array,
118    * .isAvailable() is true. <P> This method will never return null or a zero-length array. Instead, if no compiler
119    * is registered and available, this will return a one-element array containing an instance of {@link
120    * NoCompilerAvailable}.
121    */

122   public CompilerInterface[] getAvailableCompilers() {
123     LinkedList JavaDoc<CompilerInterface> availableCompilers = new LinkedList JavaDoc<CompilerInterface>();
124     
125     if (_candidateCompilers == null) throw new
126       UnexpectedException("Java specification version " + CompilerProxy.VERSION + "is not supported. Must be 1.4, 1.5, or 1.6");
127
128     for (String JavaDoc name : _candidateCompilers) {
129       _log.log("CompilerRegistry.getAvailableCompilers is checking compiler: " + name);
130       try { if (_createCompiler(name, availableCompilers)) continue; }
131       catch (Throwable JavaDoc t) {
132         // This compiler didn't load. Keep on going.
133
_log.log("Compiler " + name + " failed to load:");
134         //t.printStackTrace(DrJava.consoleOut());
135
//System.err.println();
136
}
137     }
138
139     if (availableCompilers.size() == 0) availableCompilers.add(NoCompilerAvailable.ONLY);
140     
141    _log.log("CompilerRegistry.getAvailableCompilers() returning " + availableCompilers);
142     
143     return availableCompilers.toArray(new CompilerInterface[availableCompilers.size()]);
144   }
145
146   private boolean _createCompiler(String JavaDoc name, LinkedList JavaDoc<CompilerInterface> availableCompilers) throws Throwable JavaDoc {
147     _log.log("CompilerRegistry._createCompiler(" + name + ", " + availableCompilers +") called");
148     CompilerInterface compiler = _instantiateCompiler(name);
149     if (compiler.isAvailable()) {
150       _log.log("Compiler " + this + " is available: added to compile list");
151
152       // can't use getActiveCompiler() because it will call back to
153
// getAvailableCompilers, forming an infinite recursion!!
154
if (_activeCompiler == NoCompilerAvailable.ONLY) {
155         //System.err.println("\tset to active.");
156
_activeCompiler = compiler;
157       }
158 // Utilities.show("Adding compiler " + compiler);
159
availableCompilers.add(compiler);
160       return true;
161     }
162     else {
163       _log.log("Compiler " + this + " is NOT available.");
164       return false;
165     }
166   }
167
168   public boolean isNoCompilerAvailable() { return getActiveCompiler() == NoCompilerAvailable.ONLY; }
169
170   /** Sets which compiler is the "active" compiler.
171    * @param compiler Compiler to set active. Cannot be null.
172    * @throws IllegalArgumentException if compiler is null.
173    *
174    * @see #getActiveCompiler
175    */

176   public void setActiveCompiler(CompilerInterface compiler) {
177     if (compiler == null) {
178       // Can't let active compiler be null
179
throw new IllegalArgumentException JavaDoc("Cannot set active compiler to null.");
180     }
181     else _activeCompiler = compiler;
182   }
183
184   /** Gets the compiler is the "active" compiler. If there is no "active" compiler or if the active compiler is
185    * not available, this will return {@link NoCompilerAvailable}.
186    * @see #setActiveCompiler
187    */

188   public CompilerInterface getActiveCompiler() {
189     // If no compiler is available now, try to see if we can get one
190
if (_activeCompiler == NoCompilerAvailable.ONLY) getAvailableCompilers();
191
192     //DrJava.consoleErr().println("active compiler: " + _activeCompiler);
193

194     if (_activeCompiler.isAvailable()) return _activeCompiler;
195     return NoCompilerAvailable.ONLY;
196   }
197
198   /** Instantiate the given compiler.
199    * @param name Full class name of compiler to instantiate. This class must implement {@link CompilerInterface}.
200    * @return Instance of {@link CompilerInterface}. This will either be the value of the .ONLY field of the class
201    * (if it exists and is an implementation of CompilerInterface) or a new instance of the given class.
202    * @throws Throwable If the compiler does not load, some type of exception will be thrown. Which particular one
203    * depends on how it failed. It is non-recoverable; the exception is thrown just to indicate failure.
204    */

205   private CompilerInterface _instantiateCompiler(String JavaDoc name) throws Throwable JavaDoc {
206     _log.log("CompilerRegistry._instantiateCompiler using class loader " + _baseClassLoader + " to load " + name);
207     Class JavaDoc<?> clazz = _baseClassLoader.loadClass(name);
208     _log.log("Loaded compiler named " + name + " with class name " + clazz);
209     return createCompiler(clazz);
210   }
211
212   public static CompilerInterface createCompiler(Class JavaDoc clazz) throws Throwable JavaDoc {
213     try {
214       _log.log("CompilerRegistry.createCompiler(" + clazz + ") called");
215       Field JavaDoc field = clazz.getField("ONLY");
216       _log.log(clazz + ".ONLY = " + field);
217       Object JavaDoc val = field.get(null); // null is passed to get since it's a static field
218
_log.log("createCompiler(" + clazz + ") returning " + val);
219       return (CompilerInterface) val;
220     }
221     catch (Throwable JavaDoc t) {
222       // Not a compiler provided by ToolsJarClassLoader
223
_log.log("createCompiler threw exception " + t);
224       return (CompilerInterface) clazz.newInstance();
225     }
226   }
227 }
228
Popular Tags