Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » jasper » compiler » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.jasper.compiler;
   19   
   20   import java.io.BufferedOutputStream;
   21   import java.io.BufferedReader;
   22   import java.io.ByteArrayOutputStream;
   23   import java.io.File;
   24   import java.io.FileInputStream;
   25   import java.io.FileNotFoundException;
   26   import java.io.FileOutputStream;
   27   import java.io.IOException;
   28   import java.io.InputStream;
   29   import java.io.InputStreamReader;
   30   import java.io.Reader;
   31   import java.util.ArrayList;
   32   import java.util.HashMap;
   33   import java.util.Locale;
   34   import java.util.Map;
   35   import java.util.StringTokenizer;
   36   
   37   import org.apache.jasper.JasperException;
   38   import org.eclipse.jdt.core.compiler.IProblem;
   39   import org.eclipse.jdt.internal.compiler.ClassFile;
   40   import org.eclipse.jdt.internal.compiler.CompilationResult;
   41   import org.eclipse.jdt.internal.compiler.Compiler;
   42   import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
   43   import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
   44   import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
   45   import org.eclipse.jdt.internal.compiler.IProblemFactory;
   46   import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
   47   import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
   48   import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
   49   import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
   50   import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
   51   import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
   52   
   53   /**
   54    * JDT class compiler. This compiler will load source dependencies from the
   55    * context classloader, reducing dramatically disk access during 
   56    * the compilation process.
   57    *
   58    * @author Cocoon2
   59    * @author Remy Maucherat
   60    */
   61   public class JDTCompiler extends org.apache.jasper.compiler.Compiler {
   62   
   63       
   64       /** 
   65        * Compile the servlet from .java file to .class file
   66        */
   67       protected void generateClass(String[] smap)
   68           throws FileNotFoundException, JasperException, Exception {
   69   
   70           long t1 = 0;
   71           if (log.isDebugEnabled()) {
   72               t1 = System.currentTimeMillis();
   73           }
   74           
   75           final String sourceFile = ctxt.getServletJavaFileName();
   76           final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
   77           String packageName = ctxt.getServletPackageName();
   78           final String targetClassName = 
   79               ((packageName.length() != 0) ? (packageName + ".") : "") 
   80                       + ctxt.getServletClassName();
   81           final ClassLoader classLoader = ctxt.getJspLoader();
   82           String[] fileNames = new String[] {sourceFile};
   83           String[] classNames = new String[] {targetClassName};
   84           final ArrayList problemList = new ArrayList();
   85           
   86           class CompilationUnit implements ICompilationUnit {
   87   
   88               String className;
   89               String sourceFile;
   90   
   91               CompilationUnit(String sourceFile, String className) {
   92                   this.className = className;
   93                   this.sourceFile = sourceFile;
   94               }
   95   
   96               public char[] getFileName() {
   97                   return sourceFile.toCharArray();
   98               }
   99               
  100               public char[] getContents() {
  101                   char[] result = null;
  102                   FileInputStream is = null;
  103                   try {
  104                       is = new FileInputStream(sourceFile);
  105                       Reader reader = 
  106                           new BufferedReader(new InputStreamReader(is, ctxt.getOptions().getJavaEncoding()));
  107                       if (reader != null) {
  108                           char[] chars = new char[8192];
  109                           StringBuffer buf = new StringBuffer();
  110                           int count;
  111                           while ((count = reader.read(chars, 0, 
  112                                                       chars.length)) > 0) {
  113                               buf.append(chars, 0, count);
  114                           }
  115                           result = new char[buf.length()];
  116                           buf.getChars(0, result.length, result, 0);
  117                       }
  118                   } catch (IOException e) {
  119                       log.error("Compilation error", e);
  120                   } finally {
  121                       if (is != null) {
  122                           try {
  123                               is.close();
  124                           } catch (IOException exc) {
  125                               // Ignore
  126                           }
  127                       }
  128                   }
  129                   return result;
  130               }
  131               
  132               public char[] getMainTypeName() {
  133                   int dot = className.lastIndexOf('.');
  134                   if (dot > 0) {
  135                       return className.substring(dot + 1).toCharArray();
  136                   }
  137                   return className.toCharArray();
  138               }
  139               
  140               public char[][] getPackageName() {
  141                   StringTokenizer izer = 
  142                       new StringTokenizer(className, ".");
  143                   char[][] result = new char[izer.countTokens()-1][];
  144                   for (int i = 0; i < result.length; i++) {
  145                       String tok = izer.nextToken();
  146                       result[i] = tok.toCharArray();
  147                   }
  148                   return result;
  149               }
  150           }
  151   
  152           final INameEnvironment env = new INameEnvironment() {
  153   
  154                   public NameEnvironmentAnswer 
  155                       findType(char[][] compoundTypeName) {
  156                       String result = "";
  157                       String sep = "";
  158                       for (int i = 0; i < compoundTypeName.length; i++) {
  159                           result += sep;
  160                           result += new String(compoundTypeName[i]);
  161                           sep = ".";
  162                       }
  163                       return findType(result);
  164                   }
  165   
  166                   public NameEnvironmentAnswer 
  167                       findType(char[] typeName, 
  168                                char[][] packageName) {
  169                           String result = "";
  170                           String sep = "";
  171                           for (int i = 0; i < packageName.length; i++) {
  172                               result += sep;
  173                               result += new String(packageName[i]);
  174                               sep = ".";
  175                           }
  176                           result += sep;
  177                           result += new String(typeName);
  178                           return findType(result);
  179                   }
  180                   
  181                   private NameEnvironmentAnswer findType(String className) {
  182   
  183                       InputStream is = null;
  184                       try {
  185                           if (className.equals(targetClassName)) {
  186                               ICompilationUnit compilationUnit = 
  187                                   new CompilationUnit(sourceFile, className);
  188                               return 
  189                                   new NameEnvironmentAnswer(compilationUnit, null);
  190                           }
  191                           String resourceName = 
  192                               className.replace('.', '/') + ".class";
  193                           is = classLoader.getResourceAsStream(resourceName);
  194                           if (is != null) {
  195                               byte[] classBytes;
  196                               byte[] buf = new byte[8192];
  197                               ByteArrayOutputStream baos = 
  198                                   new ByteArrayOutputStream(buf.length);
  199                               int count;
  200                               while ((count = is.read(buf, 0, buf.length)) > 0) {
  201                                   baos.write(buf, 0, count);
  202                               }
  203                               baos.flush();
  204                               classBytes = baos.toByteArray();
  205                               char[] fileName = className.toCharArray();
  206                               ClassFileReader classFileReader = 
  207                                   new ClassFileReader(classBytes, fileName, 
  208                                                       true);
  209                               return 
  210                                   new NameEnvironmentAnswer(classFileReader, null);
  211                           }
  212                       } catch (IOException exc) {
  213                           log.error("Compilation error", exc);
  214                       } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException exc) {
  215                           log.error("Compilation error", exc);
  216                       } finally {
  217                           if (is != null) {
  218                               try {
  219                                   is.close();
  220                               } catch (IOException exc) {
  221                                   // Ignore
  222                               }
  223                           }
  224                       }
  225                       return null;
  226                   }
  227   
  228                   private boolean isPackage(String result) {
  229                       if (result.equals(targetClassName)) {
  230                           return false;
  231                       }
  232                       String resourceName = result.replace('.', '/') + ".class";
  233                       InputStream is = 
  234                           classLoader.getResourceAsStream(resourceName);
  235                       return is == null;
  236                   }
  237   
  238                   public boolean isPackage(char[][] parentPackageName, 
  239                                            char[] packageName) {
  240                       String result = "";
  241                       String sep = "";
  242                       if (parentPackageName != null) {
  243                           for (int i = 0; i < parentPackageName.length; i++) {
  244                               result += sep;
  245                               String str = new String(parentPackageName[i]);
  246                               result += str;
  247                               sep = ".";
  248                           }
  249                       }
  250                       String str = new String(packageName);
  251                       if (Character.isUpperCase(str.charAt(0))) {
  252                           if (!isPackage(result)) {
  253                               return false;
  254                           }
  255                       }
  256                       result += sep;
  257                       result += str;
  258                       return isPackage(result);
  259                   }
  260   
  261                   public void cleanup() {
  262                   }
  263   
  264               };
  265   
  266           final IErrorHandlingPolicy policy = 
  267               DefaultErrorHandlingPolicies.proceedWithAllProblems();
  268   
  269           final Map settings = new HashMap();
  270           settings.put(CompilerOptions.OPTION_LineNumberAttribute,
  271                        CompilerOptions.GENERATE);
  272           settings.put(CompilerOptions.OPTION_SourceFileAttribute,
  273                        CompilerOptions.GENERATE);
  274           settings.put(CompilerOptions.OPTION_ReportDeprecation,
  275                        CompilerOptions.IGNORE);
  276           if (ctxt.getOptions().getJavaEncoding() != null) {
  277               settings.put(CompilerOptions.OPTION_Encoding,
  278                       ctxt.getOptions().getJavaEncoding());
  279           }
  280           if (ctxt.getOptions().getClassDebugInfo()) {
  281               settings.put(CompilerOptions.OPTION_LocalVariableAttribute,
  282                            CompilerOptions.GENERATE);
  283           }
  284   
  285           // Source JVM
  286           if(ctxt.getOptions().getCompilerSourceVM() != null) {
  287               String opt = ctxt.getOptions().getCompilerSourceVM();
  288               if(opt.equals("1.1")) {
  289                   settings.put(CompilerOptions.OPTION_Source,
  290                                CompilerOptions.VERSION_1_1);
  291               } else if(opt.equals("1.2")) {
  292                   settings.put(CompilerOptions.OPTION_Source,
  293                                CompilerOptions.VERSION_1_2);
  294               } else if(opt.equals("1.3")) { 
  295                   settings.put(CompilerOptions.OPTION_Source,
  296                                CompilerOptions.VERSION_1_3);
  297               } else if(opt.equals("1.4")) {
  298                   settings.put(CompilerOptions.OPTION_Source,
  299                                CompilerOptions.VERSION_1_4);
  300               } else if(opt.equals("1.5")) {
  301                   settings.put(CompilerOptions.OPTION_Source,
  302                                CompilerOptions.VERSION_1_5);
  303               } else {
  304                   log.warn("Unknown source VM " + opt + " ignored.");
  305                   settings.put(CompilerOptions.OPTION_Source,
  306                           CompilerOptions.VERSION_1_5);
  307               }
  308           } else {
  309               // Default to 1.5
  310               settings.put(CompilerOptions.OPTION_Source,
  311                       CompilerOptions.VERSION_1_5);
  312           }
  313           
  314           // Target JVM
  315           if(ctxt.getOptions().getCompilerTargetVM() != null) {
  316               String opt = ctxt.getOptions().getCompilerTargetVM();
  317               if(opt.equals("1.1")) {
  318                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  319                                CompilerOptions.VERSION_1_1);
  320               } else if(opt.equals("1.2")) {
  321                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  322                                CompilerOptions.VERSION_1_2);
  323               } else if(opt.equals("1.3")) { 
  324                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  325                                CompilerOptions.VERSION_1_3);
  326               } else if(opt.equals("1.4")) {
  327                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  328                                CompilerOptions.VERSION_1_4);
  329               } else if(opt.equals("1.5")) {
  330                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  331                                CompilerOptions.VERSION_1_5);
  332                   settings.put(CompilerOptions.OPTION_Compliance,
  333                           CompilerOptions.VERSION_1_5);
  334               } else {
  335                   log.warn("Unknown target VM " + opt + " ignored.");
  336                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  337                           CompilerOptions.VERSION_1_5);
  338               }
  339           } else {
  340               // Default to 1.5
  341               settings.put(CompilerOptions.OPTION_TargetPlatform,
  342                       CompilerOptions.VERSION_1_5);
  343               settings.put(CompilerOptions.OPTION_Compliance,
  344                       CompilerOptions.VERSION_1_5);
  345           }
  346   
  347           final IProblemFactory problemFactory = 
  348               new DefaultProblemFactory(Locale.getDefault());
  349           
  350           final ICompilerRequestor requestor = new ICompilerRequestor() {
  351                   public void acceptResult(CompilationResult result) {
  352                       try {
  353                           if (result.hasProblems()) {
  354                               IProblem[] problems = result.getProblems();
  355                               for (int i = 0; i < problems.length; i++) {
  356                                   IProblem problem = problems[i];
  357                                   if (problem.isError()) {
  358                                       String name = 
  359                                           new String(problems[i].getOriginatingFileName());
  360                                       try {
  361                                           problemList.add(ErrorDispatcher.createJavacError
  362                                                   (name, pageNodes, new StringBuffer(problem.getMessage()), 
  363                                                           problem.getSourceLineNumber(), ctxt));
  364                                       } catch (JasperException e) {
  365                                           log.error("Error visiting node", e);
  366                                       }
  367                                   }
  368                               }
  369                           }
  370                           if (problemList.isEmpty()) {
  371                               ClassFile[] classFiles = result.getClassFiles();
  372                               for (int i = 0; i < classFiles.length; i++) {
  373                                   ClassFile classFile = classFiles[i];
  374                                   char[][] compoundName = 
  375                                       classFile.getCompoundName();
  376                                   String className = "";
  377                                   String sep = "";
  378                                   for (int j = 0; 
  379                                        j < compoundName.length; j++) {
  380                                       className += sep;
  381                                       className += new String(compoundName[j]);
  382                                       sep = ".";
  383                                   }
  384                                   byte[] bytes = classFile.getBytes();
  385                                   String outFile = outputDir + "/" + 
  386                                       className.replace('.', '/') + ".class";
  387                                   FileOutputStream fout = 
  388                                       new FileOutputStream(outFile);
  389                                   BufferedOutputStream bos = 
  390                                       new BufferedOutputStream(fout);
  391                                   bos.write(bytes);
  392                                   bos.close();
  393                               }
  394                           }
  395                       } catch (IOException exc) {
  396                           log.error("Compilation error", exc);
  397                       }
  398                   }
  399               };
  400   
  401           ICompilationUnit[] compilationUnits = 
  402               new ICompilationUnit[classNames.length];
  403           for (int i = 0; i < compilationUnits.length; i++) {
  404               String className = classNames[i];
  405               compilationUnits[i] = new CompilationUnit(fileNames[i], className);
  406           }
  407           Compiler compiler = new Compiler(env,
  408                                            policy,
  409                                            settings,
  410                                            requestor,
  411                                            problemFactory,
  412                                            true);
  413           compiler.compile(compilationUnits);
  414   
  415           if (!ctxt.keepGenerated()) {
  416               File javaFile = new File(ctxt.getServletJavaFileName());
  417               javaFile.delete();
  418           }
  419       
  420           if (!problemList.isEmpty()) {
  421               JavacErrorDetail[] jeds = 
  422                   (JavacErrorDetail[]) problemList.toArray(new JavacErrorDetail[0]);
  423               errDispatcher.javacError(jeds);
  424           }
  425           
  426           if( log.isDebugEnabled() ) {
  427               long t2=System.currentTimeMillis();
  428               log.debug("Compiled " + ctxt.getServletJavaFileName() + " "
  429                         + (t2-t1) + "ms");
  430           }
  431   
  432           if (ctxt.isPrototypeMode()) {
  433               return;
  434           }
  435   
  436           // JSR45 Support
  437           if (! options.isSmapSuppressed()) {
  438               SmapUtil.installSmap(smap);
  439           }
  440           
  441       }
  442       
  443       
  444   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » jasper » compiler » [javadoc | source]