001 /* 002 * Copyright 1999,2004 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.apache.jasper.compiler; 018 019 import java.io.File; 020 import java.io.FileNotFoundException; 021 import java.io.PrintStream; 022 import java.util.StringTokenizer; 023 024 import org.apache.jasper.JasperException; 025 import org.apache.jasper.util.SystemLogHandler; 026 import org.apache.tools.ant.BuildException; 027 import org.apache.tools.ant.DefaultLogger; 028 import org.apache.tools.ant.Project; 029 import org.apache.tools.ant.taskdefs.Javac; 030 import org.apache.tools.ant.types.Path; 031 import org.apache.tools.ant.types.PatternSet; 032 033 /** 034 * Main JSP compiler class. This class uses Ant for compiling. 035 * 036 * @author Anil K. Vijendran 037 * @author Mandar Raje 038 * @author Pierre Delisle 039 * @author Kin-man Chung 040 * @author Remy Maucherat 041 * @author Mark Roth 042 */ 043 public class AntCompiler extends Compiler { 044 045 046 // ----------------------------------------------------- Instance Variables 047 048 protected Project project=null; 049 protected JasperAntLogger logger; 050 051 // ------------------------------------------------------------ Constructor 052 053 // Lazy eval - if we don't need to compile we probably don't need the project 054 protected Project getProject() { 055 056 if( project!=null ) return project; 057 058 // Initializing project 059 project = new Project(); 060 logger = new JasperAntLogger(); 061 logger.setOutputPrintStream(System.out); 062 logger.setErrorPrintStream(System.err); 063 logger.setMessageOutputLevel(Project.MSG_INFO); 064 project.addBuildListener( logger); 065 if (System.getProperty("catalina.home") != null) { 066 project.setBasedir( System.getProperty("catalina.home")); 067 } 068 069 if( options.getCompiler() != null ) { 070 if( log.isDebugEnabled() ) 071 log.debug("Compiler " + options.getCompiler() ); 072 project.setProperty("build.compiler", options.getCompiler() ); 073 } 074 project.init(); 075 return project; 076 } 077 078 class JasperAntLogger extends DefaultLogger { 079 080 protected StringBuffer reportBuf = new StringBuffer(); 081 082 protected void printMessage(final String message, 083 final PrintStream stream, 084 final int priority) { 085 } 086 087 protected void log(String message) { 088 reportBuf.append(message); 089 reportBuf.append(System.getProperty("line.separator")); 090 } 091 092 protected String getReport() { 093 String report = reportBuf.toString(); 094 reportBuf.setLength(0); 095 return report; 096 } 097 } 098 099 // --------------------------------------------------------- Public Methods 100 101 102 /** 103 * Compile the servlet from .java file to .class file 104 */ 105 protected void generateClass(String[] smap) 106 throws FileNotFoundException, JasperException, Exception { 107 108 long t1=System.currentTimeMillis(); 109 String javaEncoding = ctxt.getOptions().getJavaEncoding(); 110 String javaFileName = ctxt.getServletJavaFileName(); 111 String classpath = ctxt.getClassPath(); 112 113 String sep = System.getProperty("path.separator"); 114 115 StringBuffer errorReport = new StringBuffer(); 116 117 StringBuffer info=new StringBuffer(); 118 info.append("Compile: javaFileName=" + javaFileName + "\n" ); 119 info.append(" classpath=" + classpath + "\n" ); 120 121 // Start capturing the System.err output for this thread 122 SystemLogHandler.setThread(); 123 124 // Initializing javac task 125 getProject(); 126 Javac javac = (Javac) project.createTask("javac"); 127 128 // Initializing classpath 129 Path path = new Path(project); 130 path.setPath(System.getProperty("java.class.path")); 131 info.append(" cp=" + System.getProperty("java.class.path") + "\n"); 132 StringTokenizer tokenizer = new StringTokenizer(classpath, sep); Rate133 while (tokenizer.hasMoreElements()) { 134 String pathElement = tokenizer.nextToken(); 135 File repository = new File(pathElement); 136 path.setLocation(repository); 137 info.append(" cp=" + repository + "\n"); 138 } 139 140 if( log.isDebugEnabled() ) 141 log.debug( "Using classpath: " + System.getProperty("java.class.path") + sep 142 + classpath); 143 144 // Initializing sourcepath 145 Path srcPath = new Path(project); 146 srcPath.setLocation(options.getScratchDir()); 147 148 info.append(" work dir=" + options.getScratchDir() + "\n"); 149 150 // Initialize and set java extensions 151 String exts = System.getProperty("java.ext.dirs"); 152 if (exts != null) { 153 Path extdirs = new Path(project); 154 extdirs.setPath(exts); 155 javac.setExtdirs(extdirs); 156 info.append(" extension dir=" + exts + "\n"); 157 } 158 159 // Configure the compiler object 160 javac.setEncoding(javaEncoding); 161 javac.setClasspath(path); 162 javac.setDebug(ctxt.getOptions().getClassDebugInfo()); 163 javac.setSrcdir(srcPath); 164 javac.setOptimize(! ctxt.getOptions().getClassDebugInfo() ); 165 javac.setFork(ctxt.getOptions().getFork()); 166 info.append(" srcDir=" + srcPath + "\n" ); 167 168 // Set the Java compiler to use 169 if (options.getCompiler() != null) { 170 javac.setCompiler(options.getCompiler()); 171 info.append(" compiler=" + options.getCompiler() + "\n"); 172 } 173 174 // Build includes path 175 PatternSet.NameEntry includes = javac.createInclude(); 176 177 includes.setName(ctxt.getJavaPath()); 178 info.append(" include="+ ctxt.getJavaPath() + "\n" ); 179 180 BuildException be = null; 181 182 try { 183 if (ctxt.getOptions().getFork()) { 184 javac.execute(); 185 } else { 186 synchronized(javacLock) { 187 javac.execute(); 188 } 189 } 190 } catch (BuildException e) { 191 be = e; 192 log.error( "Javac exception ", e); 193 log.error( "Env: " + info.toString()); 194 } 195 196 errorReport.append(logger.getReport()); 197 198 // Stop capturing the System.err output for this thread 199 String errorCapture = SystemLogHandler.unsetThread(); 200 if (errorCapture != null) { 201 errorReport.append(System.getProperty("line.separator")); 202 errorReport.append(errorCapture); 203 } 204 205 if (!ctxt.keepGenerated()) { 206 File javaFile = new File(javaFileName); 207 javaFile.delete(); 208 } 209 210 if (be != null) { 211 String errorReportString = errorReport.toString(); 212 log.error("Error compiling file: " + javaFileName + " " 213 + errorReportString); 214 JavacErrorDetail[] javacErrors = ErrorDispatcher.parseJavacErrors( 215 errorReportString, javaFileName, pageNodes); 216 if (javacErrors != null) { 217 errDispatcher.javacError(javacErrors); 218 } else { 219 errDispatcher.javacError(errorReportString, be); 220 } 221 } 222 223 long t2=System.currentTimeMillis(); 224 if( log.isDebugEnabled() ) { 225 log.debug( "Compiled " + ctxt.getServletJavaFileName() + " " + (t2-t1) + "ms"); 226 } 227 228 logger = null; 229 project = null; 230 231 if (ctxt.isPrototypeMode()) { 232 return; 233 } 234 235 // JSR45 Support 236 if (! options.isSmapSuppressed()) { 237 SmapUtil.installSmap(smap); 238 } 239 } 240 241 242 }