Project: ant4eclipse
/**********************************************************************
 * Copyright (c) 2005-2009 ant4eclipse project team. 
 * 
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 * 
 * Contributors: 
 *     Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich 
 **********************************************************************/
package org.ant4eclipse.lib.jdt.ecj.internal.tools; 
 
import org.ant4eclipse.lib.core.exception.Ant4EclipseException; 
import org.ant4eclipse.lib.core.logging.A4ELogging; 
import org.ant4eclipse.lib.core.util.Utilities; 
import org.ant4eclipse.lib.jdt.ecj.ReferableSourceFile; 
import org.ant4eclipse.lib.jdt.ecj.SourceFile; 
import org.eclipse.jdt.core.compiler.CategorizedProblem; 
import org.eclipse.jdt.internal.compiler.ClassFile; 
import org.eclipse.jdt.internal.compiler.CompilationResult; 
import org.eclipse.jdt.internal.compiler.ICompilerRequestor; 
 
import java.io.File; 
import java.util.Arrays; 
import java.util.Collections; 
import java.util.Hashtable; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 
 
/**
 * <p> 
 * Implements the call-back interface {@link ICompilerRequestor} for receiving compilation results. The 
 * {@link CompilerRequestorImpl} writes the compiled class files to disc or reports the errors in case the compilation 
 * was not successful. 
 * </p> 
 *  
 * @author Nils Hartmann ([email protected]
 */
 
public class CompilerRequestorImpl implements ICompilerRequestor { 
 
  /** indicates whether the compilation was successful or not */ 
  protected boolean                  _compilationSuccessful; 
 
  /** the list of categorized problems */ 
  protected List<CategorizedProblem> _categorizedProblems; 
 
  /** collection of class files which have been compiled */ 
  private Map<String, File>          _compiledClassFiles; 
 
  /**
   * <p> 
   * Creates a new instance of type {@link CompilerRequestorImpl}. 
   * </p> 
   */
 
  public CompilerRequestorImpl() { 
    this._compilationSuccessful = true
    this._categorizedProblems = new LinkedList<CategorizedProblem>(); 
    this._compiledClassFiles = new Hashtable<String, File>(); 
  } 
 
  /**
   * Returns a map for the compiled class files. 
   *  
   * @return A map for the compiled class files. Not <code>null</code>. 
   */
 
  public Map<String, File> getCompiledClassFiles() { 
    return Collections.unmodifiableMap(this._compiledClassFiles); 
  } 
 
  /**
   * {@inheritDoc} 
   */
 
  public void acceptResult(CompilationResult result) { 
 
    // get the compilation unit... 
    CompilationUnitImpl compilationUnitImpl = (CompilationUnitImpl) result.getCompilationUnit(); 
 
    // ...and the source file 
    SourceFile sourceFile = compilationUnitImpl.getSourceFile(); 
 
    // return immediately if the source file is a ReferableSourceFile 
    if (sourceFile instanceof ReferableSourceFile) { 
 
      // add the problems... 
      if (result.getAllProblems() != null) { 
        if (A4ELogging.isTraceingEnabled()) { 
          A4ELogging.trace("Could not compile referenced class '%s'. Reason: %s", sourceFile.getSourceFileName(), 
              Arrays.asList(result.getAllProblems())); 
        } 
      } 
 
      return
    } 
 
    // get the destination directory 
    File destinationDirectory = sourceFile.getDestinationFolder(); 
 
    if (!result.hasErrors()) { 
      ClassFile[] classFiles = result.getClassFiles(); 
      for (ClassFile classFile2 : classFiles) { 
        char[][] compoundName = classFile2.getCompoundName(); 
        StringBuffer classFileName = new StringBuffer(); 
        for (int j = 0; j < compoundName.length; j++) { 
          classFileName.append(compoundName[j]); 
          if (j < compoundName.length - 1) { 
            classFileName.append('/'); 
          } 
        } 
        classFileName.append(".class"); 
        File classFile = new File(destinationDirectory, classFileName.toString()); 
        File classDir = classFile.getParentFile(); 
        if (!classDir.exists()) { 
          classDir.mkdirs(); 
        } 
        try { 
          A4ELogging.debug("writing class file: '%s'", classFile); 
          Utilities.writeFile(classFile, classFile2.getBytes()); 
          this._compiledClassFiles.put(classFileName.toString(), classFile); 
        } catch (Ant4EclipseException ioe) { 
          A4ELogging.error("Could not write classfile '%s': %s", classFileName.toString(), ioe.toString()); 
          ioe.printStackTrace(); 
          this._compilationSuccessful = false
        } 
      } 
    } else { 
      this._compilationSuccessful = false
    } 
 
    // add the problems... 
    if (result.getAllProblems() != null) { 
      this._categorizedProblems.addAll(Arrays.asList(result.getAllProblems())); 
    } 
  } 
 
  /**
   * <p> 
   * Returns <code>true</code> if the compilation was successful, <code>false</code> otherwise. 
   * </p> 
   *  
   * @return <code>true</code> if the compilation was successful, <code>false</code> otherwise. 
   */
 
  public boolean isCompilationSuccessful() { 
    return this._compilationSuccessful; 
  } 
 
  /**
   * <p> 
   * Returns the categorized problems. 
   * </p> 
   *  
   * @return the categorized problems. 
   */
 
  public CategorizedProblem[] getCategorizedProblems() { 
    return this._categorizedProblems.toArray(new CategorizedProblem[0]); 
  } 
}