/********************************************************************** * 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.ant.jdt; import java.io.File; import java.lang.reflect.Method; import org.ant4eclipse.ant.jdt.ecj.A4ECompilerAdapter; import org.ant4eclipse.ant.jdt.ecj.EcjCompilerAdapter; import org.ant4eclipse.ant.jdt.ecj.JavacCompilerAdapter; import org.ant4eclipse.lib.core.logging.A4ELogging; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.Javac; import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter; /** * <p> * This task is an extension to the Javac compiler task which makes use of the {@link EcjCompilerAdapter}. The most * important advantage is that the compiler implementation is provided using the classloader of the a4e package which * means that the package itself is not required to be provided together with the ant distribution. * </p> * * @author Daniel Kasmeroglu (Daniel.Kasmeroglu@Kasisoft.net) */ public class JdtCompilerTask extends Javac { private static final String MSG_INVALID_ATTRIBUTE = "The attribute 'compiler' for the task '%s' is not allowed to be used."; private static final String MSG_FAILURE = "The compilation failed. Check the output for more information."; private String _errprop = null; private String _updateprop = null; private boolean _useecj = true; private boolean _warnings = true; /** * The CompilerAdapter for this compilation */ private A4ECompilerAdapter _a4eCompilerAdapter; /** * Enables/disables the generation of warn messages. * * @param enable * <code>true</code> <=> Generate warn messages. */ public void setWarnings(boolean enable) { this._warnings = enable; } /** * Enables/disables the use of the ecj compiler. * * @param enable * <code>true</code> <=> Enables the use of the ecj compiler. */ public void setUseecj(boolean enable) { this._useecj = enable; } /** * As we're responsible for the compilation we're handling the property values as well. * * {@inheritDoc} */ @Override public void setErrorProperty(String prop) { this._errprop = prop; } /** * As we're responsible for the compilation we're handling the property values as well. * * {@inheritDoc} */ @Override public void setUpdatedProperty(String prop) { this._updateprop = prop; } /** * <p> * Returns a CompilerAdapter instance used for the compilation process. Everything would be much easier if the Ant * developers would have provided such a method in the first place. * </p> * * @return The CompilerAdapter instance used for the compilation process. Not <code>null</code>. */ protected CompilerAdapter getOrCreateCompilerAdapter() { if (this._a4eCompilerAdapter == null) { if (this._useecj) { this._a4eCompilerAdapter = new EcjCompilerAdapter(); } else { this._a4eCompilerAdapter = new JavacCompilerAdapter(); } this._a4eCompilerAdapter.setWarnings(this._warnings); } return this._a4eCompilerAdapter; } /** * {@inheritDoc} */ @Override protected void compile() { File destdir = super.getDestdir(); if (this.compileList.length > 0) { File current = new File("."); String dest = destdir != null ? String.valueOf(destdir) : String.valueOf(current); if (this.compileList.length == 1) { A4ELogging.info("Compiling 1 source file '%s' to '%s' !", this.compileList[0], dest); } else { A4ELogging.info("Compiling %d source files to '%s' !", Integer.valueOf(this.compileList.length), dest); } if (this.listFiles) { for (File element : this.compileList) { A4ELogging.info("\t%s", element.getAbsolutePath()); } } // obtain an adapter used to run the compilation process CompilerAdapter adapter = getOrCreateCompilerAdapter(); adapter.setJavac(this); // launch the compilation process if (adapter.execute()) { // everything went fine, so we can mark this using a proeprty if desired if (this._updateprop != null) { getProject().setNewProperty(this._updateprop, "true"); } } else { // damn it. we need to mark the error. if (this._errprop != null) { getProject().setNewProperty(this._errprop, "true"); } if (this.failOnError) { throw new BuildException(MSG_FAILURE, getLocation()); } else { A4ELogging.error(MSG_FAILURE); } } } } /** * {@inheritDoc} */ @Override public void setCompiler(String compiler) { A4ELogging.error(MSG_INVALID_ATTRIBUTE, getTaskName()); } /** * {@inheritDoc} */ @Override public void execute() throws BuildException { super.setCompiler(EcjCompilerAdapter.class.getName()); super.setIncludeantruntime(false); // Set Compiler Adapter (only if Ant >= 1.8.0); try { Method addAdapterMethod = getClass().getMethod("add", CompilerAdapter.class); addAdapterMethod.invoke(this, getOrCreateCompilerAdapter()); } catch (Exception ex) { // ignore } super.execute(); } } /* ENDCLASS */