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.Enumeration;
42 import java.util.HashSet;
43 import java.util.Set;
44 import java.util.Vector;
45 import java.util.jar.JarEntry;
46 import java.util.jar.JarFile;
47 import java.util.zip.ZipEntry;
48
49 /**
50 *
51 * This class allows dynamic search for classes.
52 *
53 * @author sroussel and dleberre
54 *
55 */
56 public class RTSI {
57
58 public static Vector<String> alreadySeenPckges;
59
60 public static Vector<String> find(String tosubclassname) {
61 alreadySeenPckges = new Vector<String>();
62 Set<String> v = new HashSet<String>();
63 Set<String> tmp;
64 try {
65 // ClassLoader.getSystemClassLoader().setPackageAssertionStatus("org.sat4j",
66 // true);
67 Class<?> tosubclass = Class.forName(tosubclassname);
68 Package[] pcks = Package.getPackages();
69 for (Package pck : pcks) {
70 tmp = find(pck.getName(), tosubclass);
71 if (tmp != null) {
72 v.addAll(tmp);
73 }
74 }
75 } catch (ClassNotFoundException ex) {
76 System.err.println("Class " + tosubclassname + " not found!");
77 }
78 return new Vector<String>(v);
79 }
80
81 public static Set<String> find(String pckname, String tosubclassname) {
82 Set<String> v = new HashSet<String>();
83 try {
84 Class<?> tosubclass = Class.forName(tosubclassname);
85 v = find(pckname, tosubclass);
86 } catch (ClassNotFoundException ex) {
87 System.err.println("Class " + tosubclassname + " not found!");
88 }
89 return v;
90 }
91
92 public static Set<String> find(String pckgname, Class<?> tosubclass) {
93 if (alreadySeenPckges.contains(pckgname)) {
94 return new HashSet<String>();
95 } else {
96 alreadySeenPckges.add(pckgname);
97 return findnames(pckgname, tosubclass);
98 }
99 }
100
101 public static Set<String> findnames(String pckgname, Class<?> tosubclass) {
102 Set<String> v = new HashSet<String>();
103 // Code from JWhich
104 // ======
105 // Translate the package name into an absolute path
106 String name = new String(pckgname);
107 if (!name.startsWith("/")) {
108 name = "/" + name;
109 }
110 name = name.replace('.', '/');
111
112 // Get a File object for the package
113 URL url = RTSI.class.getResource(name);
114 // URL url = tosubclass.getResource(name);
115 // URL url = ClassLoader.getSystemClassLoader().getResource(name);
116 // System.out.println(name+"->"+url);
117
118 // Happens only if the jar file is not well constructed, i.e.
119 // if the directories do not appear alone in the jar file like here:
120 //
121 // meta-inf/
122 // meta-inf/manifest.mf
123 // commands/ <== IMPORTANT
124 // commands/Command.class
125 // commands/DoorClose.class
126 // commands/DoorLock.class
127 // commands/DoorOpen.class
128 // commands/LightOff.class
129 // commands/LightOn.class
130 // RTSI.class
131 //
132 if (url == null) {
133 return null;
134 }
135
136 File directory = new File(url.getFile());
137
138 // New code
139 // ======
140 if (directory.exists()) {
141 // Get the list of the files contained in the package
142 String[] files = directory.list();
143 for (String file : files) {
144
145 // we are only interested in .class files
146 if (file.endsWith(".class")) {
147 // removes the .class extension
148 String classname = file.substring(0, file.length() - 6);
149 try {
150 // Try to create an instance of the object
151 Class<?> o = Class.forName(pckgname + "." + classname);
152
153 if (tosubclass.isAssignableFrom(o) && !o.isInterface()
154 && !Modifier.isAbstract(o.getModifiers())) {
155 // System.out.println(classname);
156 v.add(classname);
157 }
158 } catch (NoClassDefFoundError cnfex) {
159 // System.out.println("Warning : no classDefFoundError : "
160 // + classname);
161 } catch (ClassNotFoundException cnfex) {
162 System.err.println(cnfex);
163 }
164 // catch (InstantiationException iex) {
165 // // We try to instanciate an interface
166 // // or an object that does not have a
167 // // default constructor
168 // } catch (IllegalAccessException iaex) {
169 // // The class is not public
170 // }
171 }
172 }
173 File[] dirs = directory.listFiles(new FilenameFilter() {
174 public boolean accept(File dir, String name) {
175 return new File(dir.getAbsolutePath() + "/" + name)
176 .isDirectory();
177 }
178 });
179 Set<String> tmp;
180 for (File dir : dirs) {
181 String newName = pckgname + "." + dir.getName();
182 tmp = find(newName, tosubclass);
183 if (tmp != null) {
184 v.addAll(tmp);
185 }
186
187 }
188
189 } else {
190 try {
191 // It does not work with the filesystem: we must
192 // be in the case of a package contained in a jar file.
193 JarURLConnection conn = (JarURLConnection) url.openConnection();
194 String starts = conn.getEntryName();
195 JarFile jfile = conn.getJarFile();
196 Enumeration<JarEntry> e = jfile.entries();
197 while (e.hasMoreElements()) {
198 ZipEntry entry = e.nextElement();
199 String entryname = entry.getName();
200 if (entryname.startsWith(starts)
201 // &&(entryname.lastIndexOf('/')<=starts.length())
202 && entryname.endsWith(".class")) {
203 String classname = entryname.substring(0,
204 entryname.length() - 6);
205 // System.out.println(classname);
206 if (classname.startsWith("/")) {
207 classname = classname.substring(1);
208 }
209 classname = classname.replace('/', '.');
210 try {
211 // Try to create an instance of the object
212 // Object o =
213 // Class.forName(classname).newInstance();
214 // if (tosubclass.isInstance(o)) {
215
216 Class<?> o = Class.forName(classname);
217
218 if (tosubclass.isAssignableFrom(o)
219 && !o.isInterface()
220 && !Modifier.isAbstract(o.getModifiers())) {
221 // System.out.println(classname.substring(classname.lastIndexOf('.')+1));
222 v.add(classname.substring(classname
223 .lastIndexOf('.') + 1));
224 }
225 } catch (NoClassDefFoundError cnfex) {
226 // System.out.println("Warning : no classDefFoundError : "
227 // + classname);
228 } catch (ClassNotFoundException cnfex) {
229 System.err.print(cnfex);
230 }
231 // catch (InstantiationException iex) {
232 // // We try to instanciate an interface
233 // // or an object that does not have a
234 // // default constructor
235 // } catch (IllegalAccessException iaex) {
236 // // The class is not public
237 // }
238 }
239 }
240 } catch (IOException ioex) {
241 System.err.println(ioex);
242 }
243 }
244
245 return v;
246 }
247
248 public static void displayResultOfFind(String tosubclassname) {
249 System.out.println(find(tosubclassname));
250 }
251
252 public static void displayResultOfFind(String pckname, String tosubclassname) {
253 System.out.println(find(pckname, tosubclassname));
254 }
255
256 public static void displayResultOfFind(String pckgname, Class<?> tosubclass) {
257 System.out.println(findnames(pckgname, tosubclass));
258
259 }
260
261 public static void main(String[] args) {
262 if (args.length == 2) {
263 displayResultOfFind(args[0], args[1]);
264 } else {
265 if (args.length == 1) {
266 displayResultOfFind(args[0]);
267 } else {
268 System.out.println("Usage: java RTSI [<package>] <subclass>");
269 }
270 }
271 }
272 }// RTSI