Coverage Report - org.jtheque.core.managers.module.loaders.ModuleLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
ModuleLoader
0 %
0/53
0 %
0/16
2.1
ModuleLoader$1
0 %
0/3
N/A
2.1
 
 1  
 package org.jtheque.core.managers.module.loaders;
 2  
 
 3  
 import org.apache.commons.logging.LogFactory;
 4  
 import org.jtheque.core.managers.Managers;
 5  
 import org.jtheque.core.managers.beans.ioc.Ioc;
 6  
 import org.jtheque.core.managers.error.InternationalizedError;
 7  
 import org.jtheque.core.managers.error.JThequeError;
 8  
 import org.jtheque.core.managers.module.beans.ModuleContainer;
 9  
 import org.jtheque.utils.io.FileUtils;
 10  
 
 11  
 import java.io.File;
 12  
 import java.io.IOException;
 13  
 import java.lang.reflect.Method;
 14  
 import java.net.MalformedURLException;
 15  
 import java.net.URL;
 16  
 import java.net.URLClassLoader;
 17  
 import java.security.AccessController;
 18  
 import java.security.PrivilegedAction;
 19  
 import java.util.ArrayList;
 20  
 import java.util.Collection;
 21  
 import java.util.jar.JarFile;
 22  
 import java.util.jar.Manifest;
 23  
 import java.util.regex.Pattern;
 24  
 
 25  
 /*
 26  
  * This file is part of JTheque.
 27  
  *
 28  
  * JTheque is free software: you can redistribute it and/or modify
 29  
  * it under the terms of the GNU General Public License as published by
 30  
  * the Free Software Foundation, either version 3 of the License.
 31  
  *
 32  
  * JTheque is distributed in the hope that it will be useful,
 33  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 34  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 35  
  * GNU General Public License for more details.
 36  
  *
 37  
  * You should have received a copy of the GNU General Public License
 38  
  * along with JTheque.  If not, see <http://www.gnu.org/licenses/>.
 39  
  */
 40  
 
 41  
 /**
 42  
  * A loader for the modules.
 43  
  *
 44  
  * @author Baptiste Wicht
 45  
  */
 46  
 public final class ModuleLoader {
 47  0
     private static final Collection<JThequeError> ERRORS = new ArrayList<JThequeError>(10);
 48  0
     private static final Collection<ModuleContainer> MODULES = new ArrayList<ModuleContainer>(10);
 49  0
     private static final Pattern COMMA_DELIMITER_PATTERN = Pattern.compile(";");
 50  
 
 51  
     /**
 52  
      * This is an utility class, not instanciable.
 53  
      */
 54  
     private ModuleLoader() {
 55  0
         super();
 56  0
     }
 57  
 
 58  
     /**
 59  
      * Load the modules.
 60  
      */
 61  
     public static void loadModules() {
 62  0
         FileUtils.clearFolder(Managers.getCore().getFolders().getModulesFolder());
 63  
 
 64  0
         File moduleDir = Managers.getCore().getFolders().getModulesFolder();
 65  
 
 66  0
         File[] files = moduleDir.listFiles(new ModuleFilter());
 67  
 
 68  0
         if (files != null) {
 69  0
             for (File file : files) {
 70  0
                 loadModule(file);
 71  
             }
 72  
         }
 73  0
     }
 74  
 
 75  
     /**
 76  
      * Load a module from the file.
 77  
      *
 78  
      * @param file The Jar File of a module.
 79  
      */
 80  
     private static void loadModule(File file) {
 81  0
         JarFile jarFile = null;
 82  
         try {
 83  0
             jarFile = new JarFile(file);
 84  
 
 85  0
             Manifest manifest = jarFile.getManifest();
 86  
 
 87  0
             if (isValidManifest(manifest, file)) {
 88  0
                 loadModule(file, manifest);
 89  
             }
 90  0
         } catch (IOException e) {
 91  0
             ERRORS.add(new InternationalizedError("error.module.ioexception", new Object[]{file.getName()}));
 92  
         } finally {
 93  0
             FileUtils.close(jarFile);
 94  0
         }
 95  0
     }
 96  
 
 97  
     /**
 98  
      * Test if the manifest of the file is valid.
 99  
      *
 100  
      * @param manifest The
 101  
      * @param file     The file of the manifest.
 102  
      * @return true if the manifest is valid else false.
 103  
      */
 104  
     private static boolean isValidManifest(Manifest manifest, File file) {
 105  0
         if (manifest == null) {
 106  0
             ERRORS.add(new InternationalizedError("error.module.nomanifest", new Object[]{file.getName()}));
 107  
 
 108  0
             return false;
 109  
         }
 110  
 
 111  0
         return true;
 112  
     }
 113  
 
 114  
     /**
 115  
      * Load the module from the file.
 116  
      *
 117  
      * @param file     The module jar file.
 118  
      * @param manifest The module manifest.
 119  
      * @throws MalformedURLException Throw if the URLs to the resources are malformed.
 120  
      */
 121  
     private static void loadModule(File file, Manifest manifest) throws MalformedURLException {
 122  0
         String moduleContext = manifest.getMainAttributes().getValue("Module-Context");
 123  
 
 124  0
         if (moduleContext == null) {
 125  0
             ERRORS.add(new InternationalizedError("error.module.nomodulecontext", new Object[]{file.getName()}));
 126  
         } else {
 127  0
             Ioc.getContainer().addBeansFile(moduleContext);
 128  
 
 129  0
             addResource(file.toURI().toURL());
 130  
 
 131  0
             loadResources(file, manifest);
 132  
         }
 133  0
     }
 134  
 
 135  
     /**
 136  
      * Load all the resources of a module file.
 137  
      *
 138  
      * @param file     The file.
 139  
      * @param manifest The manifest of the file.
 140  
      * @throws MalformedURLException Throws if an error occurs during the loading of the URL.
 141  
      */
 142  
     private static void loadResources(File file, Manifest manifest) throws MalformedURLException {
 143  0
         String resources = manifest.getMainAttributes().getValue("Resources");
 144  
 
 145  0
         if (resources != null) {
 146  0
             String[] libs = COMMA_DELIMITER_PATTERN.split(resources.trim());
 147  
 
 148  0
             for (String lib : libs) {
 149  0
                 File libFile = new File(Managers.getCore().getFolders().getLibrariesFolder(), lib);
 150  
 
 151  0
                 if (libFile.exists()) {
 152  0
                     addResource(libFile.toURI().toURL());
 153  
                 } else {
 154  0
                     ERRORS.add(new InternationalizedError("error.module.libnotexisting", file.getName(), lib));
 155  
                 }
 156  
             }
 157  
         }
 158  0
     }
 159  
 
 160  
     /**
 161  
      * Add a resource.
 162  
      *
 163  
      * @param url The URL of the resource.
 164  
      */
 165  
     static void addResource(URL url) {
 166  
         try {
 167  0
             Class<URLClassLoader> classLoaderClass = URLClassLoader.class;
 168  0
             final Method method = classLoaderClass.getDeclaredMethod("addURL", new Class[]{URL.class});
 169  
 
 170  0
             AccessController.doPrivileged(new PrivilegedAction<Object>() {
 171  
                 @Override
 172  
                 public Object run() {
 173  0
                     method.setAccessible(true);
 174  
 
 175  0
                     return null;
 176  
                 }
 177  
             });
 178  
 
 179  0
             method.invoke(ClassLoader.getSystemClassLoader(), url);
 180  0
         } catch (Exception t) {
 181  0
             LogFactory.getLog(ModuleLoader.class).error(t);
 182  0
         }
 183  
 
 184  0
         LogFactory.getLog(ModuleLoader.class).debug("Add resource to ClassLoader. URL : " + url);
 185  0
     }
 186  
 
 187  
     /**
 188  
      * Return the errors of the loading.
 189  
      *
 190  
      * @return A collection containing all the errors occurred during the loading process.
 191  
      */
 192  
     public static Iterable<JThequeError> getErrors() {
 193  0
         return ERRORS;
 194  
     }
 195  
 
 196  
     /**
 197  
      * Return all the modules.
 198  
      *
 199  
      * @return A collection containing all the loaded modules.
 200  
      */
 201  
     public static Collection<ModuleContainer> getModules() {
 202  0
         return MODULES;
 203  
     }
 204  
 }