package org.intellimate.izou.system.file;
import org.intellimate.izou.util.IdentificationSet;
import org.intellimate.izou.util.IzouModule;
import org.intellimate.izou.identification.Identification;
import org.intellimate.izou.identification.IllegalIDException;
import org.intellimate.izou.main.Main;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
/**
* FilePublisher that notifies {@link FileSubscriber} objects. It is triggered when a file is reloaded. Particularly
* file subscribers are mapped to {@link ReloadableFile} objects. When a reloadable file is reloaded, all file
* subscribers belonging to it are notified. All file subscribers in general can also be notified.
*/
public class FilePublisher extends IzouModule {
private HashMap<ReloadableFile, IdentificationSet<FileSubscriber>> fileSubscribers;
private IdentificationSet<FileSubscriber> defaultFileSubscribers;
/**
* Creates a new FilePublisher object. There should only be one in Izou
* @param main an Instance of main, used to get all the other classes
*/
public FilePublisher(Main main) {
super(main);
this.fileSubscribers = new HashMap<>();
this.defaultFileSubscribers = new IdentificationSet<>(false);
}
/**
* Registers a {@link FileSubscriber} with a {@link ReloadableFile}. So when the {@code reloadableFile} is reloaded,
* the fileSubscriber will be notified. Multiple file subscribers can be registered with the same reloadable file.
*
* @param reloadableFile the reloadable file that should be observed
* @param fileSubscriber the fileSubscriber that should be notified when the reloadable file is reloaded
* @param identification the Identification of the FileSubscriber
* @throws IllegalIDException not yet implemented
*/
public void register(ReloadableFile reloadableFile, FileSubscriber fileSubscriber, Identification identification)
throws IllegalIDException {
IdentificationSet<FileSubscriber> subscribers = fileSubscribers.get(reloadableFile);
if (subscribers == null) {
subscribers = new IdentificationSet<>(false);
fileSubscribers.put(reloadableFile, subscribers);
}
subscribers.add(fileSubscriber, identification);
}
/**
* Registers a {@link FileSubscriber} so that whenever any file is reloaded, the fileSubscriber is notified.
*
* @param fileSubscriber the fileSubscriber that should be notified when the reloadable file is reloaded
* @param identification the Identification of the FileSubscriber
* @throws IllegalIDException not yet implemented
*/
public void register(FileSubscriber fileSubscriber, Identification identification) throws IllegalIDException {
defaultFileSubscribers.add(fileSubscriber, identification);
}
/**
* Unregisters all instances of fileSubscriber found.
*
* @param fileSubscriber the fileSubscriber to unregister
*/
public void unregister(FileSubscriber fileSubscriber) {
for (IdentificationSet<FileSubscriber> subList : fileSubscribers.values()) {
subList.remove(fileSubscriber);
}
defaultFileSubscribers.remove(fileSubscriber);
}
/**
* Notifies all file subscribers registered to {@code reloadableFile}
*
* @param reloadableFile the ReloadableFile object for which to notify all pertaining file subscribers
*/
public synchronized void notifyFileSubscribers(ReloadableFile reloadableFile) {
notifyDefaultFileSubscribers();
IdentificationSet<FileSubscriber> subList = fileSubscribers.get(reloadableFile);
if (subList == null) {
return;
}
for (FileSubscriber sub : subList) {
CompletableFuture.runAsync(sub::update, main.getThreadPoolManager().getAddOnsThreadPool());
}
}
/**
* Notifies all file subscribers.
*/
public synchronized void notifyAllFileSubcribers() {
for (IdentificationSet<FileSubscriber> subList : fileSubscribers.values()) {
for (FileSubscriber sub : subList) {
CompletableFuture.runAsync(sub::update, main.getThreadPoolManager().getAddOnsThreadPool());
}
}
notifyDefaultFileSubscribers();
}
/**
* Notifies all default file subscribers, that is those that will all be notified no matter what.
*/
public synchronized void notifyDefaultFileSubscribers() {
for (FileSubscriber sub : defaultFileSubscribers) {
CompletableFuture.runAsync(sub::update, main.getThreadPoolManager().getAddOnsThreadPool());
}
}
/**
* Get all subscribers for a {@code reloadableFile}
*
* @param reloadableFile the {@code reloadableFile} for which to get all subscribers
* @return all subscribers for a {@code reloadableFile}
*/
public IdentificationSet<FileSubscriber> getFileSubscribersForReloadableFile(ReloadableFile reloadableFile) {
return fileSubscribers.get(reloadableFile);
}
}