Projet_JAVA_P2P_STRI2A/src/serverP2P/FileWatcher.java
Louis Royer b39eaf270b
All checks were successful
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/head This commit looks good
Fix client not registering when no file in directory (#122)
Fix client not registering when no file in directory
2020-04-12 16:53:47 +02:00

170 lines
4.1 KiB
Java

package serverP2P;
import tools.Logger;
import tools.LogLevel;
import tools.HostItem;
import java.io.File;
import java.util.Vector;
import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import protocolP2P.HashAlgorithm;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
/** Class allowing to keep the tracker informed about file list
* @author Louis Royer
* @author Flavien Haas
* @author JS Auge
* @version 1.0
*/
public abstract class FileWatcher implements Runnable {
protected String[] fileList = new String[0];
protected Logger logger;
protected volatile boolean stop;
protected long time;
protected boolean force;
protected HostItem server;
protected HostItem tracker;
protected String baseDirectory;
protected Map<String, byte[]> sha512 = new HashMap<>();
protected Thread thread;
/** Constructor
* @param logger Logger
* @param millis Time interval before recheck
* @param server HostItem for the server
* @param tracker HostItem for the tracker
* @param baseDirectory Directory to search files
*/
public FileWatcher(Logger logger, long millis, HostItem server, HostItem tracker, String baseDirectory) {
assert logger != null : "Logger is null";
assert server != null : "Server is null";
assert tracker != null : "Tracker is null";
assert baseDirectory != null : "baseDirectory is null";
this.logger = logger;
time = millis;
this.server = server;
this.tracker = tracker;
this.baseDirectory = baseDirectory;
force = true;
}
/** FileList getter
* @return fileList
*/
public String[] getFileList() {
return fileList;
}
/** Sha512 map getter
* @return sha512 hashmap
*/
public Map<String, byte[]> getSha512Map() {
return sha512;
}
/** Allow a manual check
*/
public void trigger() {
if (updateFileList() || force) {
force = false;
writeLog("File list watcher detected changes. Informing tracker.", LogLevel.Info);
registerTracker();
}
}
/** Runnable implementation */
public void run() {
writeLog("File list watcher started : delay " + time + " milliseconds.", LogLevel.Info);
while(!stop) {
trigger();
try {
Thread.sleep(time);
} catch(InterruptedException e) {
writeLog("File list watcher interrupted", LogLevel.Info);
setStop();
}
}
writeLog("File watcher end of loop", LogLevel.Debug);
}
/** Register server on tracker
*/
protected abstract void registerTracker();
/** Update fileList and returns true if different than old list.
* @return true if changed
*/
protected boolean updateFileList() {
File folder = new File(baseDirectory);
Vector<String> v = new Vector<String>();
File[] files = folder.listFiles();
/* Add non-recursively files's names to fileList */
for (File f : files) {
if (f.isFile()) {
v.add(f.getName());
}
}
String[] newFileList = new String[v.size()];
v.toArray(newFileList);
Arrays.sort(newFileList);
if (!Arrays.equals(newFileList, fileList)) {
fileList = newFileList;
initSha512();
return true;
} else {
return false;
}
}
/** Ask the thread to stop
*/
public void setStop() {
stop = true;
if (thread != null) {
thread.interrupt();
}
}
/** Init sha512 map.
*/
protected void initSha512() {
for(String f: fileList) {
try {
MessageDigest md = MessageDigest.getInstance(HashAlgorithm.SHA512.getName());
sha512.put(f, md.digest(Files.readAllBytes(Paths.get(baseDirectory + f))));
md.reset();
} catch (NoSuchAlgorithmException e) {
writeLog("sha512 not supported", LogLevel.Error);
} catch (IOException e) {
writeLog("cannot read " + f, LogLevel.Warning);
}
}
}
/** Implementation of writeLog
* @param text Text to log
* @param logLevel level of logging
*/
protected abstract void writeLog(String text, LogLevel logLevel);
/** Implementation of writeLog
* @param e exception to log
* @param logLevel level of logging
*/
protected abstract void writeLog(Exception e, LogLevel logLevel);
/** Set thread
* @param thread Thread
*/
public void setThread(Thread thread) {
this.thread = thread;
}
}