001: package com.quadcap.http.servlets.jsp;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.ByteArrayOutputStream;
042: import java.io.File;
043: import java.io.FileInputStream;
044: import java.io.FileOutputStream;
045: import java.io.IOException;
046: import java.io.InputStream;
047: import java.io.OutputStream;
048:
049: import java.util.Properties;
050:
051: import javax.servlet.ServletContext;
052:
053: import com.quadcap.http.server22.WebApplication;
054:
055: import com.quadcap.io.IO;
056:
057: import com.quadcap.util.Debug;
058:
059: /**
060: * Compile java to class files using the configured compiler options.
061: *
062: * @author Stan Bailes
063: */
064: public class JavaCompiler {
065: File root;
066: String compileCmd;
067: String contextClassPath = "";
068: Properties defaultProps;
069:
070: public JavaCompiler() {
071: }
072:
073: public void init(ServletContext context, File root,
074: String compileCmd, Properties defaultProps) {
075: this .root = root;
076: this .compileCmd = compileCmd;
077: this .defaultProps = defaultProps;
078: if (context instanceof WebApplication) {
079: WebApplication app = (WebApplication) context;
080: contextClassPath = app.getContextClassPath();
081: }
082: }
083:
084: private Thread copyOutput(final OutputStream os,
085: final InputStream is) {
086: return new Thread() {
087: public void run() {
088: int c;
089: try {
090: IO.copyStream(is, os);
091: } catch (IOException e) {
092: }
093: }
094: };
095: }
096:
097: String getCompileCommand(Properties props) {
098: StringBuffer sb = new StringBuffer();
099: StringBuffer nb = new StringBuffer();
100: int state = 0;
101: for (int i = 0; i < compileCmd.length(); i++) {
102: char c = compileCmd.charAt(i);
103: switch (state) {
104: case 0:
105: if (c == '%') {
106: state = 1;
107: nb.setLength(0);
108: } else {
109: sb.append(c);
110: }
111: break;
112: case 1:
113: if (c == '%') {
114: sb.append(c);
115: state = 0;
116: } else {
117: nb.append(c);
118: state = 2;
119: }
120: break;
121: case 2:
122: if (c == '%') {
123: sb.append(props.getProperty(nb.toString()));
124: state = 0;
125: } else {
126: nb.append(c);
127: }
128: }
129: }
130: return sb.toString();
131: }
132:
133: public boolean doCompile(String cmd, OutputStream out)
134: throws IOException {
135: Process p = Runtime.getRuntime().exec(cmd);
136: Thread errthread = copyOutput(out, p.getErrorStream());
137: Thread outthread = copyOutput(out, p.getInputStream());
138: errthread.start();
139: outthread.start();
140: int res = -1;
141: try {
142: res = p.waitFor();
143: } catch (Throwable t) {
144: }
145: try {
146: errthread.join();
147: } catch (Throwable t) {
148: }
149: try {
150: outthread.join();
151: } catch (Throwable t) {
152: }
153: return res == 0;
154: }
155:
156: public void compile(File javaFile, File classFile)
157: throws IOException, ClassNotFoundException, JspException {
158: Properties cprops = new Properties(defaultProps);
159: cprops.put("source", javaFile.getPath());
160: cprops.put("repository", root.getPath());
161: cprops.put("context.classpath", contextClassPath);
162: String cmd = getCompileCommand(cprops);
163: if (Trace.level() > 2) {
164: Debug.println("COMPILE: " + cmd);
165: }
166: ByteArrayOutputStream bos = new ByteArrayOutputStream();
167: boolean ok = doCompile(cmd, bos);
168: if (Trace.level() > 3) {
169: Debug.println("COMPILE OUTPUT: " + bos.toString());
170: }
171: if (!ok) {
172: throw new JspException("compile failed: " + bos.toString());
173: }
174: if (!classFile.exists()) {
175: throw new ClassNotFoundException(
176: "No class file generated by compile: "
177: + bos.toString());
178: }
179: }
180:
181: //#ifdef DEBUG
182: public static void main(String args[]) {
183: String cmd = "./jikes -classpath %java.class.path%;%repository%;%java.home%/lib/rt.jar -d %repository% +D +E -nowarn %source%";
184: Properties props = System.getProperties();
185: try {
186: JavaCompiler jc = new JavaCompiler();
187: jc.init(null, new File("./repository"), cmd, props);
188: File j = new File("./repository/__jsp/login.java");
189: File c = new File("./repository/__jsp/login.class");
190: jc.compile(j, c);
191: } catch (Throwable tt) {
192: tt.printStackTrace(System.err);
193: }
194: }
195: //#endif
196: }
|