diff --git a/src/main/org/apache/tools/ant/taskdefs/Apt.java b/src/main/org/apache/tools/ant/taskdefs/Apt.java new file mode 100644 index 000000000..0e769250a --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/Apt.java @@ -0,0 +1,161 @@ +/* + * Copyright 2002-2004 The Apache Software Foundation + * + * 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 org.apache.tools.ant.taskdefs; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.compilers.AptExternalCompilerAdapter; +import org.apache.tools.ant.taskdefs.compilers.AptCompilerAdapter; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Reference; +import org.apache.tools.ant.util.JavaEnvUtils; + +import java.util.Vector; +import java.io.File; + +/** + * Apt Task for running the Annotation processing tool for JDK 1.5. It derives + * from the existing Javac task, and forces the compiler based on whether we're + * executing internally, or externally. + * + * @since Ant 1.7 + */ + + +public class Apt + extends Javac { + private boolean noCompile; + private String factory; + private Path factoryPath; + private Vector options; + private File preprocessDir; + public static final String EXECUTABLE_NAME = "apt"; + public static final String ERROR_IGNORING_COMPILER_OPTION = "Ignoring compiler attribute for the APT task, as it is fixed"; + public static final String ERROR_WRONG_JAVA_VERSION = "Apt task requires Java 1.5+"; + + /** + * option element + */ + public static final class Option { + private String name; + private String value; + + public Option() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public Apt() { + super(); + super.setCompiler(AptCompilerAdapter.class.getName()); + this.options = new Vector(); + } + + public String getAptExecutable() { + return JavaEnvUtils.getJdkExecutable(EXECUTABLE_NAME); + } + + public void setCompiler(String compiler) { + log(ERROR_IGNORING_COMPILER_OPTION, + Project.MSG_WARN); + } + + public void setFork(boolean fork) { + if (fork) { + super.setCompiler(AptExternalCompilerAdapter.class.getName()); + } else { + super.setCompiler(AptCompilerAdapter.class.getName()); + } + } + + public String getCompiler() { + return super.getCompiler(); + } + + public boolean isNoCompile() { + return noCompile; + } + + public void setNoCompile(boolean noCompile) { + this.noCompile = noCompile; + } + + public String getFactory() { + return factory; + } + + public void setFactory(String factory) { + this.factory = factory; + } + + public void setFactoryPathRef(Reference ref) { + createFactoryPath().setRefid(ref); + } + + public Path createFactoryPath() { + if (factoryPath == null) { + factoryPath = new Path(getProject()); + } + return factoryPath.createPath(); + } + + public Path getFactoryPath() { + return factoryPath; + } + + public Option createOption() { + Option opt = new Option(); + options.add(opt); + return opt; + } + + public Vector getOptions() { + return options; + } + + public File getPreprocessDir() { + return preprocessDir; + } + + public void setPreprocessDir(File preprocessDir) { + this.preprocessDir = preprocessDir; + } + + public void execute() + throws BuildException { + if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)) { + throw new BuildException(ERROR_WRONG_JAVA_VERSION); + } + + super.execute(); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java new file mode 100644 index 000000000..d21d28d96 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java @@ -0,0 +1,125 @@ +/* + * Copyright 2001-2002,2004 The Apache Software Foundation + * + * 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 org.apache.tools.ant.taskdefs.compilers; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Apt; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.Path; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Enumeration; +import java.util.Vector; + + +/** + * The implementation of the apt compiler for JDK 1.5 + * + * @since Ant 1.7 + */ +public class AptCompilerAdapter extends DefaultCompilerAdapter { + + /** + * Integer returned by the "Modern" jdk1.3 compiler to indicate success. + */ + private static final int APT_COMPILER_SUCCESS = 0; + public static final String APT_ENTRY_POINT = "com.sun.tools.apt.Main"; + public static final String APT_METHOD_NAME = "compile"; + + protected Apt getApt() { + return (Apt) getJavac(); + } + + static void setAptCommandlineSwitches(Apt apt, Commandline cmd) { + + if (apt.isNoCompile()) { + cmd.createArgument().setValue("-nocompile"); + } + + // Process the factory class + String factory = apt.getFactory(); + if (factory != null) { + cmd.createArgument().setValue("-factory"); + cmd.createArgument().setValue(factory); + } + + // Process the factory path + Path factoryPath = apt.getFactoryPath(); + if (factoryPath != null) { + cmd.createArgument().setValue("-factorypath"); + cmd.createArgument().setPath(factoryPath); + } + + File preprocessDir = apt.getPreprocessDir(); + if (preprocessDir != null) { + cmd.createArgument().setValue("-s"); + cmd.createArgument().setFile(preprocessDir); + } + + // Process the processor options + Vector options = apt.getOptions(); + Enumeration elements = options.elements(); + Apt.Option opt; + StringBuffer arg = null; + while (elements.hasMoreElements()) { + opt = (Apt.Option) elements.nextElement(); + arg = new StringBuffer(); + arg.append("-A").append(opt.getName()); + if (opt.getValue() != null) { + arg.append("=").append(opt.getValue()); + } + cmd.createArgument().setValue(arg.toString()); + } + } + + protected void setAptCommandlineSwitches(Commandline cmd) { + // Process the nocompile flag + Apt apt = getApt(); + setAptCommandlineSwitches(apt, cmd); + } + + /** + * Run the compilation. + * + * @throws BuildException if the compilation has problems. + */ + public boolean execute() throws BuildException { + attributes.log("Using apt compiler", Project.MSG_VERBOSE); + Commandline cmd = setupModernJavacCommand(); + setAptCommandlineSwitches(cmd); + + // Use reflection to be able to build on all JDKs: + try { + Class c = Class.forName(APT_ENTRY_POINT); + Object compiler = c.newInstance(); + Method compile = c.getMethod(APT_METHOD_NAME, + new Class[]{(new String[]{}).getClass()}); + int result = ((Integer) compile.invoke + (compiler, new Object[]{cmd.getArguments()})) + .intValue(); + return (result == APT_COMPILER_SUCCESS); + } catch (BuildException be) { + throw be; + } catch (Exception ex) { + throw new BuildException("Error starting apt compiler", + ex, location); + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java new file mode 100644 index 000000000..ef0987b1c --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java @@ -0,0 +1,62 @@ +/* + * Copyright 2001-2004 The Apache Software Foundation + * + * 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 org.apache.tools.ant.taskdefs.compilers; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Apt; +import org.apache.tools.ant.types.Commandline; + +/** + * The implementation of the apt compiler for JDK 1.5 using an external process + * + * @since Ant 1.7 + */ +public class AptExternalCompilerAdapter extends DefaultCompilerAdapter { + + + protected Apt getApt() { + return (Apt) getJavac(); + } + + /** + * Performs a compile using the Javac externally. + */ + public boolean execute() throws BuildException { + attributes.log("Using external apt compiler", Project.MSG_VERBOSE); + + + // Setup the apt executable + Apt apt = getApt(); + Commandline cmd = new Commandline(); + cmd.setExecutable(apt.getAptExecutable()); + setupModernJavacCommandlineSwitches(cmd); + AptCompilerAdapter.setAptCommandlineSwitches(apt, cmd); + + //add the files + logAndAddFilesToCompile(cmd); + + //run + return 0==executeExternalCompile(cmd.getCommandline(), + cmd.size(), + true); + + } + +} +