http://id.mind.net/~malachi/cvs/ant/patchfile-20022002-Javah.txt
--- Javah.orig.java Wed Feb 20 04:37:30 2002
+++ Javah.java Wed Feb 20 12:02:00 2002
@@ -63,12 +63,16 @@
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.Commandline;
-
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.taskdefs.optional.depend.ClassFileUtils;
import java.io.File;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.Enumeration;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
/**
* Task to generate JNI header files using javah. This task can take the
following
@@ -105,9 +109,11 @@
private final static String FAIL_MSG = "Compile failed, messages should
have been
provided.";
+ private AntClassLoader loader;
private Vector classes = new Vector(2);
private String cls;
private File destDir;
+ private File baseDir;
private Path classpath = null;
private File outputFile = null;
private boolean verbose = false;
@@ -152,6 +158,13 @@
this.destDir = destDir;
}
+ /**
+ * Set the base directory from which the class files should be found.
+ */
+ public void setBasedir(File baseDir){
+ this.baseDir = baseDir;
+ }
+
public void setClasspath(Path src) {
if (classpath == null) {
classpath = src;
@@ -255,10 +268,19 @@
* Executes the task.
*/
public void execute() throws BuildException {
+ /**
+ * If they have specified a baseDir, then we want to add
+ * all class files under it (assuming they have JNI methods).
+ */
+ addBaseDirFilesToCompile();
+
// first off, make sure that we've got a srcdir
if ((cls == null) && (classes.size() == 0)) {
- throw new BuildException("class attribute must be set!", location);
+ if(baseDir == null)
+ throw new BuildException("class attribute must be set!",
location);
+ else
+ throw new BuildException(baseDir + " contains no classes
using JNI!",
location);
}
if ((cls != null) && (classes.size() > 0)) {
@@ -427,5 +449,111 @@
log(prefix.toString() + niceClassList.toString(), Project.MSG_VERBOSE);
}
-}
+ /**
+ * Scan the baseDir and add *.class (except RMI Stubs and Skels) to the
list of
classes to compile.
+ */
+ protected void addBaseDirFilesToCompile()
+ {
+ /**
+ * Only do this if the baseDir is set.
+ */
+ if(baseDir == null)
+ return;
+
+ DirectoryScanner ds = new DirectoryScanner();
+ /**
+ * Add *.class files
+ */
+ String[] includes = {"**\\*.class"};
+ ds.setIncludes(includes);
+
+ /**
+ * Exclude RMI Stubs/Skels
+ */
+ String[] excludes = {"**\\*_Stub.class", "**\\*_Skel.class"};
+ ds.setExcludes(excludes);
+ ds.setBasedir(baseDir);
+
+ //ds.setCaseSensitive(false);
+ ds.scan();
+ String[] fileNames = ds.getIncludedFiles();
+
+ /**
+ * Now actually determine which fileNames represent classes with
native methods
+ */
+ String className = null;
+ for(int i=0; i<fileNames.length; i++)
+ {
+ className =
ClassFileUtils.convertSlashName(fileNames[i]);
+ /**
+ * Why does convertSlashName leave .class on it?
+ */
+ if(className.endsWith(".class"))
+ className = className.substring(0,
className.length() - 6);
+
+ if(hasNativeMethod(className))
+ {
+ ClassArgument ca = createClass();
+ ca.setName(className);
+ }
+ }
+ }
+
+ /**
+ * Returns true if the specified class has native methods. False otherwise.
+ */
+ protected boolean hasNativeMethod(String className){
+ try{
+ Class cls = getLoader().loadClass(className);
+ return hasNativeMethod(cls);
+ }catch(Exception e){
+ log("Error: " + e.getMessage());
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns true if the specified class has native methods. False otherwise.
+ */
+ protected boolean hasNativeMethod(Class cls){
+ try{
+ if(cls == null)
+ return false;
+
+ /**
+ * Interfaces don't implement anything, let alone native
methods.
+ */
+ if(cls.isInterface())
+ return false;
+
+ Method[] methods = cls.getDeclaredMethods();
+ for(int i=0; i<methods.length; i++){
+ int m = methods[i].getModifiers();
+ /**
+ * Has at least one native method, need javah...
+ */
+ if(Modifier.isNative(m))
+ return true;
+ }
+ }catch(Exception e){
+ log("Error: " + e.getMessage());
+ }
+
+ return false;
+ }
+
+ /**
+ * Make sure we are using Ant to load the classes.
+ */
+ protected ClassLoader getLoader()
+ {
+ /**
+ * createPath seems to return an EMPTY path!
+ */
+ //loader = new AntClassLoader(super.project,
classpath.createPath());
+ loader = new AntClassLoader(super.project, classpath);
+ return loader;
+ }
+}
\ No newline at end of
file
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>