Changeset 2281 for trunk/java-utils/src
- Timestamp:
- 08/02/19 13:39:17 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/java-utils/src/main/java/de/ugoe/cs/util/console/CommandExecuter.java
r2260 r2281 12 12 // See the License for the specific language governing permissions and 13 13 // limitations under the License. 14 15 14 16 15 package de.ugoe.cs.util.console; … … 81 80 * </p> 82 81 */ 83 private List< String> commandPackageList;84 82 private List<CommandPackage> commandPackageList; 83 85 84 /** 86 85 * <p> … … 108 107 */ 109 108 private CommandExecuter() { 110 commandPackageList = new ArrayList< String>();109 commandPackageList = new ArrayList<CommandPackage>(); 111 110 } 112 111 … … 121 120 * thrown if the package name is null or empty string 122 121 */ 123 public void addCommandPackage(String pkg ) {122 public void addCommandPackage(String pkg, ClassLoader loader) { 124 123 if ("".equals(pkg) || pkg == null) { 125 124 throw new IllegalArgumentException("package name must not be null or empty string"); 126 125 } 127 commandPackageList.add(pkg); 126 commandPackageList.add(new CommandPackage(pkg, loader)); 127 availableCommands = null; 128 128 } 129 129 … … 148 148 public void exec(String command) { 149 149 Console.commandNotification(command); 150 Command cmd = null;151 150 CommandParser parser = new CommandParser(); 152 151 parser.parse(command); 153 for (int i = 0; cmd == null && i < commandPackageList.size(); i++) { 154 cmd = loadCMD(commandPackageList.get(i) + "." + cmdPrefix + parser.getCommandName()); 155 } 156 if (cmd == null) { // check if command is available as default command 157 cmd = loadCMD(defaultPackage + "." + cmdPrefix + parser.getCommandName()); 158 } 152 153 Command cmd = getCMD(parser.getCommandName()); 154 159 155 if (cmd == null) { 160 156 Console.println("Unknown command"); … … 186 182 * otherwise 187 183 */ 188 public Command loadCMD(String className) {189 Command cmd = null;190 try {191 Class<?> cmdClass = Class.forName(className);192 cmd = (Command) cmdClass.getDeclaredConstructor().newInstance();193 }194 catch (NoClassDefFoundError e) {195 String[] splitResult = e.getMessage().split("CMD");196 String correctName = splitResult[splitResult.length - 1].replace(")", "");197 Console.println("Did you mean " + correctName + "?");198 }199 catch (ClassNotFoundException e) {}200 catch (IllegalAccessException e) {}201 catch (InstantiationException e) {}202 catch (InvocationTargetException e) {}203 catch (NoSuchMethodException e) {}204 catch (ClassCastException e) {205 Console.traceln(Level.WARNING, className + "found, but does not implement Command");206 }207 return cmd;208 }209 210 /**211 * <p>212 * Helper method that loads a class and tries to cast it to {@link Command}.213 * </p>214 *215 * @param className216 * qualified name of the class (including package name)217 * @return if class is available and implement {@link Command} and instance of the class, null218 * otherwise219 */220 184 public Command getCMD(String commandName) { 221 Command cmd = null; 222 for (int i = 0; cmd == null && i < commandPackageList.size(); i++) { 223 cmd = loadCMD(commandPackageList.get(i) + "." + cmdPrefix + commandName); 224 } 225 if (cmd == null) { // check if command is available as default command 226 cmd = loadCMD(defaultPackage + "." + cmdPrefix + commandName); 227 } 228 return cmd; 185 for (Command candidate : getAvailableCommands()) { 186 if (candidate.getClass().getSimpleName().equals(cmdPrefix + commandName)) { 187 return candidate; 188 } 189 } 190 191 return null; 229 192 } 230 193 … … 239 202 public Command[] getAvailableCommands() { 240 203 if (availableCommands == null) { 241 List<Command> commands = new ArrayList<Command>();242 List< String> packages = new ArrayList<String>();204 // List<Command> commands = new ArrayList<Command>(); 205 List<CommandPackage> packages = new ArrayList<CommandPackage>(); 243 206 packages.addAll(commandPackageList); 244 packages.add( defaultPackage);207 packages.add(new CommandPackage(defaultPackage, this.getClass().getClassLoader())); 245 208 246 209 FilenameFilter filter = new FilenameFilter() { 247 210 @Override 248 211 public boolean accept(File dir, String name) { 249 return 250 (name != null) && (name.startsWith(cmdPrefix)) && (name.endsWith(".class"));212 return (name != null) && (name.startsWith(cmdPrefix)) && 213 (name.endsWith(".class")); 251 214 } 252 215 }; 253 216 254 SortedSet< String> classNames = new TreeSet<String>(new Comparator<String>() {217 SortedSet<Command> commands = new TreeSet<Command>(new Comparator<Command>() { 255 218 @Override 256 public int compare( String arg1, Stringarg2) {257 String str1 = arg1. substring(arg1.lastIndexOf('.') + cmdPrefix.length() + 1);258 String str2 = arg2. substring(arg2.lastIndexOf('.') + cmdPrefix.length() + 1);219 public int compare(Command arg1, Command arg2) { 220 String str1 = arg1.getClass().getSimpleName().substring(cmdPrefix.length()); 221 String str2 = arg2.getClass().getSimpleName().substring(cmdPrefix.length()); 259 222 return str1.compareTo(str2); 260 223 } … … 262 225 }); 263 226 264 for ( String packageName : packages) {265 String path = packageName.replace('.', '/');227 for (CommandPackage commandPackage : packages) { 228 String path = commandPackage.getPackageName().replace('.', '/'); 266 229 try { 267 Enumeration<URL> resources = ClassLoader.getSystemResources(path); 230 ClassLoader loader = commandPackage.getClassLoader(); 231 232 if (loader == null) { 233 loader = ClassLoader.getSystemClassLoader(); 234 } 235 236 Enumeration<URL> resources = loader.getResources(path); 268 237 269 238 while (resources.hasMoreElements()) { … … 272 241 273 242 if (packageDir.isDirectory()) { 274 File[] classFiles = packageDir.listFiles(filter); 275 if (classFiles != null) { 276 for (File classFile : classFiles) { 277 String className = classFile.getName().substring 278 (0, classFile.getName().lastIndexOf('.')); 279 classNames.add(packageName + "." + className); 280 } 281 } 243 File[] classFiles = packageDir.listFiles(filter); 244 if (classFiles != null) { 245 for (File classFile : classFiles) { 246 String className = classFile.getName() 247 .substring(0, classFile.getName().lastIndexOf('.')); 248 Class<?> clazz = 249 loader.loadClass(commandPackage.getPackageName() + "." + 250 className); 251 if (Command.class.isAssignableFrom(clazz)) { 252 commands.add((Command) clazz.getConstructor().newInstance()); 253 } 254 } 255 } 282 256 } 283 257 else { … … 298 272 entry = jarInputStream.getNextJarEntry(); 299 273 if ((entry != null) && (!entry.isDirectory()) && 300 274 (entry.getName().startsWith(path))) 301 275 { 302 String className = entry.getName().substring 303 (path.length() + 1, entry.getName().lastIndexOf('.')); 304 classNames.add(packageName + "." + className); 276 String className = entry.getName() 277 .substring(path.length() + 1, 278 entry.getName().lastIndexOf('.')); 279 Class<?> clazz = 280 loader.loadClass(commandPackage.getPackageName() + 281 "." + className); 282 if (Command.class.isAssignableFrom(clazz)) { 283 commands.add((Command) clazz.getConstructor().newInstance()); 284 } 305 285 } 306 286 } … … 309 289 catch (Exception e) { 310 290 e.printStackTrace(); 311 Console.traceln(Level.WARNING, "could not read contents of " + 312 "jar " + jarFile); 291 Console 292 .traceln(Level.WARNING, 293 "could not read contents of " + "jar " + jarFile); 313 294 } 314 295 finally { … … 323 304 } 324 305 catch (IOException e) { 325 Console.traceln 326 (Level.WARNING, "could not read commands of package " + packageName); 306 Console.traceln(Level.WARNING, "could not read commands of package " + 307 commandPackage.getPackageName()); 308 } 309 catch (ClassNotFoundException e) { 310 Console.traceln(Level.WARNING, "could not load a command of package " + 311 commandPackage.getPackageName() + ": " + e); 312 } 313 catch (InstantiationException e) { 314 Console.traceln(Level.WARNING, "could not load a command of package " + 315 commandPackage.getPackageName() + ": " + e); 316 } 317 catch (IllegalAccessException e) { 318 Console.traceln(Level.WARNING, "could not load a command of package " + 319 commandPackage.getPackageName() + ": " + e); 320 } 321 catch (IllegalArgumentException e) { 322 Console.traceln(Level.WARNING, "could not load a command of package " + 323 commandPackage.getPackageName() + ": " + e); 324 } 325 catch (InvocationTargetException e) { 326 Console.traceln(Level.WARNING, "could not load a command of package " + 327 commandPackage.getPackageName() + ": " + e); 328 } 329 catch (NoSuchMethodException e) { 330 Console.traceln(Level.WARNING, "could not load a command of package " + 331 commandPackage.getPackageName() + ": " + e); 332 } 333 catch (SecurityException e) { 334 Console.traceln(Level.WARNING, "could not load a command of package " + 335 commandPackage.getPackageName() + ": " + e); 327 336 } 328 337 } 329 338 330 for (String className : classNames) {331 // class may still be inner classes. Therefore load the command, to332 // see if it is really available and a command.333 Command cmd = loadCMD(className);334 if (cmd != null) {335 commands.add(cmd);336 }337 }338 339 339 availableCommands = commands.toArray(new Command[commands.size()]); 340 340 } 341 341 342 342 return Arrays.copyOf(availableCommands, availableCommands.length); 343 343 } 344 344 345 345 /** 346 346 * <p> … … 351 351 */ 352 352 public List<String> getCommandPackages() { 353 List<String> commandPackageListCopy = new ArrayList<String>(commandPackageList); 354 commandPackageListCopy.add(0, defaultPackage); 353 List<String> commandPackageListCopy = new ArrayList<>(); 354 355 commandPackageListCopy.add(defaultPackage); 356 357 for (CommandPackage pkg : commandPackageList) { 358 commandPackageListCopy.add(pkg.getPackageName()); 359 } 360 355 361 return commandPackageListCopy; 356 362 } … … 359 365 * <p> 360 366 * this method method performs an auto completion of the provided String as far as possible 361 * regarding the available commands. It auto completes to the full command name, if only 362 * one command matches the given prefix. It auto completes to the common denominator, if363 * severalcommands match the prefix367 * regarding the available commands. It auto completes to the full command name, if only one 368 * command matches the given prefix. It auto completes to the common denominator, if several 369 * commands match the prefix 364 370 * </p> 365 371 * 366 * @param commandPrefix the prefix to be auto completed 372 * @param commandPrefix 373 * the prefix to be auto completed 367 374 * 368 375 * @return as described … … 370 377 public String autoCompleteCommand(String commandPrefix) { 371 378 Command[] commands = getAvailableCommands(); 372 379 373 380 String[] completions = new String[commands.length]; 374 381 375 382 for (int i = 0; i < commands.length; i++) { 376 383 completions[i] = commands[i].getClass().getSimpleName().substring(3); 377 384 } 378 385 379 386 return StringTools.autocomplete(commandPrefix, completions); 380 387 } 388 389 /** 390 * represents a command package with a package name and the class loader to use 391 */ 392 private class CommandPackage { 393 /** 394 * the name of the represented package 395 */ 396 private String packageName; 397 398 /** 399 * the class loader to use to load the package 400 */ 401 private ClassLoader classLoader; 402 403 /** 404 * <p> 405 * instantiate the fields 406 * </p> 407 */ 408 public CommandPackage(String packageName, ClassLoader classLoader) { 409 super(); 410 this.packageName = packageName; 411 this.classLoader = classLoader; 412 } 413 414 /** 415 * @return the packageName 416 */ 417 public String getPackageName() { 418 return packageName; 419 } 420 421 /** 422 * @return the classLoader 423 */ 424 public ClassLoader getClassLoader() { 425 return classLoader; 426 } 427 428 } 381 429 }
Note: See TracChangeset
for help on using the changeset viewer.