View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004, 2012 Artois University and CNRS
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    *  http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   *
19   * Based on the original MiniSat specification from:
20   *
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   *
27   * That class was initially written in 2001 by Daniel Le Berre for JavaWorld JavaTips 113.
28   * http://www.javaworld.com/javaworld/javatips/jw-javatip113.html
29   * 
30   * Contributors:
31   *   CRIL - initial API and implementation
32   *******************************************************************************/
33  package org.sat4j.sat;
34  
35  import java.io.File;
36  import java.io.FilenameFilter;
37  import java.io.IOException;
38  import java.lang.reflect.Modifier;
39  import java.net.JarURLConnection;
40  import java.net.URL;
41  import java.util.ArrayList;
42  import java.util.Enumeration;
43  import java.util.HashSet;
44  import java.util.List;
45  import java.util.Set;
46  import java.util.jar.JarEntry;
47  import java.util.jar.JarFile;
48  import java.util.zip.ZipEntry;
49  
50  /**
51   * 
52   * This class allows dynamic search for classes.
53   * 
54   * That code appeared in Java World 113 in an article written by Daniel Le Berre
55   * http://www.javaworld.com/javatips/jw-javatip113.html
56   * 
57   * The initial code of JWhich, on which is based this code, was published in
58   * JavaWorld 105 by Mike Clark
59   * http://www.javaworld.com/javaworld/javatips/jw-javatip105.html
60   * 
61   * @author sroussel and dleberre
62   * 
63   */
64  public class RTSI {
65  
66      private static List<String> alreadySeenPckges;
67  
68      private RTSI() {
69          // prevent creation of an instance of that class
70      }
71  
72      public static List<String> find(String tosubclassname, boolean fullname) {
73          alreadySeenPckges = new ArrayList<String>();
74          Set<String> v = new HashSet<String>();
75          Set<String> tmp;
76          try {
77              Class<?> tosubclass = Class.forName(tosubclassname);
78              Package[] pcks = Package.getPackages();
79              for (Package pck : pcks) {
80                  tmp = find(pck.getName(), tosubclass, fullname);
81                  if (tmp != null) {
82                      v.addAll(tmp);
83                  }
84              }
85          } catch (ClassNotFoundException ex) {
86              System.err.println("Class " + tosubclassname + " not found!");
87          }
88          return new ArrayList<String>(v);
89      }
90  
91      public static Set<String> find(String pckname, String tosubclassname,
92              boolean fullname) {
93          Set<String> v = new HashSet<String>();
94          try {
95              Class<?> tosubclass = Class.forName(tosubclassname);
96              v = find(pckname, tosubclass, fullname);
97          } catch (ClassNotFoundException ex) {
98              System.err.println("Class " + tosubclassname + " not found!");
99          }
100         return v;
101     }
102 
103     public static Set<String> find(String pckgname, Class<?> tosubclass,
104             boolean fullname) {
105         if (alreadySeenPckges.contains(pckgname)) {
106             return new HashSet<String>();
107         } else {
108             alreadySeenPckges.add(pckgname);
109             return findnames(pckgname, tosubclass, fullname);
110         }
111     }
112 
113     public static List<String> find(String tosubclassname) {
114         return find(tosubclassname, false);
115     }
116 
117     public static Set<String> find(String pckname, String tosubclassname) {
118         return find(pckname, tosubclassname, false);
119     }
120 
121     public static Set<String> find(String pckgname, Class<?> tosubclass) {
122         return find(pckgname, tosubclass, false);
123     }
124 
125     public static Set<String> findnames(String pckgname, Class<?> tosubclass) {
126         return findnames(pckgname, tosubclass, false);
127     }
128 
129     public static Set<String> findnames(String pckgname, Class<?> tosubclass,
130             boolean fullname) {
131         Set<String> v = new HashSet<String>();
132 
133         // Code from JWhich
134         // ======
135         // Translate the package name into an absolute path
136         String name = pckgname;
137         if (!name.startsWith("/")) {
138             name = "/" + name;
139         }
140         name = name.replace('.', '/');
141 
142         // Get a File object for the package
143         URL url = RTSI.class.getResource(name);
144 
145         if (url == null) {
146             return null;
147         }
148 
149         File directory = new File(url.getFile());
150 
151         // New code
152         // ======
153         if (directory.exists()) {
154             // Get the list of the files contained in the package
155             String[] files = directory.list();
156             for (String file : files) {
157 
158                 // we are only interested in .class files
159                 if (file.endsWith(".class")) {
160 
161                     String classname = file.substring(0, file.length() - 6);
162                     try {
163                         // Try to create an instance of the object
164                         Class<?> o = Class.forName(pckgname + "." + classname);
165 
166                         if (tosubclass.isAssignableFrom(o) && !o.isInterface()
167                                 && !Modifier.isAbstract(o.getModifiers())) {
168                             if (fullname) {
169                                 v.add(pckgname + "." + classname);
170                             } else {
171                                 v.add(classname);
172                             }
173                         }
174                     } catch (NoClassDefFoundError cnfex) {
175 
176                     } catch (ClassNotFoundException cnfex) {
177                         System.err.println(cnfex);
178                     }
179 
180                 }
181             }
182             File[] dirs = directory.listFiles(new FilenameFilter() {
183                 public boolean accept(File dir, String name) {
184                     return new File(dir.getAbsolutePath() + "/" + name)
185                             .isDirectory();
186                 }
187             });
188             Set<String> tmp;
189             for (File dir : dirs) {
190                 String newName = pckgname + "." + dir.getName();
191                 tmp = find(newName, tosubclass, fullname);
192                 if (tmp != null) {
193                     v.addAll(tmp);
194                 }
195 
196             }
197 
198         } else {
199             try {
200                 // It does not work with the filesystem: we must
201                 // be in the case of a package contained in a jar file.
202                 JarURLConnection conn = (JarURLConnection) url.openConnection();
203                 String starts = conn.getEntryName();
204                 JarFile jfile = conn.getJarFile();
205                 Enumeration<JarEntry> e = jfile.entries();
206                 while (e.hasMoreElements()) {
207                     ZipEntry entry = e.nextElement();
208                     String entryname = entry.getName();
209                     if (entryname.startsWith(starts)
210                             && entryname.endsWith(".class")) {
211                         String classname = entryname.substring(0,
212                                 entryname.length() - 6);
213                         if (classname.startsWith("/")) {
214                             classname = classname.substring(1);
215                         }
216                         classname = classname.replace('/', '.');
217                         try {
218                             // Try to create an instance of the object
219                             Class<?> o = Class.forName(classname);
220 
221                             if (tosubclass.isAssignableFrom(o)
222                                     && !o.isInterface()
223                                     && !Modifier.isAbstract(o.getModifiers())) {
224                                 if (fullname) {
225                                     v.add(classname);
226                                 } else {
227                                     v.add(classname.substring(classname
228                                             .lastIndexOf('.') + 1));
229                                 }
230                             }
231                         } catch (NoClassDefFoundError cnfex) {
232                         } catch (ClassNotFoundException cnfex) {
233                             System.err.print(cnfex);
234                         }
235                     }
236                 }
237             } catch (IOException ioex) {
238                 System.err.println(ioex);
239             }
240         }
241 
242         return v;
243     }
244 
245     public static void displayResultOfFind(String tosubclassname) {
246         System.out.println(find(tosubclassname));
247     }
248 
249     public static void displayResultOfFind(String pckname, String tosubclassname) {
250         System.out.println(find(pckname, tosubclassname));
251     }
252 
253     public static void displayResultOfFind(String pckgname, Class<?> tosubclass) {
254         System.out.println(findnames(pckgname, tosubclass));
255 
256     }
257 
258     public static void main(String[] args) {
259         if (args.length == 2) {
260             displayResultOfFind(args[0], args[1]);
261         } else {
262             if (args.length == 1) {
263                 displayResultOfFind(args[0]);
264             } else {
265                 System.out.println("Usage: java RTSI [<package>] <subclass>");
266             }
267         }
268     }
269 }// RTSI