protected String compileUnits(
      final JRCompilationUnit[] units, String classpath, File tempDirFile) {
    final StringBuffer problemBuffer = new StringBuffer();

    INameEnvironment env = getNameEnvironment(units);

    final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems();

    final Map settings = getJdtSettings();

    final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());

    final ICompilerRequestor requestor = getCompilerRequestor(units, problemBuffer);

    ICompilationUnit[] compilationUnits = new ICompilationUnit[units.length];
    for (int i = 0; i < compilationUnits.length; i++) {
      compilationUnits[i] = new CompilationUnit(units[i].getSourceCode(), units[i].getName());
    }

    Compiler compiler = new Compiler(env, policy, settings, requestor, problemFactory);
    compiler.compile(compilationUnits);

    if (problemBuffer.length() > 0) {
      return problemBuffer.toString();
    }

    return null;
  }
Exemple #2
0
  protected Class<?> compile(String className, char[] source) {
    if (source == null) {
      source = findSource(className);
    }

    if (source != null) {
      if (compiler == null) {
        compiler =
            new Compiler(
                getNameEnvironment(),
                getErrorHandlingPolicy(),
                getCompilerOptions(),
                getCompileRequestor(),
                getProblemFactory());
      }

      ICompilationUnit[] units = new CompilationUnit[1];
      units[0] = new CompilationUnit(source, className, null);
      compiler.compile(units);
      if (hasErrors()) {
        StringBuilder sb = new StringBuilder();
        try {
          writeProblemLog(sb);
        } catch (IOException e) {
          db.p(e);
        } finally {
          clearProblems();
        }
        throw new CompileException(sb.toString());
      }
    }
    return getCachedClass(className);
  }
Exemple #3
0
  /**
   * General API -> compile each of supplied files -> recompile any required types for which we have
   * an incomplete principle structure
   */
  public void compile(ICompilationUnit[] sourceUnits) {
    this.stats.startTime = System.currentTimeMillis();
    // GROOVY start
    // sort the sourceUnits - java first! might be temporary, hmmm
    if (this.options.buildGroovyFiles == 2) {
      int groovyFileIndex = -1;
      //			System.out.println("before");
      //			for (int u=0,max=sourceUnits.length;u<max;u++) {
      //				System.out.println(sourceUnits[u].getFileName());
      //			}
      for (int u = 0, max = sourceUnits.length; u < max; u++) {
        char[] fn = sourceUnits[u].getFileName();
        boolean isDotJava = fn[fn.length - 1] == 'a'; // a means .java
        if (isDotJava) {
          if (groovyFileIndex != -1) {
            // swap them!
            ICompilationUnit swap = sourceUnits[groovyFileIndex];
            sourceUnits[groovyFileIndex] = sourceUnits[u];
            sourceUnits[u] = swap;
            // find the next .groovy file after the groovyFileIndex (worst case it will be 'u')
            int newGroovyFileIndex = -1;
            for (int g = groovyFileIndex; g <= u; g++) {
              char[] fn2 = sourceUnits[g].getFileName();
              boolean isDotGroovy = fn2[fn2.length - 1] == 'm'; // ZALUUM
              if (isDotGroovy) {
                newGroovyFileIndex = g;
                break;
              }
            }
            groovyFileIndex = newGroovyFileIndex;
          }
        } else {
          if (groovyFileIndex == -1) {
            groovyFileIndex = u;
          }
        }
      }
      //			System.out.println("after");
      //			for (int u=0,max=sourceUnits.length;u<max;u++) {
      //				System.out.println(sourceUnits[u].getFileName());
      //			}
    }
    // GROOVY end
    CompilationUnitDeclaration unit = null;
    ProcessTaskManager processingTask = null;
    try {
      // build and record parsed units
      reportProgress(Messages.compilation_beginningToCompile);

      if (this.annotationProcessorManager == null) {
        beginToCompile(sourceUnits);
      } else {
        ICompilationUnit[] originalUnits =
            (ICompilationUnit[])
                sourceUnits.clone(); // remember source units in case a source type collision occurs
        try {
          beginToCompile(sourceUnits);

          processAnnotations();
          if (!this.options.generateClassFiles) {
            // -proc:only was set on the command line
            return;
          }
        } catch (SourceTypeCollisionException e) {
          reset();
          // a generated type was referenced before it was created
          // the compiler either created a MissingType or found a BinaryType for it
          // so add the processor's generated files & start over,
          // but remember to only pass the generated files to the annotation processor
          int originalLength = originalUnits.length;
          int newProcessedLength = e.newAnnotationProcessorUnits.length;
          ICompilationUnit[] combinedUnits =
              new ICompilationUnit[originalLength + newProcessedLength];
          System.arraycopy(originalUnits, 0, combinedUnits, 0, originalLength);
          System.arraycopy(
              e.newAnnotationProcessorUnits, 0, combinedUnits, originalLength, newProcessedLength);
          this.annotationProcessorStartIndex = originalLength;
          compile(combinedUnits);
          return;
        }
      }

      if (this.useSingleThread) {
        // process all units (some more could be injected in the loop by the lookup environment)
        for (int i = 0; i < this.totalUnits; i++) {
          unit = this.unitsToProcess[i];
          reportProgress(
              Messages.bind(Messages.compilation_processing, new String(unit.getFileName())));
          try {
            if (this.options.verbose)
              this.out.println(
                  Messages.bind(
                      Messages.compilation_process,
                      new String[] {
                        String.valueOf(i + 1),
                        String.valueOf(this.totalUnits),
                        new String(this.unitsToProcess[i].getFileName())
                      }));
            process(unit, i);
          } finally {
            // cleanup compilation unit result
            unit.cleanUp();
          }
          this.unitsToProcess[i] = null; // release reference to processed unit declaration

          reportWorked(1, i);
          this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
          long acceptStart = System.currentTimeMillis();
          this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
          this.stats.generateTime +=
              System.currentTimeMillis() - acceptStart; // record accept time as part of generation
          if (this.options.verbose)
            this.out.println(
                Messages.bind(
                    Messages.compilation_done,
                    new String[] {
                      String.valueOf(i + 1),
                      String.valueOf(this.totalUnits),
                      new String(unit.getFileName())
                    }));
        }
      } else {
        processingTask = new ProcessTaskManager(this);
        int acceptedCount = 0;
        // process all units (some more could be injected in the loop by the lookup environment)
        // the processTask can continue to process units until its fixed sized cache is full then it
        // must wait
        // for this this thread to accept the units as they appear (it only waits if no units are
        // available)
        while (true) {
          try {
            unit = processingTask.removeNextUnit(); // waits if no units are in the processed queue
          } catch (Error e) {
            unit = processingTask.unitToProcess;
            throw e;
          } catch (RuntimeException e) {
            unit = processingTask.unitToProcess;
            throw e;
          }
          if (unit == null) break;
          reportWorked(1, acceptedCount++);
          this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
          this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
          if (this.options.verbose)
            this.out.println(
                Messages.bind(
                    Messages.compilation_done,
                    new String[] {
                      String.valueOf(acceptedCount),
                      String.valueOf(this.totalUnits),
                      new String(unit.getFileName())
                    }));
        }
      }
    } catch (AbortCompilation e) {
      this.handleInternalException(e, unit);
    } catch (Error e) {
      this.handleInternalException(e, unit, null);
      throw e; // rethrow
    } catch (RuntimeException e) {
      this.handleInternalException(e, unit, null);
      throw e; // rethrow
    } finally {
      if (processingTask != null) {
        processingTask.shutdown();
        processingTask = null;
      }
      reset();
      this.annotationProcessorStartIndex = 0;
      this.stats.endTime = System.currentTimeMillis();
    }
    if (this.options.verbose) {
      if (this.totalUnits > 1) {
        this.out.println(
            Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits)));
      } else {
        this.out.println(Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits)));
      }
    }
  }
  /** Compile the servlet from .java file to .class file */
  protected void generateClass(String[] smap)
      throws FileNotFoundException, JasperException, Exception {

    long t1 = 0;
    if (log.isDebugEnabled()) {
      t1 = System.currentTimeMillis();
    }

    final String sourceFile = ctxt.getServletJavaFileName();
    final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
    String packageName = ctxt.getServletPackageName();
    final String targetClassName =
        ((packageName.length() != 0) ? (packageName + ".") : "") + ctxt.getServletClassName();
    final ClassLoader classLoader = ctxt.getJspLoader();
    String[] fileNames = new String[] {sourceFile};
    String[] classNames = new String[] {targetClassName};
    final ArrayList problemList = new ArrayList();

    class CompilationUnit implements ICompilationUnit {

      String className;
      String sourceFile;

      CompilationUnit(String sourceFile, String className) {
        this.className = className;
        this.sourceFile = sourceFile;
      }

      public char[] getFileName() {
        return sourceFile.toCharArray();
      }

      public char[] getContents() {
        char[] result = null;
        FileInputStream is = null;
        try {
          is = new FileInputStream(sourceFile);
          Reader reader =
              new BufferedReader(new InputStreamReader(is, ctxt.getOptions().getJavaEncoding()));
          if (reader != null) {
            char[] chars = new char[8192];
            StringBuffer buf = new StringBuffer();
            int count;
            while ((count = reader.read(chars, 0, chars.length)) > 0) {
              buf.append(chars, 0, count);
            }
            result = new char[buf.length()];
            buf.getChars(0, result.length, result, 0);
          }
        } catch (IOException e) {
          log.error("Compilation error", e);
        } finally {
          if (is != null) {
            try {
              is.close();
            } catch (IOException exc) {
              // Ignore
            }
          }
        }
        return result;
      }

      public char[] getMainTypeName() {
        int dot = className.lastIndexOf('.');
        if (dot > 0) {
          return className.substring(dot + 1).toCharArray();
        }
        return className.toCharArray();
      }

      public char[][] getPackageName() {
        StringTokenizer izer = new StringTokenizer(className, ".");
        char[][] result = new char[izer.countTokens() - 1][];
        for (int i = 0; i < result.length; i++) {
          String tok = izer.nextToken();
          result[i] = tok.toCharArray();
        }
        return result;
      }

      public boolean ignoreOptionalProblems() {
        return false;
      }
    }

    final INameEnvironment env =
        new INameEnvironment() {

          public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
            String result = "";
            String sep = "";
            for (int i = 0; i < compoundTypeName.length; i++) {
              result += sep;
              result += new String(compoundTypeName[i]);
              sep = ".";
            }
            return findType(result);
          }

          public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
            String result = "";
            String sep = "";
            for (int i = 0; i < packageName.length; i++) {
              result += sep;
              result += new String(packageName[i]);
              sep = ".";
            }
            result += sep;
            result += new String(typeName);
            return findType(result);
          }

          private NameEnvironmentAnswer findType(String className) {

            InputStream is = null;
            try {
              if (className.equals(targetClassName)) {
                ICompilationUnit compilationUnit = new CompilationUnit(sourceFile, className);
                return new NameEnvironmentAnswer(compilationUnit, null);
              }
              String resourceName = className.replace('.', '/') + ".class";
              is = classLoader.getResourceAsStream(resourceName);
              if (is != null) {
                byte[] classBytes;
                byte[] buf = new byte[8192];
                ByteArrayOutputStream baos = new ByteArrayOutputStream(buf.length);
                int count;
                while ((count = is.read(buf, 0, buf.length)) > 0) {
                  baos.write(buf, 0, count);
                }
                baos.flush();
                classBytes = baos.toByteArray();
                char[] fileName = className.toCharArray();
                ClassFileReader classFileReader = new ClassFileReader(classBytes, fileName, true);
                return new NameEnvironmentAnswer(classFileReader, null);
              }
            } catch (IOException exc) {
              log.error("Compilation error", exc);
            } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException exc) {
              log.error("Compilation error", exc);
            } finally {
              if (is != null) {
                try {
                  is.close();
                } catch (IOException exc) {
                  // Ignore
                }
              }
            }
            return null;
          }

          private boolean isPackage(String result) {
            if (result.equals(targetClassName)) {
              return false;
            }
            String resourceName = result.replace('.', '/') + ".class";
            InputStream is = classLoader.getResourceAsStream(resourceName);
            return is == null;
          }

          public boolean isPackage(char[][] parentPackageName, char[] packageName) {
            String result = "";
            String sep = "";
            if (parentPackageName != null) {
              for (int i = 0; i < parentPackageName.length; i++) {
                result += sep;
                String str = new String(parentPackageName[i]);
                result += str;
                sep = ".";
              }
            }
            String str = new String(packageName);
            if (Character.isUpperCase(str.charAt(0))) {
              if (!isPackage(result)) {
                return false;
              }
            }
            result += sep;
            result += str;
            return isPackage(result);
          }

          public void cleanup() {}
        };

    final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems();

    final Map settings = new HashMap();
    settings.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
    settings.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE);
    settings.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
    if (ctxt.getOptions().getJavaEncoding() != null) {
      settings.put(CompilerOptions.OPTION_Encoding, ctxt.getOptions().getJavaEncoding());
    }
    if (ctxt.getOptions().getClassDebugInfo()) {
      settings.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
    }

    // Source JVM
    if (ctxt.getOptions().getCompilerSourceVM() != null) {
      String opt = ctxt.getOptions().getCompilerSourceVM();
      if (opt.equals("1.1")) {
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_1);
      } else if (opt.equals("1.2")) {
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_2);
      } else if (opt.equals("1.3")) {
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
      } else if (opt.equals("1.4")) {
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
      } else if (opt.equals("1.5")) {
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
      } else if (opt.equals("1.6")) {
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
      } else if (opt.equals("1.7")) {
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
      } else {
        log.warn("Unknown source VM " + opt + " ignored.");
        settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
      }
    } else {
      // Default to 1.5
      settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
    }

    // Target JVM
    if (ctxt.getOptions().getCompilerTargetVM() != null) {
      String opt = ctxt.getOptions().getCompilerTargetVM();
      if (opt.equals("1.1")) {
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
      } else if (opt.equals("1.2")) {
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
      } else if (opt.equals("1.3")) {
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
      } else if (opt.equals("1.4")) {
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
      } else if (opt.equals("1.5")) {
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
        settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
      } else if (opt.equals("1.6")) {
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
        settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
      } else if (opt.equals("1.7")) {
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
        settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
      } else {
        log.warn("Unknown target VM " + opt + " ignored.");
        settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
      }
    } else {
      // Default to 1.5
      settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
      settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
    }

    final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());

    final ICompilerRequestor requestor =
        new ICompilerRequestor() {
          public void acceptResult(CompilationResult result) {
            try {
              if (result.hasProblems()) {
                IProblem[] problems = result.getProblems();
                for (int i = 0; i < problems.length; i++) {
                  IProblem problem = problems[i];
                  if (problem.isError()) {
                    String name = new String(problems[i].getOriginatingFileName());
                    try {
                      problemList.add(
                          ErrorDispatcher.createJavacError(
                              name,
                              pageNodes,
                              new StringBuffer(problem.getMessage()),
                              problem.getSourceLineNumber(),
                              ctxt));
                    } catch (JasperException e) {
                      log.error("Error visiting node", e);
                    }
                  }
                }
              }
              if (problemList.isEmpty()) {
                ClassFile[] classFiles = result.getClassFiles();
                for (int i = 0; i < classFiles.length; i++) {
                  ClassFile classFile = classFiles[i];
                  char[][] compoundName = classFile.getCompoundName();
                  String className = "";
                  String sep = "";
                  for (int j = 0; j < compoundName.length; j++) {
                    className += sep;
                    className += new String(compoundName[j]);
                    sep = ".";
                  }
                  byte[] bytes = classFile.getBytes();
                  String outFile = outputDir + "/" + className.replace('.', '/') + ".class";
                  FileOutputStream fout = new FileOutputStream(outFile);
                  BufferedOutputStream bos = new BufferedOutputStream(fout);
                  bos.write(bytes);
                  bos.close();
                }
              }
            } catch (IOException exc) {
              log.error("Compilation error", exc);
            }
          }
        };

    ICompilationUnit[] compilationUnits = new ICompilationUnit[classNames.length];
    for (int i = 0; i < compilationUnits.length; i++) {
      String className = classNames[i];
      compilationUnits[i] = new CompilationUnit(fileNames[i], className);
    }
    Compiler compiler = new Compiler(env, policy, settings, requestor, problemFactory, true);
    compiler.compile(compilationUnits);

    if (!ctxt.keepGenerated()) {
      File javaFile = new File(ctxt.getServletJavaFileName());
      javaFile.delete();
    }

    if (!problemList.isEmpty()) {
      JavacErrorDetail[] jeds = (JavacErrorDetail[]) problemList.toArray(new JavacErrorDetail[0]);
      errDispatcher.javacError(jeds);
    }

    if (log.isDebugEnabled()) {
      long t2 = System.currentTimeMillis();
      log.debug("Compiled " + ctxt.getServletJavaFileName() + " " + (t2 - t1) + "ms");
    }

    if (ctxt.isPrototypeMode()) {
      return;
    }

    // JSR45 Support
    if (!options.isSmapSuppressed()) {
      SmapUtil.installSmap(smap);
    }
  }