All Downloads are FREE. Search and download functionalities are using the official Maven repository.

protoj.lang.CompileFeature Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2009 Ashley Williams
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package protoj.lang;

import java.io.File;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.DirSet;
import org.apache.tools.ant.types.FileSet;

import protoj.lang.internal.InformationException;
import protoj.util.AntTarget;
import protoj.util.ArgRunnable;
import protoj.util.AspectJCompileTask;
import protoj.util.JavacCompileTask;

/**
 * Compiles the project source Java (.java) files. Compilation of AspectJ (.aj)
 * files is also supported without any additional software. Note that the
 * {@link #compile(String, String)} method is used to fully compile the project
 * from a programmatic call or from the compile command. The
 * {@link #compileAjc(List)} and {@link #compileJavac(List)} methods are used
 * usually from the command line as an alternative to calling the initial javac
 * in order to compile the core bootstrapping part of this project.
 * 
 * 
 * @author Ashley Williams
 * 
 */
public final class CompileFeature {

	/**
	 * See {@link #getParent()}.
	 */
	private final StandardProject parent;

	/**
	 * The callback object used to provide extra configuration.
	 */
	private ArgRunnable config;

	/**
	 * See {@link #getAjcCompileTask()}.
	 */
	private AspectJCompileTask ajcCompileTask;

	/**
	 * See {@link #isAspectCompiler()}.
	 */
	private boolean aspectCompiler;

	/**
	 * See {@link #getJavacCompileTask()}.
	 */
	private JavacCompileTask javacCompileTask;

	/**
	 * See the getters corresponding to the parameters here.
	 * 
	 * @param parent
	 */
	public CompileFeature(StandardProject parent) {
		this.parent = parent;
		this.aspectCompiler = false;
	}

	/**
	 * See {@link #isAspectCompiler()} and {@link #getConfig()}.
	 * 
	 * @param aspectCompiler
	 * @param config
	 */
	public void initConfig(boolean aspectCompiler,
			ArgRunnable config) {
		this.aspectCompiler = aspectCompiler;
		this.config = config;
	}

	/**
	 * Pass-thru method to
	 * {@link JavacCompileTask#initCrossCompile(String, String, String)}, that
	 * additionally will allow the following property overrides to apply if
	 * specified: {@link StandardProperties#getCompileTarget()},
	 * {@link StandardProperties#getCompileExtdirs()} and
	 * {@link StandardProperties#getCompileBootclasspath()}.
	 * 
	 * @param target
	 * @param extdirs
	 * @param bootclasspath
	 */
	public void initJavacCrossCompile(String target, String extdirs,
			String bootclasspath) {
		getJavacCompileTask().initCrossCompile(target, extdirs, bootclasspath);
	}

	/**
	 * Pass-thru method to
	 * {@link AspectJCompileTask#initCrossCompile(String, String, String)}, that
	 * additionally will allow the following property overrides to apply if
	 * specified: {@link StandardProperties#getCompileTarget()},
	 * {@link StandardProperties#getCompileExtdirs()} and
	 * {@link StandardProperties#getCompileBootclasspath()}.
	 * 
	 * @param target
	 * @param extdirs
	 * @param bootclasspath
	 */
	public void initAjcCrossCompile(String target, String extdirs,
			String bootclasspath) {
		getAjcCompileTask().initCrossCompile(target, extdirs, bootclasspath);
	}

	/**
	 * Delegates to the underlying ant task and additionally will allow an
	 * override from {@link StandardProperties#getCompileSource()} if specified.
	 * 
	 * @param source
	 */
	public void initJavacSource(String source) {
		getJavacCompileTask().getCompileTask().setSource(source);
	}

	/**
	 * Delegates to the underlying ant task and additionally will allow an
	 * override from {@link StandardProperties#getCompileSource()} if specified.
	 * 
	 * @param source
	 */
	public void initAjcSource(String source) {
		getAjcCompileTask().getCompileTask().setSource(source);
	}

	/**
	 * Delegates to the underlying ant task and additionally will allow an
	 * override from {@link StandardProperties#getCompileMemory()} if specified.
	 * 
	 * @param memory
	 */
	public void initAjcMemory(String memory) {
		getAjcCompileTask().getCompileTask().setMaxmem(memory);
	}

	/**
	 * Delegates to the underlying ant task and additionally will allow an
	 * override from {@link StandardProperties#getCompileMemory()} if specified.
	 * 
	 * @param memory
	 */
	public void initJavacMemory(String memory) {
		getJavacCompileTask().getCompileTask().setMemoryMaximumSize(memory);
	}

	/**
	 * The instance used to configure the api. This gets called back during the
	 * call to {@link #compile(String, String)}.
	 * 
	 * @return
	 */
	public ArgRunnable getConfig() {
		return config;
	}

	/**
	 * The ant wrapper used to carry out aspectj compilation.
	 * 
	 * @return
	 */
	public AspectJCompileTask getAjcCompileTask() {
		return ajcCompileTask;
	}

	/**
	 * The ant wrapper used to carry out javac compilation.
	 * 
	 * @return
	 */
	public JavacCompileTask getJavacCompileTask() {
		return javacCompileTask;
	}

	/**
	 * Compiles the source code based on the specified ant patterns. Resources
	 * are initially copied to the classes directory.
	 * 
	 * @param includes
	 *            can be null to include all
	 * @param excludes
	 *            can be null to exclude nothing
	 */
	public void compile(String includes, String excludes) {
		// use if statement, don't need polymorphism
		if (aspectCompiler) {
			compileAjc(includes, excludes);
		} else {
			compileJavac(includes, excludes);
		}
	}

	/**
	 * Invokes the aspectj compiler.
	 * 
	 * @param includes
	 * @param excludes
	 */
	public void compileAjc(String includes, String excludes) {
		copyResources(null, null);
		ajcCompileTask = createAjcTask();
		DirSet dirSet = ajcCompileTask.getDirSet();
		if (includes != null) {
			dirSet.setIncludes(includes);
		}
		if (excludes != null) {
			dirSet.setExcludes(excludes);
		}
		if (config != null) {
			config.run(this);
		}
		ajcCompileTask.execute();
		if (!ajcCompileTask.isSuccess()) {
			throw new InformationException(
					"there was a problem compiling the source code");
		}
	}

	/**
	 * Invokes the javac compiler.
	 * 
	 * @param includes
	 * @param excludes
	 */
	public void compileJavac(String includes, String excludes) {
		copyResources(null, null);
		javacCompileTask = createJavacTask();
		DirSet dirSet = javacCompileTask.getDirSet();
		if (includes != null) {
			dirSet.setIncludes(includes);
		}
		if (excludes != null) {
			dirSet.setExcludes(excludes);
		}
		if (config != null) {
			config.run(this);
		}
		javacCompileTask.execute();
		if (!javacCompileTask.isSuccess()) {
			throw new InformationException(
					"there was a problem compiling the source code");
		}
	}

	/**
	 * Compiles a set of files in the source directory using the javac compiler.
	 * The options parameter contains name value pairs to be applied to the
	 * underlying ant task by beans introspection, so that the compiler can
	 * easily be configured from the command line.
	 * 

* The bean being configured is the JavacCompileTask instance. For example a * string with the content "compileTask.source=1.5" is equivalent to calling * JavacCompileTask.getCompileTask().setSource("1.5"). *

* If the source directory doesn't exist then this method does nothing. *

* Resources are initially copied but not including any aop.xml files. This * is because they may point to aspects that don't even exist yet until a * full compile has been carried out. * * @param options */ public void compileJavac(List options) { File srcDir = parent.getLayout().getSrcDir(); if (srcDir.exists()) { copyResources(null, "**/aop.xml"); parent.getLogger().info("applying javac options:"); JavacCompileTask task = createJavacTask(); assignProperties(options, task); task.execute(); if (!task.isSuccess()) { throw new InformationException( "there was a problem compiling the source code"); } } } /** * Aspectj compiling equivalent of {@link #compileJavac(List)}. * * @param options */ public void compileAjc(List options) { File srcDir = parent.getLayout().getSrcDir(); if (srcDir.exists()) { copyResources(null, "**/aop.xml"); parent.getLogger().info("applying ajc options:"); AspectJCompileTask task = createAjcTask(); assignProperties(options, task); task.execute(); if (!task.isSuccess()) { throw new InformationException( "there was a problem compiling the source code"); } } } /** * Assigns the name=value pairs in the opts list to the given task using * beans utils. * * @param opts * @param task */ private void assignProperties(List opts, Object task) { for (String opt : opts) { String[] property = opt.split("="); String name = property[0]; String value = property[1]; parent.getLogger().info(String.format("%s=%s", name, value)); PropertyUtils.setProperty(task, name, value); } } /** * True if the ajc compiler is configured, false if the javac compiler is * configured. * * @return */ public boolean isAspectCompiler() { return aspectCompiler; } /** * Creates the ajc compile implementation instance. * * @return */ public AspectJCompileTask createAjcTask() { ProjectLayout layout = parent.getLayout(); AspectJCompileTask task = new AspectJCompileTask(layout.getJavaDir(), layout.getClassesDir(), layout.getClasspathConfig()); task.initLogging(); task.getCompileTask().setFailonerror(true); return task; } /** * Creates the javac compile implementation instance. * * @return */ public JavacCompileTask createJavacTask() { ProjectLayout layout = parent.getLayout(); JavacCompileTask task = new JavacCompileTask(layout.getJavaDir(), layout.getClassesDir(), parent.getLayout().getClasspathConfig()); task.initLogging(); return task; } /** * Copies the files in the resources directory into the classes directory. * * @param includes * the ant pattern of files to be included, null means all * @param excludes * the ant pattern of files to be excluded, null means none */ public void copyResources(String includes, String excludes) { AntTarget target = new AntTarget("compile-feature-copy"); ProjectLayout layout = parent.getLayout(); layout.getClassesDir().mkdirs(); Copy copy = new Copy(); target.addTask(copy); copy.setTaskName("copy"); copy.setTodir(layout.getClassesDir()); FileSet resourceFiles = new FileSet(); resourceFiles.setDir(layout.getResourcesDir()); if (includes != null) { resourceFiles.setIncludes(includes); } if (excludes != null) { resourceFiles.setExcludes(excludes); } copy.addFileset(resourceFiles); target.execute(); } /** * The owning instance. * * @return */ public StandardProject getParent() { return parent; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy