1 package demoRunner;
2
3
4 import java.io.BufferedReader;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.FileNotFoundException;
8 import java.io.FilenameFilter;
9 import java.io.IOException;
10 import java.io.InputStreamReader;
11 import java.lang.reflect.InvocationTargetException;
12 import java.lang.reflect.Method;
13 import java.net.URL;
14 import java.util.ArrayList;
15 import java.util.Comparator;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.jar.JarEntry;
19 import java.util.jar.JarInputStream;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
22
23
24
30 public class DemoRunner {
31
32
33
39 public static void run(String args[],String packageName, String noRunName) {
40 if (args.length > 1) {
41 System.out
42 .println("Anna parametrina vain yhden ajettavan demon nimi.\n"
43 + "Jos et anna parametreja, voit valita ajettavan demon "
44 + "listasta.");
45 System.exit(1);
46 }
47
48
49 DemoRunner demo = new DemoRunner(packageName,noRunName);
50
51 String msg = "";
52 if (args.length == 0) {
53 msg = demo.runInteractively();
54 } else {
55 msg = demo.runWithArgs(args);
56 }
57 System.out.println(msg);
58 }
59
60 private ClassList classes;
61
62
67 public DemoRunner(String packageName, String noRunName) {
68 classes = new ClassList(packageName,noRunName);
69 classes.sort();
70 }
71
72
77 public String runWithArgs(String[] args) {
78 String sampleName = args[0];
79 String[] restOfArgs = new String[args.length-1];
82 for (int i = 0; i<args.length-1; ++i) {
83 restOfArgs[i] = args[i+1];
84 }
85 Class<?> sampleClass = classes.get(sampleName);
86 if (sampleClass == null)
87 return "Demoa " + sampleName + " ei ole.";
88 runDemo(sampleClass, restOfArgs);
89 return "";
90 }
91
92
96 public String runInteractively() {
97 String resultMessage = "";
98
99 System.out.println("Valitse ajettava demo");
100
101 int number = 0;
102 for (Class<?> aClass : classes) {
103 System.out.printf(" %d. %s\n", number++, aClass.getName());
104 }
105
106 BufferedReader consoleInputStream = new BufferedReader(
107 new InputStreamReader(System.in));
108
109 while (true) {
110 try {
111 System.out.print("Anna ajettavan demon numero: ");
112 String response = consoleInputStream.readLine();
113 if (response.equals("")) {
114 break;
115 }
116 int index = Integer.parseInt(response);
117 Class<?> sampleClass = classes.get(index);
118 runDemo(sampleClass, null);
119 resultMessage = "";
120 break;
121 } catch (IOException e) {
122 resultMessage = "Demoa ei voitu ajaa: "
123 + e.getLocalizedMessage();
124 System.err.println(resultMessage);
125 } catch (NumberFormatException e) {
126 System.out.println("Anna numero 0..." + (classes.size() - 1));
127 resultMessage = "";
128 } catch (IndexOutOfBoundsException e) {
129 System.out.println("Anna numero 0..." + (classes.size() - 1));
130 resultMessage = "";
131 }
132 }
133
134 return resultMessage;
135 }
136
137 private void runDemo(Class<?> sampleClass, String[] args) {
138 try {
139 Object objectParameters[] = { new String[] {} };
140 Class<?> classParameters[] = { objectParameters[0].getClass() };
141 Method mainMethod = sampleClass.getDeclaredMethod("main",
142 classParameters);
143 mainMethod.invoke(null, (Object) args);
144 } catch (SecurityException e) { e.printStackTrace(System.err); } catch (IllegalArgumentException e) { e.printStackTrace(System.err); } catch (NoSuchMethodException e) {
149 e.printStackTrace(System.err);
150 } catch (IllegalAccessException e) {
151 e.printStackTrace(System.err);
152 } catch (InvocationTargetException e) {
153 e.printStackTrace(System.err);
154 }
155 }
156
157
158
162 public static class ClassList implements Iterable<Class<?>> {
163 private List<Class<?>> classes;
164 private String packageOfClasses;
165 private String noRunName;
166
167
173 private boolean isAllowed(String name,String noRunName1) {
174 return !name.endsWith(noRunName1+".class");
175 }
176
177
178
183 public ClassList(String packageName,String noRunName) {
184 classes = new ArrayList<Class<?>>();
185 add(packageName, noRunName);
186 }
187
188
193 public final void add(String packageName,String noRunName1) {
194 String thisPackageName = DemoRunner.class.getPackage().getName();
195 String thisName = DemoRunner.class.getSimpleName();
196 this.noRunName = noRunName1;
197 packageOfClasses = packageName;
198 URL demoURL = DemoRunner.class.getResource(thisName+".class");
199 File classFile = new File(demoURL.toExternalForm());
200 String pathnameOfClass = classFile.getParentFile().getPath();
201
202 String[] packagePath = pathnameOfClass.split("!")[0].split(":");
203 String thisPackage = packagePath[packagePath.length - 1];
204 String packageRoot = thisPackage.substring(0,thisPackage.length()-thisPackageName.length());
205
206 if (packagePath[0].equals("jar")) {
207 String packageFileName = thisPackage;
208 File packageFile = new File(packageFileName);
209 classesInJar(packageFile);
210 } else {
211 String packageFileName = packageRoot+File.separator+packageName;
212 File packageFile = new File(packageFileName);
213 classesInDirectory(packageFile);
214 }
215 }
216
217 private void classesInDirectory(final File directory) {
218 File[] files = directory.listFiles(new FilenameFilter() {
219 @SuppressWarnings("synthetic-access")
220 @Override
221 public boolean accept(File dir, String name) {
222 return dir.equals(directory) && name.endsWith(".class")
223 && !name.contains("$") && isAllowed(name, noRunName);
224 }
225 });
226 for (File file : files) {
227 loadSampleClass(file);
228 }
229 }
230
231
232 private void classesInJar(File jarFile) {
233 JarInputStream jarStream = null;
234 try {
235 jarStream = new JarInputStream(new FileInputStream(jarFile));
236 JarEntry jarEntry = jarStream.getNextJarEntry();
237 while (jarEntry != null) {
238 if (jarEntry.toString().endsWith(".class") && isAllowed(jarEntry.toString(),noRunName) ) {
239
240 Pattern pp = Pattern.compile(packageOfClasses
241 + "/([\\w\\d_]+)\\.class");
242 Matcher mm = pp.matcher(jarEntry.toString());
243 if (mm.matches()) {
244 loadSampleClass(mm.group(1));
245 }
246 }
247 try {
248 jarEntry = jarStream.getNextJarEntry();
249 } catch (IOException e) {
250 }
252 }
253 } catch (FileNotFoundException e) { e.printStackTrace(System.err); } catch (IOException e) { e.printStackTrace(System.err);
260 } finally {
261 if ( jarStream != null )
262 try {
263 jarStream.close();
264 } catch (IOException e) { }
266 }
267 }
268
269
270
274 @Override
275 public Iterator<Class<?>> iterator() {
276 return classes.iterator();
277 }
278
279
282 public void sort() {
283 java.util.Collections.sort(classes, new Comparator<Class<?>>() {
284 @Override
285 public int compare(Class<?> o1, Class<?> o2) {
286 return o1.getName().compareTo(o2.getName());
287 }
288 });
289 }
290
291
298 public Class<?> get(String sampleName) {
299 for (Class<?> aClass : this) {
300 if (aClass.getName().endsWith(sampleName)) {
301 return aClass;
302 }
303 }
304 return null;
305 }
306
307
316 public Class<?> get(int index) throws IndexOutOfBoundsException {
317 return classes.get(index);
318 }
319
320
326 public int size() {
327 return classes.size();
328 }
329
330 private Class<?> loadSampleClass(File file) {
331 String filename = file.getName();
332 return loadSampleClass(filename.substring(0, filename
333 .lastIndexOf(".")));
334 }
335
336 private Class<?> loadSampleClass(String fname) {
337 Class<?> candidateClass = null;
338
339 try {
340 candidateClass = java.lang.Class.forName(packageOfClasses
341 + "." + fname, true, ClassLoader.getSystemClassLoader());
342 } catch (ClassNotFoundException e) {
343 return null;
344 }
345 classes.add(candidateClass);
346 return candidateClass;
347 }
348
349 }
350
351 }
352
353