Save This Page
Home » apache-tomcat-6.0.26-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 if(opt.equals("1.6")) {
  304                   settings.put(CompilerOptions.OPTION_Source,
  305                                CompilerOptions.VERSION_1_6);
  306               } else if(opt.equals("1.7")) {
  307                   settings.put(CompilerOptions.OPTION_Source,
  308                                CompilerOptions.VERSION_1_7);
  309               } else {
  310                   log.warn("Unknown source VM " + opt + " ignored.");
  311                   settings.put(CompilerOptions.OPTION_Source,
  312                           CompilerOptions.VERSION_1_5);
  313               }
  314           } else {
  315               // Default to 1.5
  316               settings.put(CompilerOptions.OPTION_Source,
  317                       CompilerOptions.VERSION_1_5);
  318           }
  319           
  320           // Target JVM
  321           if(ctxt.getOptions().getCompilerTargetVM() != null) {
  322               String opt = ctxt.getOptions().getCompilerTargetVM();
  323               if(opt.equals("1.1")) {
  324                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  325                                CompilerOptions.VERSION_1_1);
  326               } else if(opt.equals("1.2")) {
  327                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  328                                CompilerOptions.VERSION_1_2);
  329               } else if(opt.equals("1.3")) { 
  330                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  331                                CompilerOptions.VERSION_1_3);
  332               } else if(opt.equals("1.4")) {
  333                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  334                                CompilerOptions.VERSION_1_4);
  335               } else if(opt.equals("1.5")) {
  336                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  337                                CompilerOptions.VERSION_1_5);
  338                   settings.put(CompilerOptions.OPTION_Compliance,
  339                           CompilerOptions.VERSION_1_5);
  340               } else if(opt.equals("1.6")) {
  341                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  342                                CompilerOptions.VERSION_1_6);
  343                   settings.put(CompilerOptions.OPTION_Compliance,
  344                           CompilerOptions.VERSION_1_6);
  345               } else if(opt.equals("1.7")) {
  346                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  347                                CompilerOptions.VERSION_1_7);
  348                   settings.put(CompilerOptions.OPTION_Compliance,
  349                           CompilerOptions.VERSION_1_7);
  350               } else {
  351                   log.warn("Unknown target VM " + opt + " ignored.");
  352                   settings.put(CompilerOptions.OPTION_TargetPlatform,
  353                           CompilerOptions.VERSION_1_5);
  354               }
  355           } else {
  356               // Default to 1.5
  357               settings.put(CompilerOptions.OPTION_TargetPlatform,
  358                       CompilerOptions.VERSION_1_5);
  359               settings.put(CompilerOptions.OPTION_Compliance,
  360                       CompilerOptions.VERSION_1_5);
  361           }
  362   
  363           final IProblemFactory problemFactory = 
  364               new DefaultProblemFactory(Locale.getDefault());
  365           
  366           final ICompilerRequestor requestor = new ICompilerRequestor() {
  367                   public void acceptResult(CompilationResult result) {
  368                       try {
  369                           if (result.hasProblems()) {
  370                               IProblem[] problems = result.getProblems();
  371                               for (int i = 0; i < problems.length; i++) {
  372                                   IProblem problem = problems[i];
  373                                   if (problem.isError()) {
  374                                       String name = 
  375                                           new String(problems[i].getOriginatingFileName());
  376                                       try {
  377                                           problemList.add(ErrorDispatcher.createJavacError
  378                                                   (name, pageNodes, new StringBuffer(problem.getMessage()), 
  379                                                           problem.getSourceLineNumber(), ctxt));
  380                                       } catch (JasperException e) {
  381                                           log.error("Error visiting node", e);
  382                                       }
  383                                   }
  384                               }
  385                           }
  386                           if (problemList.isEmpty()) {
  387                               ClassFile[] classFiles = result.getClassFiles();
  388                               for (int i = 0; i < classFiles.length; i++) {
  389                                   ClassFile classFile = classFiles[i];
  390                                   char[][] compoundName = 
  391                                       classFile.getCompoundName();
  392                                   String className = "";
  393                                   String sep = "";
  394                                   for (int j = 0; 
  395                                        j < compoundName.length; j++) {
  396                                       className += sep;
  397                                       className += new String(compoundName[j]);
  398                                       sep = ".";
  399                                   }
  400                                   byte[] bytes = classFile.getBytes();
  401                                   String outFile = outputDir + "/" + 
  402                                       className.replace('.', '/') + ".class";
  403                                   FileOutputStream fout = 
  404                                       new FileOutputStream(outFile);
  405                                   BufferedOutputStream bos = 
  406                                       new BufferedOutputStream(fout);
  407                                   bos.write(bytes);
  408                                   bos.close();
  409                               }
  410                           }
  411                       } catch (IOException exc) {
  412                           log.error("Compilation error", exc);
  413                       }
  414                   }
  415               };
  416   
  417           ICompilationUnit[] compilationUnits = 
  418               new ICompilationUnit[classNames.length];
  419           for (int i = 0; i < compilationUnits.length; i++) {
  420               String className = classNames[i];
  421               compilationUnits[i] = new CompilationUnit(fileNames[i], className);
  422           }
  423           Compiler compiler = new Compiler(env,
  424                                            policy,
  425                                            settings,
  426                                            requestor,
  427                                            problemFactory,
  428                                            true);
  429           compiler.compile(compilationUnits);
  430   
  431           if (!ctxt.keepGenerated()) {
  432               File javaFile = new File(ctxt.getServletJavaFileName());
  433               javaFile.delete();
  434           }
  435       
  436           if (!problemList.isEmpty()) {
  437               JavacErrorDetail[] jeds = 
  438                   (JavacErrorDetail[]) problemList.toArray(new JavacErrorDetail[0]);
  439               errDispatcher.javacError(jeds);
  440           }
  441           
  442           if( log.isDebugEnabled() ) {
  443               long t2=System.currentTimeMillis();
  444               log.debug("Compiled " + ctxt.getServletJavaFileName() + " "
  445                         + (t2-t1) + "ms");
  446           }
  447   
  448           if (ctxt.isPrototypeMode()) {
  449               return;
  450           }
  451   
  452           // JSR45 Support
  453           if (! options.isSmapSuppressed()) {
  454               SmapUtil.installSmap(smap);
  455           }
  456           
  457       }
  458       
  459       
  460   }

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