001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 1999 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
027: * Foundation" must not be used to endorse or promote products derived
028: * from this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of the Apache Software Foundation. For more
051: * information on the Apache Software Foundation, please see
052: * <http://www.apache.org/>.
053: *
054: */
055:
056: package com.sun.portal.providers.jsp.jasper3.jasper.compiler;
057:
058: import java.io.ByteArrayOutputStream;
059: import java.io.OutputStream;
060: import java.io.PrintStream;
061: import java.io.PrintWriter;
062: import java.lang.reflect.InvocationTargetException;
063: import java.lang.reflect.Method;
064:
065: /**
066: * In order to fix the problem of failing to compile big JSPs
067: * with large # of tags using sun.tools.javac.Main with JDK 1.4.x,
068: * this default compiler is modified to use sun.tools.javac.Main
069: * only in the case of JDK 1.3.x (or earlier JDK versions) and use
070: * com.sun.tools.javac.Main in the case of JDK 1.4.x.
071: *
072: * The Java Reflection mechanism is used to switch between these
073: * two cases and appropriate initialization is done within the static
074: * initializer block to improve the performance.
075: *
076: */
077: public class SunJavaCompiler implements JavaCompiler {
078:
079: // A@
080: // Since the following method
081: //
082: // public static int compile(java.lang.String[], java.io.PrintWriter);
083: //
084: // is only contained in com.sun.tools.javac.Main with JDK 1.4.x, if
085: // this method can be obtained through the Java Reflection API, the
086: // static boolean variable "jdk14" will be set to true and this method
087: // will be used to compile the java files. Otherwise (JDK 1.3.x or
088: // earlier JDK versions), sun.tools.javac.Main will be instantiated
089: // (in compile() method) to do the compilation.
090:
091: private static com.sun.tools.javac.Main compiler;
092: private static Method compileMethod;
093: private static boolean jdk14 = false;
094:
095: // static initializer
096: static {
097: try {
098: Class c = Class.forName("com.sun.tools.javac.Main");
099: compiler = (com.sun.tools.javac.Main) c.newInstance();
100:
101: Class paramTypes[] = new Class[2];
102: paramTypes[0] = (new String[1]).getClass();
103: PrintWriter pw = new PrintWriter(new ByteArrayOutputStream(
104: 256));
105: paramTypes[1] = pw.getClass();
106:
107: compileMethod = c.getMethod("compile", paramTypes);
108: jdk14 = true;
109: } catch (NoSuchMethodException nsme) {
110: // thrown in the case of JDK 1.3.x (or earlier JDK versions)
111: } catch (Exception e) {
112: }
113: }
114:
115: String encoding;
116: String classpath; // ignored
117: String compilerPath;
118: String outdir;
119: OutputStream out;
120: boolean classDebugInfo = false;
121:
122: /**
123: * Specify where the compiler can be found
124: */
125: public void setCompilerPath(String compilerPath) {
126: // not used by the SunJavaCompiler
127: this .compilerPath = compilerPath;
128: }
129:
130: /**
131: * Set the encoding (character set) of the source
132: */
133: public void setEncoding(String encoding) {
134: this .encoding = encoding;
135: }
136:
137: /**
138: * Set the class path for the compiler
139: */
140: public void setClasspath(String classpath) {
141: this .classpath = classpath;
142: }
143:
144: /**
145: * Set the output directory
146: */
147: public void setOutputDir(String outdir) {
148: this .outdir = outdir;
149: }
150:
151: /**
152: * Set where you want the compiler output (messages) to go
153: */
154: public void setMsgOutput(OutputStream out) {
155: this .out = out;
156: }
157:
158: /**
159: * Set where you want the compiler output (messages) to go
160: */
161: public void setOut(OutputStream out) {
162: this .out = out;
163: }
164:
165: /**
166: * Set if you want debugging information in the class file
167: */
168: public void setClassDebugInfo(boolean classDebugInfo) {
169: this .classDebugInfo = classDebugInfo;
170: }
171:
172: public boolean compile(String source) {
173:
174: String[] args;
175: if (classDebugInfo) {
176: args = new String[] { "-g", "-encoding", encoding,
177: "-classpath", classpath, "-d", outdir, source };
178: } else {
179: args = new String[] { "-encoding", encoding, "-classpath",
180: classpath, "-d", outdir, source };
181: }
182:
183: // A@
184: boolean retValue = false;
185: if (jdk14) {
186: // In JDK 1.4.x, the signature of the compile() method
187: // used here is as follows:
188: // public static int compile(String[], PrintWriter);
189:
190: Integer result = null;
191: Object[] argsArray1 = new Object[2];
192: PrintWriter pw = new PrintWriter(out);
193: try {
194: argsArray1[0] = args;
195: argsArray1[1] = pw;
196: result = (Integer) compileMethod.invoke(compiler,
197: argsArray1);
198: } catch (Exception e) {
199: e.printStackTrace(pw);
200: }
201: if (result == null) {
202: retValue = false;
203: } else {
204: retValue = (result.intValue() == 0) ? true : false;
205: }
206: } else {
207: // if not JDK 1.4.x, use sun.tools.javac.Main
208: sun.tools.javac.Main comp = new sun.tools.javac.Main(out,
209: "jsp->javac");
210: retValue = comp.compile(args);
211: }
212: return retValue;
213: }
214: }
|