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]>

Reply via email to