Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 5bd5baa5

Přidáno uživatelem Tomáš Šimandl před asi 6 roky(ů)

Add documentation to modularization classes

Zobrazit rozdíly:

sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleLoader.java
7 7
import java.io.File;
8 8
import java.io.FileInputStream;
9 9
import java.io.FilenameFilter;
10
import java.io.IOException;
10 11
import java.net.URISyntaxException;
11 12
import java.net.URL;
12 13
import java.net.URLClassLoader;
......
18 19
import java.util.jar.Manifest;
19 20
import java.util.stream.Collectors;
20 21

  
21
public class ModuleLoader {
22
/**
23
 * @author Tomáš Šimandl
24
 */
25
class ModuleLoader {
22 26

  
23 27
    private static final Logger logger = LogManager.getLogger();
28
    /** Filter to get only jar files from modules folder. */
24 29
    private static final FilenameFilter MODULE_FILTER = (file, name) -> name.contains(".jar");
30
    /** Identification of class name in modules manifest. */
25 31
    private static final String MODULE_CLASS_IDENTIFIER = "Module-Class";
32
    /** Identification of modules visible name in modules manifest. */
26 33
    private static final String MODULE_NAME_IDENTIFIER = "Module-Name";
27 34

  
35
    /** Path to folder where are modules. Path is relative to resources. */
28 36
    private final String modulesPath;
37
    /** Name of method which must contains every module. */
29 38
    private final String methodName;
39
    /** Class type of parameter to method which must contains every module. */
30 40
    private final Class methodParamClass;
31 41

  
32
    public ModuleLoader(String modulesPath, String methodName, Class methodParamClass) {
42

  
43
    /**
44
     * Only story  input parameters
45
     * @param modulesPath Path to folder where are modules. Path is relative to resources.
46
     * @param methodName Name of method which must contains every module.
47
     * @param methodParamClass Class type of parameter to method which must contains every module.
48
     */
49
    ModuleLoader(String modulesPath, String methodName, Class methodParamClass) {
33 50
        this.modulesPath = modulesPath;
34 51
        this.methodName = methodName;
35 52
        this.methodParamClass = methodParamClass;
36 53
        logger.info("Initializing new ModuleLoader with folder path: " + modulesPath);
37 54
    }
38 55

  
39
    public Set<Pair<String, Class>> loadModules() {
56
    /**
57
     * Method starts process of loading all modules from modules folder (defined in constructor).
58
     * @return set of loaded modules in Pair where key is: 'Visible name' and value: 'Class to be called'.
59
     */
60
    Set<Pair<String, Class>> loadModules() {
40 61
        logger.info("Loading all modules from file.");
41 62
        final File[] modules = loadJarFiles();
42 63
        return Arrays.stream(modules)
43
                .map(this::loadModule)
44
                .filter(Optional::isPresent)
45
                .map(Optional::get)
46
                .collect(Collectors.toSet());
64
                .map(this::loadModule) // call method loadModule for every module
65
                .filter(Optional::isPresent) // remove modules which were not loaded
66
                .map(Optional::get) // extract modules from Optional class
67
                .collect(Collectors.toSet()); // return set of modules
47 68
    }
48 69

  
49
    public Optional<File> getModulesFolder() {
70
    /**
71
     * Method open file given by modules path in constructor, check if folder exists and if it is a directory.
72
     * On success return Optional of opened folder otherwise returns empty optional.
73
     * @return Optional of opened folder otherwise returns empty optional.
74
     */
75
    Optional<File> getModulesFolder() {
50 76

  
51 77
        final URL fileURL = getClass().getClassLoader().getResource(modulesPath);
52 78
        if (fileURL == null) {
......
69 95
        }
70 96
    }
71 97

  
98
    /**
99
     * Load all jar files from folder given by modules path in constructor.
100
     *
101
     * @return array of founded jars or empty array
102
     */
72 103
    private File[] loadJarFiles() {
73 104

  
74 105
        Optional<File> folderOptional = getModulesFolder();
75 106
        if (folderOptional.isPresent()) {
76 107
            File[] files = folderOptional.get().listFiles(MODULE_FILTER);
77
            logger.info(files == null ? 0 : files.length + " modules were read from file");
108
            if (files == null) files = new File[0];
109
            logger.info(files.length + " modules were read from file");
78 110
            return files;
79 111
        }
80 112
        return new File[0];
81 113
    }
82 114

  
115
    /**
116
     * Load one particular module given by input File containing opened jar file.
117
     * Method returns module in Optional in Pair where key is visible modules name and value is access Class from module.
118
     *
119
     * @param moduleFile opened jar file with module
120
     * @return opened module or empty Optional where some error occurs.
121
     */
83 122
    private Optional<Pair<String, Class>> loadModule(File moduleFile) {
84 123
        JarInputStream jis = null;
85 124
        try {
sources/src/main/java/cz/zcu/kiv/offscreen/modularization/ModuleProvider.java
13 13
import java.util.Set;
14 14
import java.util.concurrent.*;
15 15

  
16
/**
17
 * @author Tomáš Šimandl
18
 */
16 19
public class ModuleProvider {
17 20

  
21
    /** Name of accessed method in every module. */
18 22
    public static final String METHOD_NAME = "getRawJson";
23
    /** Class of input parameter to accessed method in every module. */
19 24
    public static final Class METHOD_PARAMETER_CLASS = String.class;
20 25

  
21 26
    private static final Logger logger = LogManager.getLogger();
27
    /** Path to folder with modules relative to resources */
22 28
    private static final String MODULES_PATH = "modules";
29
    /** Instance of this class used for singleton pattern. */
23 30
    private static ModuleProvider instance = null;
24 31

  
32
    /**
33
     * Map containing actual loaded modules. Key is hash of visible name and value is pair of
34
     * visible name na accessed method.
35
     */
25 36
    private ConcurrentMap<String, Pair<String, Class>> modules = new ConcurrentHashMap<>();
37
    /** Instance of class ModuleLoader. */
26 38
    private final ModuleLoader loader;
27
    private boolean watch = true;
28 39

  
40
    /** Instance of ScheduledExecutorService used for scheduling of module folder watcher. */
29 41
    private ScheduledExecutorService executor;
42
    /** Instance of ScheduledFuture used for scheduling of module folder watcher. */
30 43
    private ScheduledFuture scheduledFuture;
44
    /** Instance of WatchService used for watching of folder with modules. */
31 45
    private WatchService watcher = null;
32 46

  
33

  
47
    /**
48
     * Static method for creating only one instance of this class.
49
     * Singleton pattern.
50
     *
51
     * @return one instance of this class for every call.
52
     */
34 53
    public static ModuleProvider getInstance() {
35 54
        if (instance == null) {
36 55
            instance = new ModuleProvider();
......
38 57
        return instance;
39 58
    }
40 59

  
60
    /**
61
     * Private constructor is used for singleton pattern. Constructor loads (method moduleLoader.loadModules)
62
     * and store (method processModules) all modules from folder and start watcher on modules folder.
63
     * When watcher fails than is automatically starts new watcher after 5 minutes timeout.
64
     */
41 65
    private ModuleProvider() {
42 66
        this.loader = new ModuleLoader(MODULES_PATH, METHOD_NAME, METHOD_PARAMETER_CLASS);
43 67

  
......
48 72
        logger.debug("Scheduling Modules Watcher thread.");
49 73
        // task will be scheduled after 1 minute
50 74
        // When task ends (on failure) after one minute will be planed again
51
        scheduledFuture = executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.MINUTES);
75
        scheduledFuture = executor.scheduleWithFixedDelay(task, 0, 5, TimeUnit.MINUTES);
52 76
    }
53 77

  
78
    /**
79
     * Method is used for stopping watcher on modules folder and thread associate with it.
80
     */
54 81
    public void stopWatcher() {
55 82
        logger.debug("Stopping WatcherProvider");
56
        watch = false;
57 83

  
58 84
        try {
59 85
            logger.info("Closing WatcherService");
......
69 95
        if (executor != null) executor.shutdown();
70 96
    }
71 97

  
98
    /**
99
     * Method open folder with modules and starts watcher on folder. Watcher is activated when any file is created,
100
     * deleted of modified in modules folder. Activation of watcher run loading (method moduleLoader.loadModules)
101
     * and storing (method processModules) of all modules.
102
     */
72 103
    private void initModulesWatcher() {
73 104
        try {
74 105
            logger.debug("Initializing new WatcherService for modules directory");
......
101 132
                    break; // watching only one folder and loading all files every loop => Only one iteration is needed.
102 133
                }
103 134

  
104
                if (!key.reset() || !watch) {
135
                if (!key.reset()) {
105 136
                    logger.warn("Stopping modules directory watcher");
106 137
                    break;
107 138
                }
......
112 143
        }
113 144
    }
114 145

  
146
    /**
147
     * Method is used for prepare loaded modules to be used in application. Result is stored in modules variable.
148
     * First of all is created new map where keys are hash of first arguments of input pairs and values are input pairs.
149
     * Than variable modules is cleared and all values from created map is insert to it.
150
     *
151
     * @param unprocessedModules Set of loaded modules where first argument is visible name and second is accessible method.
152
     */
115 153
    private void processModules(Set<Pair<String, Class>> unprocessedModules) {
116 154
        long startTime = System.nanoTime();
117 155
        Map<String, Pair<String, Class>> localModules = new HashMap<>();
......
127 165
        logger.debug("Modules were loaded and processed in " + (System.nanoTime() - startTime) / 1000000d + " milliseconds");
128 166
    }
129 167

  
168
    /**
169
     * Return all loaded modules in map where value is Pair of visible name and module accessible method and key is
170
     * hash code of visible name.
171
     * 
172
     * @return all loaded modules.
173
     */
130 174
    public Map<String, Pair<String, Class>> getModules() {
131 175
        return modules;
132 176
    }

Také k dispozici: Unified diff