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

org.apache.tools.ant.taskdefs.optional.Javah Maven / Gradle / Ivy

The newest version!
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.optional;

import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapter;
import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapterFactory;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.StringUtils;
import org.apache.tools.ant.util.facade.FacadeTaskHelper;
import org.apache.tools.ant.util.facade.ImplementationSpecificArgument;

/**
 * Generates JNI header files using javah.
 *
 * This task can take the following arguments:
 * 
    *
  • classname - the fully-qualified name of a class
  • *
  • outputFile - Concatenates the resulting header or source files for all * the classes listed into this file
  • *
  • destdir - Sets the directory where javah saves the header files or the * stub files
  • *
  • classpath
  • *
  • bootclasspath
  • *
  • force - Specifies that output files should always be written (JDK1.2 only)
  • *
  • old - Specifies that old JDK1.0-style header files should be generated * (otherwise output file contain JNI-style native method * function prototypes) (JDK1.2 only)
  • *
  • stubs - generate C declarations from the Java object file (used with old)
  • *
  • verbose - causes javah to print a message to stdout concerning the status * of the generated files
  • *
  • extdirs - Override location of installed extensions
  • *
* Of these arguments, either outputFile or destdir is required, * but not both. More than one classname may be specified, using a comma-separated * list or by using <class name="xxx"> elements within the task. *

* When this task executes, it will generate C header and source files that * are needed to implement native methods. * */ public class Javah extends Task { private Vector classes = new Vector(2); private String cls; private File destDir; private Path classpath = null; private File outputFile = null; private boolean verbose = false; private boolean force = false; private boolean old = false; private boolean stubs = false; private Path bootclasspath; //private Path extdirs; private FacadeTaskHelper facade = null; private Vector files = new Vector(); private JavahAdapter nestedAdapter = null; /** * No arg constructor. */ public Javah() { facade = new FacadeTaskHelper(JavahAdapterFactory.getDefault()); } /** * the fully-qualified name of the class (or classes, separated by commas). * @param cls the classname (or classnames). */ public void setClass(String cls) { this.cls = cls; } /** * Adds class to process. * @return a ClassArgument to be configured. */ public ClassArgument createClass() { ClassArgument ga = new ClassArgument(); classes.addElement(ga); return ga; } /** * A class corresponding the the nested "class" element. * It contains a "name" attribute. */ public class ClassArgument { private String name; /** Constructor for ClassArgument. */ public ClassArgument() { } /** * Set the name attribute. * @param name the name attribute. */ public void setName(String name) { this.name = name; } /** * Get the name attribute. * @return the name attribute. */ public String getName() { return name; } } /** * Add a fileset. * @param fs the fileset to add. */ public void addFileSet(FileSet fs) { files.add(fs); } /** * Names of the classes to process. * @return the array of classes. * @since Ant 1.6.3 */ public String[] getClasses() { ArrayList al = new ArrayList(); if (cls != null) { StringTokenizer tok = new StringTokenizer(cls, ",", false); while (tok.hasMoreTokens()) { al.add(tok.nextToken().trim()); } } if (files.size() > 0) { for (Enumeration e = files.elements(); e.hasMoreElements();) { FileSet fs = (FileSet) e.nextElement(); String[] includedClasses = fs.getDirectoryScanner( getProject()).getIncludedFiles(); for (int i = 0; i < includedClasses.length; i++) { String className = includedClasses[i].replace('\\', '.').replace('/', '.') .substring(0, includedClasses[i].length() - 6); al.add(className); } } } Enumeration e = classes.elements(); while (e.hasMoreElements()) { ClassArgument arg = (ClassArgument) e.nextElement(); al.add(arg.getName()); } return (String[]) al.toArray(new String[al.size()]); } /** * Set the destination directory into which the Java source * files should be compiled. * @param destDir the destination directory. */ public void setDestdir(File destDir) { this.destDir = destDir; } /** * The destination directory, if any. * @return the destination directory. * @since Ant 1.6.3 */ public File getDestdir() { return destDir; } /** * the classpath to use. * @param src the classpath. */ public void setClasspath(Path src) { if (classpath == null) { classpath = src; } else { classpath.append(src); } } /** * Path to use for classpath. * @return a path to be configured. */ public Path createClasspath() { if (classpath == null) { classpath = new Path(getProject()); } return classpath.createPath(); } /** * Adds a reference to a classpath defined elsewhere. * @param r a reference to a classpath. * @todo this needs to be documented in the HTML docs. */ public void setClasspathRef(Reference r) { createClasspath().setRefid(r); } /** * The classpath to use. * @return the classpath. * @since Ant 1.6.3 */ public Path getClasspath() { return classpath; } /** * location of bootstrap class files. * @param src the bootstrap classpath. */ public void setBootclasspath(Path src) { if (bootclasspath == null) { bootclasspath = src; } else { bootclasspath.append(src); } } /** * Adds path to bootstrap class files. * @return a path to be configured. */ public Path createBootclasspath() { if (bootclasspath == null) { bootclasspath = new Path(getProject()); } return bootclasspath.createPath(); } /** * To the bootstrap path, this adds a reference to a classpath defined elsewhere. * @param r a reference to a classpath * @todo this needs to be documented in the HTML. */ public void setBootClasspathRef(Reference r) { createBootclasspath().setRefid(r); } /** * The bootclasspath to use. * @return the bootclass path. * @since Ant 1.6.3 */ public Path getBootclasspath() { return bootclasspath; } /** * Concatenates the resulting header or source files for all * the classes listed into this file. * @param outputFile the output file. */ public void setOutputFile(File outputFile) { this.outputFile = outputFile; } /** * The destination file, if any. * @return the destination file. * @since Ant 1.6.3 */ public File getOutputfile() { return outputFile; } /** * If true, output files should always be written (JDK1.2 only). * @param force the value to use. */ public void setForce(boolean force) { this.force = force; } /** * Whether output files should always be written. * @return the force attribute. * @since Ant 1.6.3 */ public boolean getForce() { return force; } /** * If true, specifies that old JDK1.0-style header files should be * generated. * (otherwise output file contain JNI-style native method function * prototypes) (JDK1.2 only). * @param old if true use old 1.0 style header files. */ public void setOld(boolean old) { this.old = old; } /** * Whether old JDK1.0-style header files should be generated. * @return the old attribute. * @since Ant 1.6.3 */ public boolean getOld() { return old; } /** * If true, generate C declarations from the Java object file (used with old). * @param stubs if true, generated C declarations. */ public void setStubs(boolean stubs) { this.stubs = stubs; } /** * Whether C declarations from the Java object file should be generated. * @return the stubs attribute. * @since Ant 1.6.3 */ public boolean getStubs() { return stubs; } /** * If true, causes Javah to print a message concerning * the status of the generated files. * @param verbose if true, do verbose printing. */ public void setVerbose(boolean verbose) { this.verbose = verbose; } /** * Whether verbose output should get generated. * @return the verbose attribute. * @since Ant 1.6.3 */ public boolean getVerbose() { return verbose; } /** * Choose the implementation for this particular task. * @param impl the name of the implemenation. * @since Ant 1.6.3 */ public void setImplementation(String impl) { if ("default".equals(impl)) { facade.setImplementation(JavahAdapterFactory.getDefault()); } else { facade.setImplementation(impl); } } /** * Adds an implementation specific command-line argument. * @return a ImplementationSpecificArgument to be configured. * * @since Ant 1.6.3 */ public ImplementationSpecificArgument createArg() { ImplementationSpecificArgument arg = new ImplementationSpecificArgument(); facade.addImplementationArgument(arg); return arg; } /** * Returns the (implementation specific) settings given as nested * arg elements. * @return the arguments. * @since Ant 1.6.3 */ public String[] getCurrentArgs() { return facade.getArgs(); } /** * The classpath to use when loading the javah implementation * if it is not a built-in one. * * @since Ant 1.8.0 */ public Path createImplementationClasspath() { return facade.getImplementationClasspath(getProject()); } /** * Set the adapter explicitly. * @since Ant 1.8.0 */ public void add(JavahAdapter adapter) { if (nestedAdapter != null) { throw new BuildException("Can't have more than one javah" + " adapter"); } nestedAdapter = adapter; } /** * Execute the task * * @throws BuildException is there is a problem in the task execution. */ public void execute() throws BuildException { // first off, make sure that we've got a srcdir if ((cls == null) && (classes.size() == 0) && (files.size() == 0)) { throw new BuildException("class attribute must be set!", getLocation()); } if ((cls != null) && (classes.size() > 0) && (files.size() > 0)) { throw new BuildException("set class attribute OR class element OR fileset, " + "not 2 or more of them.", getLocation()); } if (destDir != null) { if (!destDir.isDirectory()) { throw new BuildException("destination directory \"" + destDir + "\" does not exist or is not a directory", getLocation()); } if (outputFile != null) { throw new BuildException("destdir and outputFile are mutually " + "exclusive", getLocation()); } } if (classpath == null) { classpath = (new Path(getProject())).concatSystemClasspath("last"); } else { classpath = classpath.concatSystemClasspath("ignore"); } JavahAdapter ad = nestedAdapter != null ? nestedAdapter : JavahAdapterFactory.getAdapter(facade.getImplementation(), this, createImplementationClasspath()); if (!ad.compile(this)) { throw new BuildException("compilation failed"); } } /** * Logs the compilation parameters, adds the files to compile and logs the * "niceSourceList" * @param cmd the command line. */ public void logAndAddFiles(Commandline cmd) { logAndAddFilesToCompile(cmd); } /** * Logs the compilation parameters, adds the files to compile and logs the * "niceSourceList" * @param cmd the command line to add parameters to. */ protected void logAndAddFilesToCompile(Commandline cmd) { log("Compilation " + cmd.describeArguments(), Project.MSG_VERBOSE); StringBuffer niceClassList = new StringBuffer(); String[] c = getClasses(); for (int i = 0; i < c.length; i++) { cmd.createArgument().setValue(c[i]); niceClassList.append(" "); niceClassList.append(c[i]); niceClassList.append(StringUtils.LINE_SEP); } StringBuffer prefix = new StringBuffer("Class"); if (c.length > 1) { prefix.append("es"); } prefix.append(" to be compiled:"); prefix.append(StringUtils.LINE_SEP); log(prefix.toString() + niceClassList.toString(), Project.MSG_VERBOSE); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy