1   /*
2    *  Tools.java
3    *
4    *  Copyright (c) 1998-2001, 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.11 2002/05/20 10:33:35 valyt Exp $
14   */
15  
16  package gate.util;
17  
18  import java.util.*;
19  import java.net.URL;
20  import java.io.File;
21  import java.net.JarURLConnection;
22  import java.util.jar.*;
23  import java.util.zip.*;
24  
25  import 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 parent 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                  if(parentClass.isAssignableFrom(aClass)) result.add(aClass);
92                }catch(ClassNotFoundException cnfex){}
93              }
94            }
95          }else{
96            //look in jar files
97            try{
98              JarURLConnection conn = (JarURLConnection)packageURL.openConnection();
99              String starts = conn.getEntryName();
100             JarFile jFile = conn.getJarFile();
101             Enumeration e = jFile.entries();
102             while (e.hasMoreElements()){
103               String entryname = ((ZipEntry)e.nextElement()).getName();
104               if (entryname.startsWith(starts) &&
105                   //not sub dir
106                   (entryname.lastIndexOf('/')<=starts.length()) &&
107                   entryname.endsWith(".class")){
108                 String classname = entryname.substring(0, entryname.length() - 6);
109                 if (classname.startsWith("/")) classname = classname.substring(1);
110                 classname = classname.replace('/','.');
111                 try {
112                   // Try to create an instance of the object
113                   Class aClass = Class.forName(packages[i] + "." + classname);
114                   if(parentClass.isAssignableFrom(aClass)) result.add(aClass);
115                 }catch(ClassNotFoundException cnfex){}
116               }
117             }
118           }catch(java.io.IOException ioe){}
119         }
120       }
121     }
122     return result;
123   }
124 } // class Tools
125