commit 5bd5baa5a3ad5faf22d79436f385beb0ec294ff4
Author: Tomáš Šimandl <tomas.simandl@gmail.com>
Date:   Sat Jan 26 12:53:30 2019 +0100

    Add documentation to modularization classes

diff --git a/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleLoader.java b/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleLoader.java
index 8823a64..141a36b 100644
--- a/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleLoader.java
+++ b/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleLoader.java
@@ -7,6 +7,7 @@ import org.apache.logging.log4j.Logger;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FilenameFilter;
+import java.io.IOException;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -18,35 +19,60 @@ import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
 import java.util.stream.Collectors;
 
-public class ModuleLoader {
+/**
+ * @author Tomáš Šimandl
+ */
+class ModuleLoader {
 
     private static final Logger logger = LogManager.getLogger();
+    /** Filter to get only jar files from modules folder. */
     private static final FilenameFilter MODULE_FILTER = (file, name) -> name.contains(".jar");
+    /** Identification of class name in modules manifest. */
     private static final String MODULE_CLASS_IDENTIFIER = "Module-Class";
+    /** Identification of modules visible name in modules manifest. */
     private static final String MODULE_NAME_IDENTIFIER = "Module-Name";
 
+    /** Path to folder where are modules. Path is relative to resources. */
     private final String modulesPath;
+    /** Name of method which must contains every module. */
     private final String methodName;
+    /** Class type of parameter to method which must contains every module. */
     private final Class methodParamClass;
 
-    public ModuleLoader(String modulesPath, String methodName, Class methodParamClass) {
+
+    /**
+     * Only story  input parameters
+     * @param modulesPath Path to folder where are modules. Path is relative to resources.
+     * @param methodName Name of method which must contains every module.
+     * @param methodParamClass Class type of parameter to method which must contains every module.
+     */
+    ModuleLoader(String modulesPath, String methodName, Class methodParamClass) {
         this.modulesPath = modulesPath;
         this.methodName = methodName;
         this.methodParamClass = methodParamClass;
         logger.info("Initializing new ModuleLoader with folder path: " + modulesPath);
     }
 
-    public Set<Pair<String, Class>> loadModules() {
+    /**
+     * Method starts process of loading all modules from modules folder (defined in constructor).
+     * @return set of loaded modules in Pair where key is: 'Visible name' and value: 'Class to be called'.
+     */
+    Set<Pair<String, Class>> loadModules() {
         logger.info("Loading all modules from file.");
         final File[] modules = loadJarFiles();
         return Arrays.stream(modules)
-                .map(this::loadModule)
-                .filter(Optional::isPresent)
-                .map(Optional::get)
-                .collect(Collectors.toSet());
+                .map(this::loadModule) // call method loadModule for every module
+                .filter(Optional::isPresent) // remove modules which were not loaded
+                .map(Optional::get) // extract modules from Optional class
+                .collect(Collectors.toSet()); // return set of modules
     }
 
-    public Optional<File> getModulesFolder() {
+    /**
+     * Method open file given by modules path in constructor, check if folder exists and if it is a directory.
+     * On success return Optional of opened folder otherwise returns empty optional.
+     * @return Optional of opened folder otherwise returns empty optional.
+     */
+    Optional<File> getModulesFolder() {
 
         final URL fileURL = getClass().getClassLoader().getResource(modulesPath);
         if (fileURL == null) {
@@ -69,17 +95,30 @@ public class ModuleLoader {
         }
     }
 
+    /**
+     * Load all jar files from folder given by modules path in constructor.
+     *
+     * @return array of founded jars or empty array
+     */
     private File[] loadJarFiles() {
 
         Optional<File> folderOptional = getModulesFolder();
         if (folderOptional.isPresent()) {
             File[] files = folderOptional.get().listFiles(MODULE_FILTER);
-            logger.info(files == null ? 0 : files.length + " modules were read from file");
+            if (files == null) files = new File[0];
+            logger.info(files.length + " modules were read from file");
             return files;
         }
         return new File[0];
     }
 
+    /**
+     * Load one particular module given by input File containing opened jar file.
+     * Method returns module in Optional in Pair where key is visible modules name and value is access Class from module.
+     *
+     * @param moduleFile opened jar file with module
+     * @return opened module or empty Optional where some error occurs.
+     */
     private Optional<Pair<String, Class>> loadModule(File moduleFile) {
         JarInputStream jis = null;
         try {
diff --git a/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleProvider.java b/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleProvider.java
index db49e9b..eab6937 100644
--- a/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleProvider.java
+++ b/sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleProvider.java
@@ -13,24 +13,43 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.*;
 
+/**
+ * @author Tomáš Šimandl
+ */
 public class ModuleProvider {
 
+    /** Name of accessed method in every module. */
     public static final String METHOD_NAME = "getRawJson";
+    /** Class of input parameter to accessed method in every module. */
     public static final Class METHOD_PARAMETER_CLASS = String.class;
 
     private static final Logger logger = LogManager.getLogger();
+    /** Path to folder with modules relative to resources */
     private static final String MODULES_PATH = "modules";
+    /** Instance of this class used for singleton pattern. */
     private static ModuleProvider instance = null;
 
+    /**
+     * Map containing actual loaded modules. Key is hash of visible name and value is pair of
+     * visible name na accessed method.
+     */
     private ConcurrentMap<String, Pair<String, Class>> modules = new ConcurrentHashMap<>();
+    /** Instance of class ModuleLoader. */
     private final ModuleLoader loader;
-    private boolean watch = true;
 
+    /** Instance of ScheduledExecutorService used for scheduling of module folder watcher. */
     private ScheduledExecutorService executor;
+    /** Instance of ScheduledFuture used for scheduling of module folder watcher. */
     private ScheduledFuture scheduledFuture;
+    /** Instance of WatchService used for watching of folder with modules. */
     private WatchService watcher = null;
 
-
+    /**
+     * Static method for creating only one instance of this class.
+     * Singleton pattern.
+     *
+     * @return one instance of this class for every call.
+     */
     public static ModuleProvider getInstance() {
         if (instance == null) {
             instance = new ModuleProvider();
@@ -38,6 +57,11 @@ public class ModuleProvider {
         return instance;
     }
 
+    /**
+     * Private constructor is used for singleton pattern. Constructor loads (method moduleLoader.loadModules)
+     * and store (method processModules) all modules from folder and start watcher on modules folder.
+     * When watcher fails than is automatically starts new watcher after 5 minutes timeout.
+     */
     private ModuleProvider() {
         this.loader = new ModuleLoader(MODULES_PATH, METHOD_NAME, METHOD_PARAMETER_CLASS);
 
@@ -48,12 +72,14 @@ public class ModuleProvider {
         logger.debug("Scheduling Modules Watcher thread.");
         // task will be scheduled after 1 minute
         // When task ends (on failure) after one minute will be planed again
-        scheduledFuture = executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.MINUTES);
+        scheduledFuture = executor.scheduleWithFixedDelay(task, 0, 5, TimeUnit.MINUTES);
     }
 
+    /**
+     * Method is used for stopping watcher on modules folder and thread associate with it.
+     */
     public void stopWatcher() {
         logger.debug("Stopping WatcherProvider");
-        watch = false;
 
         try {
             logger.info("Closing WatcherService");
@@ -69,6 +95,11 @@ public class ModuleProvider {
         if (executor != null) executor.shutdown();
     }
 
+    /**
+     * Method open folder with modules and starts watcher on folder. Watcher is activated when any file is created,
+     * deleted of modified in modules folder. Activation of watcher run loading (method moduleLoader.loadModules)
+     * and storing (method processModules) of all modules.
+     */
     private void initModulesWatcher() {
         try {
             logger.debug("Initializing new WatcherService for modules directory");
@@ -101,7 +132,7 @@ public class ModuleProvider {
                     break; // watching only one folder and loading all files every loop => Only one iteration is needed.
                 }
 
-                if (!key.reset() || !watch) {
+                if (!key.reset()) {
                     logger.warn("Stopping modules directory watcher");
                     break;
                 }
@@ -112,6 +143,13 @@ public class ModuleProvider {
         }
     }
 
+    /**
+     * Method is used for prepare loaded modules to be used in application. Result is stored in modules variable.
+     * First of all is created new map where keys are hash of first arguments of input pairs and values are input pairs.
+     * Than variable modules is cleared and all values from created map is insert to it.
+     *
+     * @param unprocessedModules Set of loaded modules where first argument is visible name and second is accessible method.
+     */
     private void processModules(Set<Pair<String, Class>> unprocessedModules) {
         long startTime = System.nanoTime();
         Map<String, Pair<String, Class>> localModules = new HashMap<>();
@@ -127,6 +165,12 @@ public class ModuleProvider {
         logger.debug("Modules were loaded and processed in " + (System.nanoTime() - startTime) / 1000000d + " milliseconds");
     }
 
+    /**
+     * Return all loaded modules in map where value is Pair of visible name and module accessible method and key is
+     * hash code of visible name.
+     * 
+     * @return all loaded modules.
+     */
     public Map<String, Pair<String, Class>> getModules() {
         return modules;
     }
