1   /*
2    *  Tools.java
3    *
4    *  Copyright (c) 1998-2005, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Valentin Tablan, Jan/2000
12   *
13   *  $Id: Tools.java,v 1.16 2006/03/09 13:33:20 ian_roberts Exp $
14   */
15  
16  package gate.util;
17  
18  import java.io.File;
19  import java.net.JarURLConnection;
20  import java.net.URL;
21  import java.util.*;
22  import java.util.jar.JarFile;
23  import java.util.zip.ZipEntry;
24  
25  import gate.Gate;
26  
27  public class Tools {
28  
29    /** Debug flag */
30    private static final boolean DEBUG = false;
31  
32    public Tools() {
33    }
34    static long sym=0;
35  
36    /** Returns a Long wich is unique during the current run.
37      * Maybe we should use serializaton in order to save the state on
38      * System.exit...
39      */
40    static public synchronized Long gensym(){
41      return new Long(sym++);
42    }
43  
44    static public synchronized Long genTime(){
45  
46      return new Long(new Date().getTime());
47    }
48  
49  
50    /** Specifies whether Gate should or shouldn't know about Unicode */
51    static public void setUnicodeEnabled(boolean value){
52      unicodeEnabled = value;
53    }
54  
55    /** Checks wheter Gate is Unicode enabled */
56    static public boolean isUnicodeEnabled(){
57      return unicodeEnabled;
58    }
59  
60    /** Does Gate know about Unicode? */
61    static private boolean unicodeEnabled = false;
62  
63  
64    /**
65     * Finds all subclasses of a given class or interface. It will only search
66     * within the loaded packages and not the entire classpath.
67     * @param parentClass the class for which subclasses are sought
68     * @return a list of {@link Class} objects.
69     */
70    static public List findSubclasses(Class parentClass){
71      Package[] packages = Package.getPackages();
72      List result = new ArrayList();
73      for(int i = 0; i < packages.length; i++){
74        String packageDir = packages[i].getName();
75        //look in the file system
76        if(!packageDir.startsWith("/")) packageDir = "/" + packageDir;
77        packageDir.replace('.', Strings.getPathSep().charAt(0));
78        URL packageURL = Gate.getClassLoader().getResource(packageDir);
79        if(packageURL != null){
80          File directory = new File(packageURL.getFile());
81          if(directory.exists()){
82            String [] files = directory.list();
83            for (int j=0; j < files.length; j++){
84              // we are only interested in .class files
85              if(files[j].endsWith(".class")){
86                // removes the .class extension
87                String classname = files[j].substring(0, files[j].length() - 6);
88                try {
89                  // Try to create an instance of the object
90                  Class aClass = Class.forName(packages[i] + "." + classname,
91                                               true, Gate.getClassLoader());
92                  if(parentClass.isAssignableFrom(aClass)) result.add(aClass);
93                }catch(ClassNotFoundException cnfex){}
94              }
95            }
96          }else{
97            //look in jar files
98            try{
99              JarURLConnection conn = (JarURLConnection)packageURL.openConnection();
100             String starts = conn.getEntryName();
101             JarFile jFile = conn.getJarFile();
102             Enumeration e = jFile.entries();
103             while (e.hasMoreElements()){
104               String entryname = ((ZipEntry)e.nextElement()).getName();
105               if (entryname.startsWith(starts) &&
106                   //not sub dir
107                   (entryname.lastIndexOf('/')<=starts.length()) &&
108                   entryname.endsWith(".class")){
109                 String classname = entryname.substring(0, entryname.length() - 6);
110                 if (classname.startsWith("/")) classname = classname.substring(1);
111                 classname = classname.replace('/','.');
112                 try {
113                   // Try to create an instance of the object
114                   Class aClass = Class.forName(packages[i] + "." + classname,
115                                                true, Gate.getClassLoader());
116                   if(parentClass.isAssignableFrom(aClass)) result.add(aClass);
117                 }catch(ClassNotFoundException cnfex){}
118               }
119             }
120           }catch(java.io.IOException ioe){}
121         }
122       }
123     }
124     return result;
125   }
126 } // class Tools
127