001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Vasily Zakharov
021: * @version $Revision: 1.1.2.3 $
022: */package org.apache.harmony.rmi.common;
023:
024: import java.io.File;
025:
026: import java.lang.reflect.InvocationTargetException;
027: import java.lang.reflect.Method;
028: import java.lang.reflect.Modifier;
029:
030: import java.net.MalformedURLException;
031: import java.net.URL;
032: import java.net.URLClassLoader;
033:
034: /**
035: * This class represents a Java Compiler executed with a simple Java call.
036: * The class provides multiple constructors to allow flexible specification
037: * of what class and method must be used.
038: *
039: * @author Vasily Zakharov
040: * @version $Revision: 1.1.2.3 $
041: */
042: public class MethodJavaCompiler extends JavaCompiler {
043:
044: /**
045: * Default name of a method to call in a compiler class.
046: */
047: public static final String DEFAULT_COMPILER_METHOD = "main"; //$NON-NLS-1$
048:
049: /**
050: * Compiler method signature.
051: */
052: protected static final Class[] COMPILER_METHOD_SIGNATURE = new Class[] { String[].class };
053:
054: /**
055: * Compiler instance.
056: */
057: protected Object compilerInstance;
058:
059: /**
060: * Compiler method.
061: */
062: protected Method compilerMethod;
063:
064: /**
065: * Creates uninitialized instance of this class.
066: * Note that using this constructor in most cases
067: * requires overriding {@link #run(String[])} method.
068: */
069: protected MethodJavaCompiler() {
070: }
071:
072: /**
073: * Configures this class to use {@link #DEFAULT_COMPILER_METHOD} method
074: * of the specified class to compile.
075: *
076: * Equivalent to {@link #MethodJavaCompiler(String, ClassLoader, String)
077: * MethodJavaCompiler(className, null, null)}.
078: *
079: * @param className
080: * Name of the compiler class to use.
081: *
082: * @throws JavaCompilerException
083: * If error occurs while finding or loading
084: * the compiler class or method.
085: */
086: public MethodJavaCompiler(String className)
087: throws JavaCompilerException {
088: this (className, null, null);
089: }
090:
091: /**
092: * Configures this class to use {@link #DEFAULT_COMPILER_METHOD} method
093: * of the specified class (loaded by the specified class loader) to compile.
094: *
095: * Equivalent to {@link #MethodJavaCompiler(String, ClassLoader, String)
096: * MethodJavaCompiler(className, classLoader, null)}.
097: *
098: * @param className
099: * Name of the compiler class to use.
100: *
101: * @param classLoader
102: * Class loader to use to instantiate the specified class.
103: * Can be <code>null</code>, in this case
104: * the default class loader is used.
105: *
106: * @throws JavaCompilerException
107: * If error occurs while finding or loading
108: * the compiler class or method.
109: */
110: public MethodJavaCompiler(String className, ClassLoader classLoader)
111: throws JavaCompilerException {
112: this (className, classLoader, null);
113: }
114:
115: /**
116: * Configures this class to use the specified class and method to compile.
117: *
118: * Equivalent to {@link #MethodJavaCompiler(String, ClassLoader, String)
119: * MethodJavaCompiler(className, null, methodName)}.
120: *
121: * @param className
122: * Name of the compiler class to use.
123: *
124: * @param methodName
125: * Name of the method to use.
126: * Can be <code>null</code>, in this case the
127: * {@linkplain #DEFAULT_COMPILER_METHOD default method name}
128: * is used.
129: *
130: * @throws JavaCompilerException
131: * If error occurs while finding or loading
132: * the compiler class or method.
133: */
134: public MethodJavaCompiler(String className, String methodName)
135: throws JavaCompilerException {
136: this (className, null, methodName);
137: }
138:
139: /**
140: * Configures this class to use the specified class
141: * (loaded by the specified class loader) and method to compile.
142: *
143: * Equivalent to {@link #MethodJavaCompiler(Class, String)
144: * MethodJavaCompiler(Class.forName(className, true, classLoader),
145: * methodName)}.
146: *
147: * @param className
148: * Name of the compiler class to use.
149: *
150: * @param classLoader
151: * Class loader to use to instantiate the specified class.
152: * Can be <code>null</code>, in this case
153: * the default class loader is used.
154: *
155: * @param methodName
156: * Name of the method to use.
157: * Can be <code>null</code>, in this case the
158: * {@linkplain #DEFAULT_COMPILER_METHOD default method name}
159: * is used.
160: *
161: * @throws JavaCompilerException
162: * If error occurs while finding or loading
163: * the compiler class or method.
164: */
165: public MethodJavaCompiler(String className,
166: ClassLoader classLoader, String methodName)
167: throws JavaCompilerException {
168: this (getClass(className, classLoader), methodName);
169: }
170:
171: /**
172: * Configures this class to use method
173: * {@link #DEFAULT_COMPILER_METHOD}<code>(String[])</code>
174: * of the specified class to compile.
175: *
176: * Equivalent to {@link #MethodJavaCompiler(Class, String)
177: * MethodJavaCompiler(c, null)}.
178: *
179: * @param c
180: * Compiler class to use.
181: *
182: * @throws JavaCompilerException
183: * If error occurs while finding or loading
184: * the compiler method.
185: */
186: public MethodJavaCompiler(Class c) throws JavaCompilerException {
187: this (c, null);
188: }
189:
190: /**
191: * Configures this class to use the specified class and method to compile.
192: *
193: * @param c
194: * Compiler class to use.
195: *
196: * @param methodName
197: * Name of the method to use.
198: * Can be <code>null</code>, in this case the
199: * {@linkplain #DEFAULT_COMPILER_METHOD default method name}
200: * is used.
201: *
202: * @throws JavaCompilerException
203: * If error occurs while finding or loading
204: * the compiler method.
205: */
206: public MethodJavaCompiler(Class c, String methodName)
207: throws JavaCompilerException {
208: this (getMethod(c, ((methodName != null) ? methodName
209: : DEFAULT_COMPILER_METHOD)));
210: }
211:
212: /**
213: * Configures this class to use the specified method to compile.
214: *
215: * @param method
216: * Compiler method to use.
217: *
218: * @throws JavaCompilerException
219: * If specified method is an instance method,
220: * and the compiler class cannot be instantiated.
221: */
222: public MethodJavaCompiler(Method method)
223: throws JavaCompilerException {
224: try {
225: compilerInstance = (Modifier
226: .isStatic(method.getModifiers()) ? null : method
227: .getDeclaringClass().newInstance());
228: } catch (InstantiationException e) {
229: throw new JavaCompilerException(e);
230: } catch (IllegalAccessException e) {
231: throw new JavaCompilerException(e);
232: } catch (ExceptionInInitializerError e) {
233: throw new JavaCompilerException(e);
234: }
235: compilerMethod = method;
236: }
237:
238: /**
239: * Runs the compilation process with the specified arguments.
240: *
241: * @param args
242: * Full arguments list.
243: *
244: * @return Java Compiler return value.
245: * For this particular implementation, always <code>0</code>,
246: * unless exception is thrown.
247: *
248: * @throws JavaCompilerException
249: * If some error occurs during invocation.
250: */
251: protected int run(String[] args) throws JavaCompilerException {
252: try {
253: compilerMethod.invoke(compilerInstance,
254: new Object[] { args });
255: return 0;
256: } catch (IllegalAccessException e) {
257: throw new JavaCompilerException(e);
258: } catch (InvocationTargetException e) {
259: throw new JavaCompilerException(e.getCause());
260: }
261: }
262:
263: /**
264: * Tries to create a class loader for the specified JAR file.
265: *
266: * @param jar
267: * Jar file to create class loader for.
268: *
269: * @return Class loader for the specified JAR file.
270: *
271: * @throws JavaCompilerException
272: * If file name parsing failed.
273: */
274: protected static ClassLoader getClassLoaderFromJarFile(File jar)
275: throws JavaCompilerException {
276: try {
277: return new URLClassLoader(new URL[] { jar.toURI().toURL() });
278: } catch (MalformedURLException e) {
279: throw new JavaCompilerException(e);
280: }
281: }
282:
283: /**
284: * Loads the specified class with the specified class loader.
285: * Wraps the possible exceptions to {@link JavaCompilerException}.
286: *
287: * @param className
288: * Name of the class to get.
289: *
290: * @param classLoader
291: * Class loader to use to instantiate the specified class.
292: * Can be <code>null</code>, in this case
293: * the default class loader is used.
294: *
295: * @return The loaded class.
296: *
297: * @throws JavaCompilerException
298: * If error occurs while trying to load the class.
299: */
300: protected static Class getClass(String className,
301: ClassLoader classLoader) throws JavaCompilerException {
302: try {
303: return Class.forName(className, true, classLoader);
304: } catch (ClassNotFoundException e) {
305: throw new JavaCompilerException(e);
306: } catch (LinkageError e) {
307: throw new JavaCompilerException(e);
308: }
309: }
310:
311: /**
312: * Returns the specified compiler method for the specified class.
313: * Wraps the possible exceptions to {@link JavaCompilerException}.
314: *
315: * @param c
316: * Class to get method for.
317: *
318: * @param methodName
319: * Name of the method to get.
320: *
321: * @return The resulting {@link Method} object.
322: *
323: * @throws JavaCompilerException
324: * If method is not found.
325: */
326: protected static Method getMethod(Class c, String methodName)
327: throws JavaCompilerException {
328: return getMethod(c, methodName, COMPILER_METHOD_SIGNATURE);
329: }
330:
331: /**
332: * Returns the specified method for the specified class.
333: * Wraps the possible exceptions to {@link JavaCompilerException}.
334: *
335: * @param c
336: * Class to get method for.
337: *
338: * @param methodName
339: * Name of the method to get.
340: *
341: * @param methodSignature
342: * Signature of the method to get.
343: *
344: * @return The resulting {@link Method} object.
345: *
346: * @throws JavaCompilerException
347: * If method is not found.
348: */
349: protected static Method getMethod(Class c, String methodName,
350: Class[] methodSignature) throws JavaCompilerException {
351: try {
352: return c.getMethod(methodName, methodSignature);
353: } catch (NoSuchMethodException e) {
354: throw new JavaCompilerException(e);
355: }
356: }
357: }
|