Ignore:
Timestamp:
05/10/18 16:04:51 (6 years ago)
Author:
davidb
Message:

Reworking of the code-base to separate logic from graphics. This version of Expeditee now supports a JFX graphics as an alternative to SWING

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/reflection/PackageLoader.java

    r919 r1102  
    3636public class PackageLoader {
    3737
    38     // The following is adapted from:
    39     // http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath
    40 
    41     public static List<Class<?>> getClassesNew(String packageName)
    42             throws ClassNotFoundException {
    43 
    44         ClassLoader classLoader = Thread.currentThread()
    45                 .getContextClassLoader();
    46 
    47         ArrayList<String> names = new ArrayList<String>();
    48         ;
    49         final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
    50 
    51         String realPackageName = packageName;
    52         packageName = packageName.replace(".", "/");
    53         URL packageURL = classLoader.getResource(packageName);
    54 
    55         if (packageURL.getProtocol().equals("jar")) {
    56 
    57             // build jar file name, then loop through zipped entries
    58 
    59             String jarFileNameUndecoded = packageURL.getFile();
    60 
    61             try {
    62                 JarURLConnection ju_connection = (JarURLConnection) packageURL
    63                         .openConnection();
    64                 JarFile jf = ju_connection.getJarFile();
    65 
    66                 Enumeration<JarEntry> jarEntries = jf.entries();
    67                 while (jarEntries.hasMoreElements()) {
    68                     String entryName = jarEntries.nextElement().getName();
    69 
    70                     if (entryName.startsWith(packageName)) {
    71 
    72                         if (entryName.endsWith(".class")
    73                                 && !entryName.contains("$")) {
    74 
    75                             // Deal with situation where the class found might
    76                             // be a further sub-package
    77                             // e.g. for "org.expeditee.action"
    78                             // there is:
    79                             // org/expeditee/action/widgets/Chart.class
    80                             // which would produce a value of 'entryName' as
    81                             // widgets/Chart.class
    82 
    83                             entryName = entryName.substring(0,
    84                                     entryName.length() - 6); // 6 = '.class'
    85                             entryName = entryName.replace('/', '.');
    86 
    87                             names.add(entryName);
    88                             classes.add(Class.forName(entryName));
    89                         }
    90                     }
     38        // The following is adapted from:
     39        // http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath
     40
     41        public static List<Class<?>> getClassesNew(String packageName) throws ClassNotFoundException
     42        {
     43                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
     44
     45                ArrayList<String> names = new ArrayList<String>();
     46
     47                final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
     48
     49                String realPackageName = packageName;
     50                packageName = packageName.replace(".", "/");
     51                URL packageURL = classLoader.getResource(packageName);
     52
     53                if (packageURL.getProtocol().equals("jar")) {
     54
     55                        // build jar file name, then loop through zipped entries
     56
     57                        String jarFileNameUndecoded = packageURL.getFile();
     58
     59                        try {
     60                                JarURLConnection ju_connection = (JarURLConnection) packageURL
     61                                                .openConnection();
     62                                JarFile jf = ju_connection.getJarFile();
     63
     64                                Enumeration<JarEntry> jarEntries = jf.entries();
     65                                while (jarEntries.hasMoreElements()) {
     66                                        String entryName = jarEntries.nextElement().getName();
     67
     68                                        if (entryName.startsWith(packageName)) {
     69
     70                                                if (entryName.endsWith(".class")
     71                                                                && !entryName.contains("$")) {
     72
     73                                                        // Deal with situation where the class found might
     74                                                        // be a further sub-package
     75                                                        // e.g. for "org.expeditee.action"
     76                                                        // there is:
     77                                                        // org/expeditee/action/widgets/Chart.class
     78                                                        // which would produce a value of 'entryName' as
     79                                                        // widgets/Chart.class
     80
     81                                                        entryName = entryName.substring(0,
     82                                                                        entryName.length() - 6); // 6 = '.class'
     83                                                        entryName = entryName.replace('/', '.');
     84
     85                                                        names.add(entryName);
     86                                                        classes.add(Class.forName(entryName));
     87                                                }
     88                                        }
     89                                }
     90                        } catch (Exception e) {
     91                                System.err.println("Failed to decode jar file: "
     92                                                + jarFileNameUndecoded);
     93                                e.printStackTrace();
     94                        }
     95                } else if (packageURL.getProtocol().equals("bundleresource")) {
     96                        try {
     97                                final URLConnection urlConnection = packageURL.openConnection();
     98                                final Class<?> c = urlConnection.getClass();
     99                                final java.lang.reflect.Method toInvoke = c.getMethod("getFileURL");
     100                                final URL fileURL = (URL)toInvoke.invoke(urlConnection);
     101                                final File folder = new File(fileURL.getFile());
     102                                final List<String> files = findFiles(folder);
     103                                for (final String s : files) {
     104                                        String entryName = realPackageName + s;
     105                                        if (entryName.endsWith(".class") && !entryName.contains("$")) {
     106                                                entryName = entryName.substring(0, entryName.lastIndexOf('.'));
     107                                                entryName = entryName.replace('/', '.');
     108                                                names.add(entryName);
     109                                                try {
     110                                                        final Class<?> tmpc = Class.forName(entryName);
     111                                                        classes.add(tmpc);
     112                                                } catch (NoClassDefFoundError e) {
     113                                                        System.err.println("Unable to instantiate class " + entryName);
     114                                                        System.err.println(e.getMessage());
     115                                                }
     116                                        }
     117                                }
     118                        } catch (final Exception e) {
     119                                System.err.println("Failed to process file: " + packageName);
     120                                e.printStackTrace();
     121                        }
     122                } else {
     123                        // loop through files in classpath
     124
     125                        String packageURLString = packageURL.toString();
     126                        try {
     127                                URI uri = new URI(packageURLString);
     128                                File folder = new File(uri.getPath());
     129
     130                                List<String> files = findFiles(folder);
     131                                for (String s : files) {
     132                                        String entryName = realPackageName + s;
     133
     134                                        if (entryName.endsWith(".class")
     135                                                        && !entryName.contains("$")) {
     136                                                entryName = entryName.substring(0,
     137                                                                entryName.lastIndexOf('.'));
     138                                                entryName = entryName.replace('/', '.');
     139
     140                                                names.add(entryName);
     141                                                classes.add(Class.forName(entryName));
     142                                        }
     143                                }
     144                        } catch (Exception e) {
     145                                System.err.println("Failed to process file: "
     146                                                + packageURLString);
     147                                e.printStackTrace();
     148                        }
    91149                }
    92             } catch (Exception e) {
    93                 System.err.println("Failed to decode jar file: "
    94                         + jarFileNameUndecoded);
    95                 e.printStackTrace();
    96             }
    97         } else if (packageURL.getProtocol().equals("bundleresource")) {
    98             try {
    99                 final URLConnection urlConnection = packageURL.openConnection();
    100                 final Class<?> c = urlConnection.getClass();
    101                 final java.lang.reflect.Method toInvoke = c.getMethod("getFileURL");
    102                 final URL fileURL = (URL)toInvoke.invoke(urlConnection);
    103                 final File folder = new File(fileURL.getFile());
    104                 final List<String> files = findFiles(folder);
    105                 for (final String s : files) {
    106                     String entryName = realPackageName + s;
    107                     if (entryName.endsWith(".class") && !entryName.contains("$")) {
    108                         entryName = entryName.substring(0, entryName.lastIndexOf('.'));
    109                         entryName = entryName.replace('/', '.');
    110                         names.add(entryName);
     150
     151                return classes;
     152        }
     153
     154        /**
     155         * Finds all files in a directory and it's subdirectories
     156         *
     157         * @param directory
     158         *            The folder to start in
     159         *
     160         * @return A list of Strings containing file paths relative to the starting
     161         *         directory
     162         */
     163        private static List<String> findFiles(File directory) {
     164                List<String> files = new LinkedList<String>();
     165                for (File f : directory.listFiles()) {
     166                        if (f.isDirectory()) {
     167                                for (String s : findFiles(f)) {
     168                                        files.add(f.getName() + "/" + s);
     169                                }
     170                        } else {
     171                                files.add(f.getName());
     172                        }
     173                }
     174                return files;
     175        }
     176
     177        public static List<Class<?>> getClasses(final String pckgname)
     178                        throws ClassNotFoundException {
     179
     180                final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
     181
     182                // Must be a forward slash for loading resources
     183                final String packagePath = pckgname.replace('.', '/');
     184
     185                if (System.getProperty("eclipse.expeditee.home") == null) {
     186                        final ClassLoader cld = Thread.currentThread()
     187                                        .getContextClassLoader();
     188                        if (cld == null) {
     189                                throw new ClassNotFoundException("Can't get class loader.");
     190                        }
     191                        URL resource = null;
    111192                        try {
    112                             final Class<?> tmpc = Class.forName(entryName);
    113                             classes.add(tmpc);
    114                         } catch (NoClassDefFoundError e) {
    115                             System.err.println("Unable to instantiate class " + entryName);
    116                             System.err.println(e.getMessage());
    117                         }
    118                     }
     193                                final Enumeration<URL> resources = cld
     194                                                .getResources(packagePath);
     195                                while (resources.hasMoreElements()) {
     196                                        URL url = resources.nextElement();
     197                                        resource = url;
     198                                }
     199                        } catch (IOException e) {
     200                                System.err
     201                                .println("A IO Error has occured when trying to use the ContextClassLoader"
     202                                                + System.getProperty("line.separator")
     203                                                + "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
     204                                                + " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
     205                                                + System.getProperty("eclipse.expeditee.home")
     206                                                + "'"
     207                                                + System.getProperty("line.separator")
     208                                                + "You can set it by adding a VM argument.  "
     209                                                + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
     210                                e.printStackTrace();
     211                        }
     212                        if (resource == null) {
     213                                throw new ClassNotFoundException("No resource for "
     214                                                + packagePath);
     215                        }
     216                        final File directory = new File(resource.getFile());
     217
     218                        final int splitPoint = directory.getPath().indexOf('!');
     219                        if (splitPoint > 0) {
     220                                String jarName = directory.getPath().substring(
     221                                                "file:".length(), splitPoint);
     222                                // Windows HACK
     223                                if (jarName.indexOf(":") >= 0)
     224                                        jarName = jarName.substring(1);
     225
     226                                if (jarName.indexOf("%20") > 0) {
     227                                        jarName = jarName.replace("%20", " ");
     228                                }
     229                                // System.out.println("JarName:" + jarName);
     230                                try {
     231                                        final JarFile jarFile = new JarFile(jarName);
     232                                        final Enumeration<?> entries = jarFile.entries();
     233                                        while (entries.hasMoreElements()) {
     234                                                final ZipEntry entry = (ZipEntry) entries.nextElement();
     235                                                final String className = entry.getName();
     236                                                if (className.startsWith(packagePath)) {
     237                                                        if (className.endsWith(".class")
     238                                                                        && !className.contains("$")) {
     239                                                                // The forward slash below is a forwards slash
     240                                                                // for
     241                                                                // both windows and linux
     242
     243                                                                String class_forname = className.substring(0,
     244                                                                                className.length() - 6);
     245                                                                class_forname = class_forname.replace('/', '.');
     246
     247                                                                classes.add(Class.forName(class_forname));
     248                                                        }
     249                                                }
     250                                        }
     251                                        try {
     252                                                jarFile.close();
     253                                        } catch (IOException e) {
     254                                                System.err
     255                                                .println("Error attempting to close Jar file");
     256                                                e.printStackTrace();
     257                                        }
     258                                } catch (IOException e) {
     259                                        System.err.println("Error Instantiating Jar File Object");
     260                                        e.printStackTrace();
     261                                }
     262                        } else {
     263
     264                                System.err
     265                                .println("A Error has occured when trying to use a Jar file to find actions or agents."
     266                                                + System.getProperty("line.separator")
     267                                                + "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
     268                                                + " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
     269                                                + System.getProperty("eclipse.expeditee.home")
     270                                                + "'"
     271                                                + System.getProperty("line.separator")
     272                                                + "You can set it by adding a VM argument.  "
     273                                                + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
     274                        }
     275                } else {
     276                        String eclipse_expeditee_home = System.getProperty(
     277                                        "eclipse.expeditee.home", "");
     278                        String full_package_path = eclipse_expeditee_home + File.separator
     279                                        + "bin" + File.separator + packagePath;
     280
     281                        final File directory = new File(full_package_path);
     282
     283                        if (directory.exists()) {
     284                                // Get the list of the files contained in the package
     285                                String[] files = directory.list();
     286                                for (int i = 0; i < files.length; i++) {
     287                                        // we are only interested in .class files
     288                                        if (files[i].endsWith(".class") && !files[i].contains("$")
     289                                                        && !files[i].equals("Actions.class")) {
     290                                                // removes the .class extension
     291                                                classes.add(Class.forName(pckgname
     292                                                                + files[i].substring(0, files[i].length() - 6)));
     293                                        }
     294                                }
     295                        } else {
     296                                throw new ClassNotFoundException("The package '" + pckgname
     297                                                + "' in the directory '" + directory
     298                                                + "' does not appear to be a valid package");
     299                        }
    119300                }
    120             } catch (final Exception e) {
    121                 System.err.println("Failed to process file: " + packageName);
    122                 e.printStackTrace();
    123             }
    124         } else {
    125             // loop through files in classpath
    126 
    127             String packageURLString = packageURL.toString();
    128             try {
    129                 URI uri = new URI(packageURLString);
    130                 File folder = new File(uri.getPath());
    131 
    132                 List<String> files = findFiles(folder);
    133                 for (String s : files) {
    134                     String entryName = realPackageName + s;
    135 
    136                     if (entryName.endsWith(".class")
    137                             && !entryName.contains("$")) {
    138                         entryName = entryName.substring(0,
    139                                 entryName.lastIndexOf('.'));
    140                         entryName = entryName.replace('/', '.');
    141 
    142                         names.add(entryName);
    143                         classes.add(Class.forName(entryName));
    144                     }
    145                 }
    146             } catch (Exception e) {
    147                 System.err.println("Failed to process file: "
    148                         + packageURLString);
    149                 e.printStackTrace();
    150             }
     301                return classes;
    151302        }
    152303
    153         return classes;
    154     }
    155 
    156     /**
    157      * Finds all files in a directory and it's subdirectories
    158      *
    159      * @param directory
    160      *            The folder to start in
    161      *
    162      * @return A list of Strings containing file paths relative to the starting
    163      *         directory
    164      */
    165     private static List<String> findFiles(File directory) {
    166         List<String> files = new LinkedList<String>();
    167         for (File f : directory.listFiles()) {
    168             if (f.isDirectory()) {
    169                 for (String s : findFiles(f)) {
    170                     files.add(f.getName() + "/" + s);
    171                 }
    172             } else {
    173                 files.add(f.getName());
    174             }
    175         }
    176         return files;
    177     }
    178 
    179     public static List<Class<?>> getClasses(final String pckgname)
    180             throws ClassNotFoundException {
    181 
    182         final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
    183 
    184         // Must be a forward slash for loading resources
    185         final String packagePath = pckgname.replace('.', '/');
    186 
    187         if (System.getProperty("eclipse.expeditee.home") == null) {
    188             final ClassLoader cld = Thread.currentThread()
    189                     .getContextClassLoader();
    190             if (cld == null) {
    191                 throw new ClassNotFoundException("Can't get class loader.");
    192             }
    193             URL resource = null;
    194             try {
    195                 final Enumeration<URL> resources = cld
    196                         .getResources(packagePath);
    197                 while (resources.hasMoreElements()) {
    198                     URL url = resources.nextElement();
    199                     resource = url;
    200                 }
    201             } catch (IOException e) {
    202                 System.err
    203                         .println("A IO Error has occured when trying to use the ContextClassLoader"
    204                                 + System.getProperty("line.separator")
    205                                 + "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
    206                                 + " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
    207                                 + System.getProperty("eclipse.expeditee.home")
    208                                 + "'"
    209                                 + System.getProperty("line.separator")
    210                                 + "You can set it by adding a VM argument.  "
    211                                 + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
    212                 e.printStackTrace();
    213             }
    214             if (resource == null) {
    215                 throw new ClassNotFoundException("No resource for "
    216                         + packagePath);
    217             }
    218             final File directory = new File(resource.getFile());
    219 
    220             final int splitPoint = directory.getPath().indexOf('!');
    221             if (splitPoint > 0) {
    222                 String jarName = directory.getPath().substring(
    223                         "file:".length(), splitPoint);
    224                 // Windows HACK
    225                 if (jarName.indexOf(":") >= 0)
    226                     jarName = jarName.substring(1);
    227 
    228                 if (jarName.indexOf("%20") > 0) {
    229                     jarName = jarName.replace("%20", " ");
    230                 }
    231                 // System.out.println("JarName:" + jarName);
    232                 try {
    233                     final JarFile jarFile = new JarFile(jarName);
    234                     final Enumeration<?> entries = jarFile.entries();
    235                     while (entries.hasMoreElements()) {
    236                         final ZipEntry entry = (ZipEntry) entries.nextElement();
    237                         final String className = entry.getName();
    238                         if (className.startsWith(packagePath)) {
    239                             if (className.endsWith(".class")
    240                                     && !className.contains("$")) {
    241                                 // The forward slash below is a forwards slash
    242                                 // for
    243                                 // both windows and linux
    244 
    245                                 String class_forname = className.substring(0,
    246                                         className.length() - 6);
    247                                 class_forname = class_forname.replace('/', '.');
    248 
    249                                 classes.add(Class.forName(class_forname));
    250                             }
    251                         }
    252                     }
    253                     try {
    254                         jarFile.close();
    255                     } catch (IOException e) {
    256                         System.err
    257                                 .println("Error attempting to close Jar file");
    258                         e.printStackTrace();
    259                     }
    260                 } catch (IOException e) {
    261                     System.err.println("Error Instantiating Jar File Object");
    262                     e.printStackTrace();
    263                 }
    264             } else {
    265 
    266                 System.err
    267                         .println("A Error has occured when trying to use a Jar file to find actions or agents."
    268                                 + System.getProperty("line.separator")
    269                                 + "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
    270                                 + " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
    271                                 + System.getProperty("eclipse.expeditee.home")
    272                                 + "'"
    273                                 + System.getProperty("line.separator")
    274                                 + "You can set it by adding a VM argument.  "
    275                                 + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
    276             }
    277         } else {
    278             String eclipse_expeditee_home = System.getProperty(
    279                     "eclipse.expeditee.home", "");
    280             String full_package_path = eclipse_expeditee_home + File.separator
    281                     + "bin" + File.separator + packagePath;
    282 
    283             final File directory = new File(full_package_path);
    284 
    285             if (directory.exists()) {
    286                 // Get the list of the files contained in the package
    287                 String[] files = directory.list();
    288                 for (int i = 0; i < files.length; i++) {
    289                     // we are only interested in .class files
    290                     if (files[i].endsWith(".class") && !files[i].contains("$")
    291                             && !files[i].equals("Actions.class")) {
    292                         // removes the .class extension
    293                         classes.add(Class.forName(pckgname
    294                                 + files[i].substring(0, files[i].length() - 6)));
    295                     }
    296                 }
    297             } else {
    298                 throw new ClassNotFoundException("The package '" + pckgname
    299                         + "' in the directory '" + directory
    300                         + "' does not appear to be a valid package");
    301             }
    302         }
    303         return classes;
    304     }
    305 
    306304}
Note: See TracChangeset for help on using the changeset viewer.