Ignore:
Timestamp:
08/02/19 13:39:17 (5 years ago)
Author:
pharms
Message:

made plugin command loading work with Java 11 (hopefully) :-)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/java-utils/src/main/java/de/ugoe/cs/util/console/CommandExecuter.java

    r2260 r2281  
    1212//   See the License for the specific language governing permissions and 
    1313//   limitations under the License. 
    14  
    1514 
    1615package de.ugoe.cs.util.console; 
     
    8180     * </p> 
    8281     */ 
    83     private List<String> commandPackageList; 
    84      
     82    private List<CommandPackage> commandPackageList; 
     83 
    8584    /** 
    8685     * <p> 
     
    108107     */ 
    109108    private CommandExecuter() { 
    110         commandPackageList = new ArrayList<String>(); 
     109        commandPackageList = new ArrayList<CommandPackage>(); 
    111110    } 
    112111 
     
    121120     *             thrown if the package name is null or empty string 
    122121     */ 
    123     public void addCommandPackage(String pkg) { 
     122    public void addCommandPackage(String pkg, ClassLoader loader) { 
    124123        if ("".equals(pkg) || pkg == null) { 
    125124            throw new IllegalArgumentException("package name must not be null or empty string"); 
    126125        } 
    127         commandPackageList.add(pkg); 
     126        commandPackageList.add(new CommandPackage(pkg, loader)); 
     127        availableCommands = null; 
    128128    } 
    129129 
     
    148148    public void exec(String command) { 
    149149        Console.commandNotification(command); 
    150         Command cmd = null; 
    151150        CommandParser parser = new CommandParser(); 
    152151        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 
    159155        if (cmd == null) { 
    160156            Console.println("Unknown command"); 
     
    186182     *         otherwise 
    187183     */ 
    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 className 
    216      *            qualified name of the class (including package name) 
    217      * @return if class is available and implement {@link Command} and instance of the class, null 
    218      *         otherwise 
    219      */ 
    220184    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; 
    229192    } 
    230193 
     
    239202    public Command[] getAvailableCommands() { 
    240203        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>(); 
    243206            packages.addAll(commandPackageList); 
    244             packages.add(defaultPackage); 
     207            packages.add(new CommandPackage(defaultPackage, this.getClass().getClassLoader())); 
    245208 
    246209            FilenameFilter filter = new FilenameFilter() { 
    247210                @Override 
    248211                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")); 
    251214                } 
    252215            }; 
    253216 
    254             SortedSet<String> classNames = new TreeSet<String>(new Comparator<String>() { 
     217            SortedSet<Command> commands = new TreeSet<Command>(new Comparator<Command>() { 
    255218                @Override 
    256                 public int compare(String arg1, String arg2) { 
    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()); 
    259222                    return str1.compareTo(str2); 
    260223                } 
     
    262225            }); 
    263226 
    264             for (String packageName : packages) { 
    265                 String path = packageName.replace('.', '/'); 
     227            for (CommandPackage commandPackage : packages) { 
     228                String path = commandPackage.getPackageName().replace('.', '/'); 
    266229                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); 
    268237 
    269238                    while (resources.hasMoreElements()) { 
     
    272241 
    273242                        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                            } 
    282256                        } 
    283257                        else { 
     
    298272                                        entry = jarInputStream.getNextJarEntry(); 
    299273                                        if ((entry != null) && (!entry.isDirectory()) && 
    300                                                 (entry.getName().startsWith(path))) 
     274                                            (entry.getName().startsWith(path))) 
    301275                                        { 
    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                                            } 
    305285                                        } 
    306286                                    } 
     
    309289                                catch (Exception e) { 
    310290                                    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); 
    313294                                } 
    314295                                finally { 
     
    323304                } 
    324305                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); 
    327336                } 
    328337            } 
    329338 
    330             for (String className : classNames) { 
    331                 // class may still be inner classes. Therefore load the command, to 
    332                 // 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  
    339339            availableCommands = commands.toArray(new Command[commands.size()]); 
    340340        } 
    341          
     341 
    342342        return Arrays.copyOf(availableCommands, availableCommands.length); 
    343343    } 
    344      
     344 
    345345    /** 
    346346     * <p> 
     
    351351     */ 
    352352    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 
    355361        return commandPackageListCopy; 
    356362    } 
     
    359365     * <p> 
    360366     * 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, if 
    363      * several commands match the prefix 
     367     * 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 
    364370     * </p> 
    365371     * 
    366      * @param commandPrefix the prefix to be auto completed 
     372     * @param commandPrefix 
     373     *            the prefix to be auto completed 
    367374     *  
    368375     * @return as described 
     
    370377    public String autoCompleteCommand(String commandPrefix) { 
    371378        Command[] commands = getAvailableCommands(); 
    372          
     379 
    373380        String[] completions = new String[commands.length]; 
    374          
     381 
    375382        for (int i = 0; i < commands.length; i++) { 
    376383            completions[i] = commands[i].getClass().getSimpleName().substring(3); 
    377384        } 
    378          
     385 
    379386        return StringTools.autocomplete(commandPrefix, completions); 
    380387    } 
     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    } 
    381429} 
Note: See TracChangeset for help on using the changeset viewer.