001package org.intellimate.izou.system.file; 002 003import org.intellimate.izou.util.IdentificationSet; 004import org.intellimate.izou.util.IzouModule; 005import org.intellimate.izou.identification.Identification; 006import org.intellimate.izou.identification.IllegalIDException; 007import org.intellimate.izou.main.Main; 008 009import java.util.HashMap; 010import java.util.concurrent.CompletableFuture; 011 012/** 013 * FilePublisher that notifies {@link FileSubscriber} objects. It is triggered when a file is reloaded. Particularly 014 * file subscribers are mapped to {@link ReloadableFile} objects. When a reloadable file is reloaded, all file 015 * subscribers belonging to it are notified. All file subscribers in general can also be notified. 016 */ 017public class FilePublisher extends IzouModule { 018 private HashMap<ReloadableFile, IdentificationSet<FileSubscriber>> fileSubscribers; 019 private IdentificationSet<FileSubscriber> defaultFileSubscribers; 020 021 /** 022 * Creates a new FilePublisher object. There should only be one in Izou 023 * @param main an Instance of main, used to get all the other classes 024 */ 025 public FilePublisher(Main main) { 026 super(main); 027 this.fileSubscribers = new HashMap<>(); 028 this.defaultFileSubscribers = new IdentificationSet<>(false); 029 } 030 031 /** 032 * Registers a {@link FileSubscriber} with a {@link ReloadableFile}. So when the {@code reloadableFile} is reloaded, 033 * the fileSubscriber will be notified. Multiple file subscribers can be registered with the same reloadable file. 034 * 035 * @param reloadableFile the reloadable file that should be observed 036 * @param fileSubscriber the fileSubscriber that should be notified when the reloadable file is reloaded 037 * @param identification the Identification of the FileSubscriber 038 * @throws IllegalIDException not yet implemented 039 */ 040 public void register(ReloadableFile reloadableFile, FileSubscriber fileSubscriber, Identification identification) 041 throws IllegalIDException { 042 IdentificationSet<FileSubscriber> subscribers = fileSubscribers.get(reloadableFile); 043 044 if (subscribers == null) { 045 subscribers = new IdentificationSet<>(false); 046 fileSubscribers.put(reloadableFile, subscribers); 047 } 048 subscribers.add(fileSubscriber, identification); 049 } 050 051 /** 052 * Registers a {@link FileSubscriber} so that whenever any file is reloaded, the fileSubscriber is notified. 053 * 054 * @param fileSubscriber the fileSubscriber that should be notified when the reloadable file is reloaded 055 * @param identification the Identification of the FileSubscriber 056 * @throws IllegalIDException not yet implemented 057 */ 058 public void register(FileSubscriber fileSubscriber, Identification identification) throws IllegalIDException { 059 defaultFileSubscribers.add(fileSubscriber, identification); 060 } 061 062 /** 063 * Unregisters all instances of fileSubscriber found. 064 * 065 * @param fileSubscriber the fileSubscriber to unregister 066 */ 067 public void unregister(FileSubscriber fileSubscriber) { 068 for (IdentificationSet<FileSubscriber> subList : fileSubscribers.values()) { 069 subList.remove(fileSubscriber); 070 } 071 defaultFileSubscribers.remove(fileSubscriber); 072 } 073 074 /** 075 * Notifies all file subscribers registered to {@code reloadableFile} 076 * 077 * @param reloadableFile the ReloadableFile object for which to notify all pertaining file subscribers 078 */ 079 public synchronized void notifyFileSubscribers(ReloadableFile reloadableFile) { 080 notifyDefaultFileSubscribers(); 081 082 IdentificationSet<FileSubscriber> subList = fileSubscribers.get(reloadableFile); 083 if (subList == null) { 084 return; 085 } 086 087 for (FileSubscriber sub : subList) { 088 CompletableFuture.runAsync(sub::update, main.getThreadPoolManager().getAddOnsThreadPool()); 089 } 090 } 091 092 /** 093 * Notifies all file subscribers. 094 */ 095 public synchronized void notifyAllFileSubcribers() { 096 for (IdentificationSet<FileSubscriber> subList : fileSubscribers.values()) { 097 for (FileSubscriber sub : subList) { 098 CompletableFuture.runAsync(sub::update, main.getThreadPoolManager().getAddOnsThreadPool()); 099 } 100 } 101 102 notifyDefaultFileSubscribers(); 103 } 104 105 /** 106 * Notifies all default file subscribers, that is those that will all be notified no matter what. 107 */ 108 public synchronized void notifyDefaultFileSubscribers() { 109 for (FileSubscriber sub : defaultFileSubscribers) { 110 CompletableFuture.runAsync(sub::update, main.getThreadPoolManager().getAddOnsThreadPool()); 111 } 112 } 113 114 /** 115 * Get all subscribers for a {@code reloadableFile} 116 * 117 * @param reloadableFile the {@code reloadableFile} for which to get all subscribers 118 * @return all subscribers for a {@code reloadableFile} 119 */ 120 public IdentificationSet<FileSubscriber> getFileSubscribersForReloadableFile(ReloadableFile reloadableFile) { 121 return fileSubscribers.get(reloadableFile); 122 } 123}