Lab3 #1

Merged
bytegrip merged 3 commits from lab3 into master 2023-10-16 19:17:02 +00:00
6 changed files with 179 additions and 57 deletions
Showing only changes of commit 4ecd73d4ed - Show all commits

View File

@@ -3,9 +3,16 @@ package org.lumijiez;
import org.lumijiez.gui.MainFrame; import org.lumijiez.gui.MainFrame;
import javax.swing.*; import javax.swing.*;
import java.io.IOException;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true)); SwingUtilities.invokeLater(() -> {
try {
new MainFrame().setVisible(true);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} }
} }

View File

@@ -3,7 +3,10 @@ import org.lumijiez.tracker.TrackerThread;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*;
public class MainFrame extends JFrame { public class MainFrame extends JFrame {
private final JScrollPane fileListScrollPane = new JScrollPane(); private final JScrollPane fileListScrollPane = new JScrollPane();
@@ -19,47 +22,38 @@ public class MainFrame extends JFrame {
private final JMenuItem pickFolder = new JMenuItem(); private final JMenuItem pickFolder = new JMenuItem();
private final JMenu settingsMenu = new JMenu(); private final JMenu settingsMenu = new JMenu();
private final JMenuItem settings = new JMenuItem(); private final JMenuItem settings = new JMenuItem();
private final Map<File, byte[]> fileContents = new HashMap<>();
private TrackerThread tracker;
public MainFrame() { public MainFrame() throws IOException {
initComponents(); initComponents();
} }
private void initComponents() { private void initComponents() {
mainTextPane.setContentType("text/html");
JFileChooser folderChooser = new JFileChooser(); JFileChooser folderChooser = new JFileChooser();
folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = folderChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("Selected folder: " + folderChooser.getSelectedFile().getAbsolutePath());
TrackerThread tr = new TrackerThread(mainTextPane, Path.of(folderChooser.getSelectedFile().getAbsolutePath()));
tr.start();
}
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
fileList.setModel(new AbstractListModel<>() { int returnVal = folderChooser.showOpenDialog(this);
final String[] strings = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}; if (returnVal == JFileChooser.APPROVE_OPTION) {
tracker = new TrackerThread(mainTextPane, Path.of(folderChooser.getSelectedFile().getAbsolutePath()), fileContents, fileList);
public int getSize() { tracker.start();
return strings.length;
} }
public String getElementAt(int i) {
return strings[i];
}
});
fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fileListScrollPane.setViewportView(fileList); fileListScrollPane.setViewportView(fileList);
snapshotLabel.setFont(new java.awt.Font("Trebuchet MS", Font.PLAIN, 18)); // NOI18N snapshotLabel.setFont(new java.awt.Font("Trebuchet MS", Font.PLAIN, 18)); // NOI18N
snapshotLabel.setText("Last snapshot:"); snapshotLabel.setText("Last snapshot: " + new Date());
mainScrollPane.setViewportView(mainTextPane); mainScrollPane.setViewportView(mainTextPane);
pathLabel.setFont(new java.awt.Font("Trebuchet MS", Font.PLAIN, 18)); // NOI18N pathLabel.setFont(new java.awt.Font("Trebuchet MS", Font.PLAIN, 18)); // NOI18N
pathLabel.setText("Currently tracking: "); pathLabel.setText("Currently tracking: " + folderChooser.getSelectedFile().getAbsolutePath());
CommitButton.setText("Commit"); CommitButton.setText("Commit");
CommitButton.addActionListener(this::CommitButtonActionPerformed); CommitButton.addActionListener(this::CommitButtonActionPerformed);
@@ -119,13 +113,14 @@ public class MainFrame extends JFrame {
.addComponent(CommitButton) .addComponent(CommitButton)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addComponent(StatusButton))) .addComponent(StatusButton)))
.addContainerGap()) .addContainerGap()));
);
pack(); pack();
} }
private void CommitButtonActionPerformed(java.awt.event.ActionEvent evt) { private void CommitButtonActionPerformed(java.awt.event.ActionEvent evt) {
tracker.reset();
mainTextPane.setText("");
snapshotLabel.setText("Last snapshot: " + new Date());
} }
private void StatusButtonActionPerformed(java.awt.event.ActionEvent evt) { private void StatusButtonActionPerformed(java.awt.event.ActionEvent evt) {

View File

@@ -1,60 +1,100 @@
package org.lumijiez.tracker; package org.lumijiez.tracker;
import org.lumijiez.util.DiffType;
import org.lumijiez.util.FileDiffer;
import org.lumijiez.util.StateType;
import javax.swing.*; import javax.swing.*;
import java.io.IOException; import java.io.File;
import java.nio.file.*; import java.nio.file.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class TrackerThread extends Thread { public class TrackerThread extends Thread {
private final JTextPane textPane; private final JTextPane textPane;
private final Path path; private final Path path;
private Map<File, byte[]> fileContents;
private final JList<String> fileList;
private final Map<File, StateType> fileStates = new HashMap<>();
public TrackerThread(JTextPane textPane, Path path) { public TrackerThread(JTextPane textPane, Path path, Map<File, byte[]> files, JList<String> fileList) {
this.textPane = textPane; this.textPane = textPane;
this.path = path; this.path = path;
this.fileContents = files;
this.fileList = fileList;
init();
} }
public void checkDirectory(Path path) { public void init() {
try { System.out.println("Init called");
WatchService watchService = FileSystems.getDefault().newWatchService(); fileContents = FileDiffer.crawlDirectory(path);
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);
while (true) { ArrayList<String> fileNames = new ArrayList<>();
WatchKey key;
try { for (File file : fileContents.keySet()) {
key = watchService.take(); fileNames.add(file.getName());
} catch (InterruptedException e) { }
return; fileList.setModel(new AbstractListModel<>() {
public int getSize() {
return fileNames.size();
}
public String getElementAt(int i) {
return fileNames.get(i);
}
});
} }
for (WatchEvent<?> event : key.pollEvents()) { public void reset() {
WatchEvent.Kind<?> kind = event.kind(); fileStates.clear();
}
@SuppressWarnings("unchecked") public void checkDirectory() {
WatchEvent<Path> ev = (WatchEvent<Path>) event; Map<DiffType, ArrayList<File>> result = FileDiffer.diff(fileContents, FileDiffer.crawlDirectory(path));
Path fileName = ev.context();
System.out.println(kind.name() + ": " + fileName); StringBuilder toShow = new StringBuilder();
if (kind == StandardWatchEventKinds.ENTRY_CREATE) { boolean created = false, deleted = false, modified = false;
textPane.setText(textPane.getText() + " file created\n"); if (!result.get(DiffType.CREATE).isEmpty()) {
} else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) { created = true;
textPane.setText(textPane.getText() + " file modified\n"); for (File file : result.get(DiffType.CREATE)) {
} else if (kind == StandardWatchEventKinds.ENTRY_DELETE) { fileStates.put(file, StateType.NEW);
textPane.setText(textPane.getText() + " file deleted\n"); }
System.out.println("Created");
}
if (!result.get(DiffType.DELETE).isEmpty()) {
deleted = true;
for (File file : result.get(DiffType.DELETE)) {
fileStates.put(file, StateType.DELETED);
}
System.out.println("Deleted");
}
if (!result.get(DiffType.MODIFY).isEmpty()) {
modified = true;
for (File file : result.get(DiffType.MODIFY)) {
fileStates.put(file, StateType.MODIFIED);
}
System.out.println("Modified");
}
if (created || deleted || modified) {
init();
for (File file : fileStates.keySet()) {
if (fileStates.get(file) != StateType.NONE) {
toShow.append(file.getName()).append(" has been ").append(fileStates.get(file).getName()).append("<br>");
}
}
textPane.setText(toShow.toString());
} }
} }
boolean valid = key.reset();
if (!valid) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override @Override
public void run() { public void run() {
checkDirectory(path); while(this.isAlive()) {
checkDirectory();
//Thread.sleep(200);
}
} }
} }

View File

@@ -0,0 +1,5 @@
package org.lumijiez.util;
public enum DiffType {
CREATE, DELETE, MODIFY, NONE
}

View File

@@ -0,0 +1,61 @@
package org.lumijiez.util;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class FileDiffer {
public static Map<DiffType, ArrayList<File>> diff(Map<File, byte[]> oldFiles, Map<File, byte[]> newFiles) {
Map<DiffType, ArrayList<File>> result = new HashMap<>();
ArrayList<File> newFileList = new ArrayList<>();
ArrayList<File> deletedFileList = new ArrayList<>();
ArrayList<File> modifiedFileList = new ArrayList<>();
for (File file : oldFiles.keySet()) {
if (newFiles.get(file) != null) {
if (Arrays.compare(oldFiles.get(file), newFiles.get(file)) != 0) {
modifiedFileList.add(file);
}
} else {
deletedFileList.add(file);
}
}
for (File file : newFiles.keySet()) {
if (oldFiles.get(file) == null) {
newFileList.add(file);
}
}
result.put(DiffType.CREATE, newFileList);
result.put(DiffType.DELETE, deletedFileList);
result.put(DiffType.MODIFY, modifiedFileList);
return result;
}
public static Map<File, byte[]> crawlDirectory(Path path) {
Map<File, byte[]> newFileContents = new HashMap<>();
try (Stream<Path> paths = Files.walk(path)) {
paths.forEach(p -> {
if (Files.isRegularFile(p)) {
try {
newFileContents.put(p.toFile(), Files.readAllBytes(p));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
return newFileContents;
}
}

View File

@@ -0,0 +1,14 @@
package org.lumijiez.util;
public enum StateType {
NEW("Created"), MODIFIED("Modified"), DELETED("Deleted"), NONE("Nothing");
private final String name;
StateType(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}