| Javac.java |
1 /*
2 *
3 * Copyright (c) 1998-2005, The University of Sheffield.
4 *
5 * This file is part of GATE (see http://gate.ac.uk/), and is free
6 * software, licenced under the GNU Library General Public License,
7 * Version 2, June 1991 (in the distribution as file licence.html,
8 * and also available at http://gate.ac.uk/gate/licence.html).
9 *
10 * Valentin Tablan, 18/Feb/2002
11 *
12 * $Id: Javac.java,v 1.24 2005/01/11 13:51:37 ian Exp $
13 */
14 package gate.util;
15
16 import java.io.*;
17 import java.util.*;
18
19 import gate.Gate;
20 import gate.GateConstants;
21
22 /**
23 * This class compiles a set of java sources using the user's preferred Java
24 * compiler. The default compiler used is the Eclipse JDT compiler, but this
25 * can be overridden by the user via an option in gate.xml.
26 */
27 public abstract class Javac implements GateConstants {
28
29 /**
30 * Compiles a set of java sources and loads the compiled classes in the gate
31 * class loader.
32 * @param sources a map from fully qualified classname to java source
33 * @throws GateException in case of a compilation error or warning.
34 * In the case of warnings the compiled classes are loaded before the error is
35 * raised.
36 */
37 public static void loadClasses(Map sources) throws GateException {
38 if(compiler == null) {
39 setCompilerTypeFromUserConfig();
40 }
41
42 compiler.compile(sources);
43 }
44
45 /**
46 * Sets the type of compiler to be used, based on the user's configuration.
47 * The default is to use the Eclipse compiler unless the user requests
48 * otherwise.
49 */
50 private static void setCompilerTypeFromUserConfig() throws GateException {
51 if(classLoader == null) classLoader = Gate.getClassLoader();
52 // see if the user has expressed a preference
53 String compilerType = Gate.getUserConfig().getString(COMPILER_TYPE_KEY);
54 // if not, use the default
55 if(compilerType == null) {
56 compilerType = DEFAULT_COMPILER;
57 }
58
59 // We try and load the compiler class first by treating the given name as a
60 // fully qualified class name. If this fails, we prepend
61 // "gate.util.compilers." (so the user can say just "Sun" rather than
62 // "gate.util.compilers.Sun"). If that fails, we try the default value
63 // DEFAULT_COMPILER. If that fails, we give up.
64 Class compilerClass = null;
65 try {
66 // first treat the compiler type as a fully qualified class name
67 compilerClass = classLoader.loadClass(compilerType, true);
68 }
69 catch(ClassNotFoundException cnfe) {
70 // not a problem
71 }
72
73 if(compilerClass == null
74 || !Javac.class.isAssignableFrom(compilerClass)) {
75 // failed to find the class as a FQN, so try relative to
76 // gate.util.compilers
77 compilerType = "gate.util.compilers." + compilerType;
78 try {
79 compilerClass = classLoader.loadClass(compilerType, true);
80 }
81 catch(ClassNotFoundException cnfe2) {
82 // still not a problem
83 }
84 }
85
86 if(compilerClass == null
87 || !Javac.class.isAssignableFrom(compilerClass)) {
88 Err.prln("Unable to load compiler class " + compilerType
89 + ", falling back to default of " + DEFAULT_COMPILER);
90 compilerType = DEFAULT_COMPILER;
91 try {
92 compilerClass = classLoader.loadClass(compilerType, true);
93 }
94 catch(ClassNotFoundException cnfe3) {
95 // a problem
96 }
97 }
98
99 if(compilerClass == null
100 || !Javac.class.isAssignableFrom(compilerClass)) {
101 throw new GateException("Unable to load a Java compiler class");
102 }
103
104 // At this point we have successfully loaded a compiler class.
105 // Now create an instance using a no-argument constructor.
106 try {
107 compiler = (Javac)compilerClass.newInstance();
108 }
109 catch(IllegalAccessException iae) {
110 Err.prln("Cannot access Java compiler class " + compilerType);
111 throw new GateException(iae);
112 }
113 catch(InstantiationException ie) {
114 Err.prln("Cannot instantiate Java compiler class " + compilerType);
115 throw new GateException(ie);
116 }
117 }
118
119 /**
120 * Compile a set of Java sources, and load the resulting classes into the
121 * GATE class loader.
122 *
123 * @param sources a map from fully qualified classname to java source
124 * @throws GateException in case of a compilation error or warning.
125 * In the case of warnings, the compiled classes are loaded before the
126 * exception is thrown.
127 */
128 public abstract void compile(Map sources) throws GateException;
129
130 /**
131 * The compiler to use.
132 */
133 private static Javac compiler = null;
134
135 /**
136 * The GATE class loader.
137 */
138 private static GateClassLoader classLoader = null;
139
140 /**
141 * The default compiler to use.
142 */
143 public static final String DEFAULT_COMPILER = "gate.util.compilers.Eclipse";
144 }
145