001package org.intellimate.izou.main;
002
003import org.apache.logging.log4j.LogManager;
004import org.apache.logging.log4j.Logger;
005import org.intellimate.izou.activator.ActivatorManager;
006import org.intellimate.izou.addon.AddOnManager;
007import org.intellimate.izou.addon.AddOnModel;
008import org.intellimate.izou.events.EventDistributor;
009import org.intellimate.izou.events.LocalEventManager;
010import org.intellimate.izou.identification.InternalIdentificationManager;
011import org.intellimate.izou.output.OutputManager;
012import org.intellimate.izou.resource.ResourceManager;
013import org.intellimate.izou.security.SecurityManager;
014import org.intellimate.izou.support.SystemMail;
015import org.intellimate.izou.system.SystemInitializer;
016import org.intellimate.izou.system.file.FileManager;
017import org.intellimate.izou.system.file.FilePublisher;
018import org.intellimate.izou.system.file.FileSystemManager;
019import org.intellimate.izou.system.javafx.JavaFXInitializer;
020import org.intellimate.izou.system.logger.IzouLogger;
021import org.intellimate.izou.system.sound.SoundManager;
022import org.intellimate.izou.threadpool.ThreadPoolManager;
023
024import java.io.IOException;
025import java.util.List;
026import java.util.concurrent.atomic.AtomicBoolean;
027
028/**
029 * Main Class.
030 *
031 * This is where our journey begins and all the Managers get initialized
032 */
033@SuppressWarnings("FieldCanBeLocal")
034public class Main {
035    public static AtomicBoolean jfxToolKitInit;
036    private static final long INIT_TIME_LIMIT = 10000;
037    private final InternalIdentificationManager internalIdentificationManager;
038    private final OutputManager outputManager;
039    private final ResourceManager resourceManager;
040    private final EventDistributor eventDistributor;
041    private final LocalEventManager localEventManager;
042    private final ActivatorManager activatorManager;
043    private final AddOnManager addOnManager;
044    private final FileManager fileManager;
045    private final FilePublisher filePublisher;
046    private final IzouLogger izouLogger;
047    private final ThreadPoolManager threadPoolManager;
048    private final SecurityManager securityManager;
049    private final SystemInitializer systemInitializer;
050    private final SoundManager soundManager;
051    private final SystemMail systemMail;
052    private final Logger fileLogger = LogManager.getLogger(this.getClass());
053    private FileSystemManager fileSystemManager;
054
055    /**
056     * Creates a new Main instance with a optionally disabled lib-folder
057     *
058     * @param javaFX true if javaFX should be started, false otherwise
059     * @param disableLibFolder  if true, izou will not load plugin from the lib-folder
060     */
061    private Main(boolean javaFX, boolean disableLibFolder) {
062        this(null, javaFX, disableLibFolder);
063    }
064
065    /**
066     * If you want to debug your Plugin, you can get an Main instance with this Method, JavaFX is disabled
067     *
068     * @param addOns a List of AddOns to run
069     */
070    public Main(List<AddOnModel> addOns) {
071        this(addOns, false, false);
072    }
073
074    /**
075     * If you want to debug your Plugin, you can get an Main instance with this Method
076     *
077     * @param disableLibFolder  if true, izou will not load plugin from the lib-folder
078     * @param addOns a List of AddOns to run
079     */
080    public Main(List<AddOnModel> addOns, boolean disableLibFolder) {
081        this(addOns, false, disableLibFolder);
082    }
083
084    /**
085     * If you want to debug your Plugin, you can get an Main instance with this Method
086     *
087     * @param javaFX true if javaFX should be started, false otherwise
088     * @param disableLibFolder  if true, izou will not load plugin from the lib-folder
089     * @param addOns a List of AddOns to run
090     */
091    public Main(List<AddOnModel> addOns, boolean javaFX, boolean disableLibFolder) {
092        fileLogger.debug("Starting Izou");
093        fileLogger.debug("Initializing...");
094        systemInitializer = initSystem();
095        if (addOns != null) {
096            fileLogger.debug("setting to debug");
097            System.setProperty("debug", "true");
098        }
099
100        internalIdentificationManager = new InternalIdentificationManager(this);
101        addOnManager = new AddOnManager(this);
102        threadPoolManager = new ThreadPoolManager(this);
103        izouLogger = new IzouLogger();
104        outputManager = new OutputManager(this);
105        resourceManager = new ResourceManager(this);
106        eventDistributor = new EventDistributor(this);
107        localEventManager = new LocalEventManager(this);
108        threadPoolManager.getIzouThreadPool().submit(localEventManager);
109        activatorManager = new ActivatorManager(this);
110        filePublisher = new FilePublisher(this);
111        soundManager = new SoundManager(this);
112
113        fileManager = initFileManager();
114
115        systemInitializer.registerWithPropertiesManager();
116
117        setUpJavaFX(javaFX);
118
119        fileLogger.debug("Done initializing.");
120        fileLogger.debug("Adding addons..");
121
122        // Starting security manager
123        systemMail = initMail();
124        securityManager = startSecurity(systemMail);
125
126        if (addOns != null && !disableLibFolder) {
127            fileLogger.debug("adding addons from the parameter without registering");
128            addOnManager.addAddOnsWithoutRegistering(addOns);
129        } else if (addOns != null) {
130            fileLogger.debug("adding and registering addons from the parameter");
131            addOnManager.addAndRegisterAddOns(addOns);
132        }
133        if (!disableLibFolder) {
134            fileLogger.debug("retrieving addons & registering them");
135            addOnManager.retrieveAndRegisterAddOns();
136        }
137    }
138
139    public static void main(String[] args) {
140        if (args.length > 0) {
141            @SuppressWarnings("UnusedAssignment") Main main = new Main(Boolean.getBoolean(args[0]), false);
142        } else {
143            @SuppressWarnings("UnusedAssignment") Main main = new Main(false, false);
144        }
145    }
146
147    private SystemMail initMail() {
148        // Create system mail
149        SystemMail mailTemp = null;
150        try {
151            mailTemp = SystemMail.createSystemMail();
152        } catch (IllegalAccessException e) {
153            fileLogger.fatal("Unable to create a system mail object");
154        }
155        return mailTemp;
156    }
157
158    private void setUpJavaFX(boolean javaFX) {
159        // Starts javaFX if desired
160        if (javaFX) {
161            jfxToolKitInit = new AtomicBoolean(false);
162            JavaFXInitializer.initToolKit();
163            fileLogger.debug("Initializing JavaFX ToolKit");
164
165            long startTime = System.currentTimeMillis();
166            long duration = 0;
167            while (!jfxToolKitInit.get() && duration < INIT_TIME_LIMIT) {
168                duration = System.currentTimeMillis() - startTime;
169                try {
170                    Thread.sleep(5000);
171                } catch (InterruptedException e) {
172                    fileLogger.error("Error happened while thread was sleeping", e);
173                }
174            }
175
176            if (!jfxToolKitInit.get()) {
177                fileLogger.error("Unable to Initialize JavaFX ToolKit");
178            }
179            fileLogger.debug("Done initializing JavaFX ToolKit");
180        }
181    }
182
183    private SecurityManager startSecurity(SystemMail systemMail) {
184        SecurityManager securityManagerTemp;
185        try {
186            securityManagerTemp = SecurityManager.createSecurityManager(systemMail, this);
187        } catch (IllegalAccessException e) {
188            securityManagerTemp = null;
189            fileLogger.fatal("Security manager already exists", e);
190        }
191        if (!Boolean.getBoolean("noSecurity")) {
192            try {
193                System.setSecurityManager(securityManagerTemp);
194            } catch (SecurityException e) {
195                fileLogger.fatal("Security manager already exists", e);
196            }
197        }
198        return securityManagerTemp;
199    }
200
201    private FileManager initFileManager() {
202        FileManager fileManagerTemp;
203        try {
204            fileManagerTemp = new FileManager(this);
205        } catch (IOException e) {
206            fileManagerTemp = null;
207            fileLogger.fatal("Failed to create the FileManager", e);
208        }
209
210        return fileManagerTemp;
211    }
212
213    public SoundManager getSoundManager() {
214        return soundManager;
215    }
216
217    public SecurityManager getSecurityManager() {
218        return securityManager;
219    }
220
221    public OutputManager getOutputManager() {
222        return outputManager;
223    }
224
225    public LocalEventManager getLocalEventManager() {
226        return localEventManager;
227    }
228
229    public ActivatorManager getActivatorManager() {
230        return activatorManager;
231    }
232
233    public AddOnManager getAddOnManager() {
234        return addOnManager;
235    }
236
237    public ResourceManager getResourceManager() {
238        return resourceManager;
239    }
240
241    public EventDistributor getEventDistributor() {
242        return eventDistributor;
243    }
244
245    public ThreadPoolManager getThreadPoolManager() {
246        return threadPoolManager;
247    }
248
249    public FileManager getFileManager() {
250        return fileManager;
251    }
252
253    public FilePublisher getFilePublisher() {
254        return filePublisher;
255    }
256
257    public IzouLogger getIzouLogger() {
258        return izouLogger;
259    }
260
261    public FileSystemManager getFileSystemManager() {
262        return fileSystemManager;
263    }
264
265    public SystemInitializer getSystemInitializer() {
266        return systemInitializer;
267    }
268
269    public InternalIdentificationManager getInternalIdentificationManager() {
270        return internalIdentificationManager;
271    }
272
273    private SystemInitializer initSystem() {
274        // Setting up file system
275        this.fileSystemManager = new FileSystemManager(this);
276        try {
277            fileSystemManager.createIzouFileSystem();
278        } catch (IOException e) {
279            fileLogger.fatal("Failed to create the FileSystemManager", e);
280        }
281
282        SystemInitializer systemInitializer = new SystemInitializer(this);
283        systemInitializer.initSystem();
284        return systemInitializer;
285    }
286}