Merge pull request #2 from lumijiez/lab3
Lab3
This commit was merged in pull request #2.
This commit is contained in:
@@ -3,16 +3,9 @@ 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(() -> {
|
SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
|
||||||
try {
|
|
||||||
new MainFrame().setVisible(true);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
20
Lab3/src/main/java/org/lumijiez/base/ArbitraryFile.java
Normal file
20
Lab3/src/main/java/org/lumijiez/base/ArbitraryFile.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package org.lumijiez.base;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class ArbitraryFile extends Document{
|
||||||
|
public ArbitraryFile(Path path) {
|
||||||
|
super(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfo() {
|
||||||
|
StringBuilder info = new StringBuilder();
|
||||||
|
info.append("Type: ").append(getFileType().getTypeName()).append("<br>");
|
||||||
|
info.append("Extension: ").append(getExtension().toUpperCase()).append("<br>");
|
||||||
|
info.append("File size: ").append(getFilesizeKB()).append(" KB").append("<br>");
|
||||||
|
info.append("Created at: ").append(getCreatedTime()).append("<br>");
|
||||||
|
info.append("Modified at: ").append(getModificationTime()).append("<br>");
|
||||||
|
return info.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Lab3/src/main/java/org/lumijiez/base/CodeFile.java
Normal file
25
Lab3/src/main/java/org/lumijiez/base/CodeFile.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package org.lumijiez.base;
|
||||||
|
|
||||||
|
import org.lumijiez.util.Utils;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class CodeFile extends Document{
|
||||||
|
public CodeFile(Path path) {
|
||||||
|
super(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfo() {
|
||||||
|
StringBuilder info = new StringBuilder();
|
||||||
|
info.append("Type: ").append(getFileType().getTypeName()).append("<br>");
|
||||||
|
info.append("Extension: ").append(getExtension().toUpperCase()).append("<br>");
|
||||||
|
info.append("File size: ").append(getFilesizeKB()).append(" KB").append("<br>");
|
||||||
|
info.append("Lines: ").append(Utils.countLines(this)).append("<br>");
|
||||||
|
info.append("Classes: ").append(Utils.countClasses(this)).append("<br>");
|
||||||
|
info.append("Methods: ").append(Utils.countMethods(this)).append("<br>");
|
||||||
|
info.append("Created at: ").append(getCreatedTime()).append("<br>");
|
||||||
|
info.append("Modified at: ").append(getModificationTime()).append("<br>");
|
||||||
|
return info.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
92
Lab3/src/main/java/org/lumijiez/base/Document.java
Normal file
92
Lab3/src/main/java/org/lumijiez/base/Document.java
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package org.lumijiez.base;
|
||||||
|
|
||||||
|
import org.lumijiez.enums.FileType;
|
||||||
|
import org.lumijiez.interfaces.IDocument;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class Document extends File implements IDocument {
|
||||||
|
private String extension;
|
||||||
|
private FileType fileType;
|
||||||
|
|
||||||
|
public Document(Path path) {
|
||||||
|
super(path.toString());
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
int lastDotIndex = getName().lastIndexOf('.');
|
||||||
|
extension = (lastDotIndex > 0) ? getName().substring(lastDotIndex + 1) : "";
|
||||||
|
fileType = FileType.getFileType(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExtension() {
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCreatedTime() {
|
||||||
|
try {
|
||||||
|
BasicFileAttributes fileAttributes = Files.readAttributes(Path.of(this.getPath()), BasicFileAttributes.class);
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yy");
|
||||||
|
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
|
||||||
|
|
||||||
|
Date date = new Date(fileAttributes.creationTime().toMillis());
|
||||||
|
|
||||||
|
String formattedDate = dateFormat.format(date);
|
||||||
|
String formattedTime = timeFormat.format(date);
|
||||||
|
|
||||||
|
return formattedTime + " " + formattedDate;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModificationTime() {
|
||||||
|
try {
|
||||||
|
BasicFileAttributes fileAttributes = Files.readAttributes(Path.of(this.getPath()), BasicFileAttributes.class);
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yy");
|
||||||
|
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
|
||||||
|
|
||||||
|
Date date = new Date(fileAttributes.lastModifiedTime().toMillis());
|
||||||
|
|
||||||
|
String formattedDate = dateFormat.format(date);
|
||||||
|
String formattedTime = timeFormat.format(date);
|
||||||
|
|
||||||
|
return formattedTime + " " + formattedDate;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileType getFileType() {
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getFilesizeKB() {
|
||||||
|
try {
|
||||||
|
BasicFileAttributes fileAttributes = Files.readAttributes(Path.of(this.getPath()), BasicFileAttributes.class);
|
||||||
|
return fileAttributes.size() / 1024;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfo() {
|
||||||
|
return "Name: " + getName() + " Size: " + getFilesizeKB() + "Type: " + getFileType().getTypeName();
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Lab3/src/main/java/org/lumijiez/base/ImageFile.java
Normal file
29
Lab3/src/main/java/org/lumijiez/base/ImageFile.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package org.lumijiez.base;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class ImageFile extends Document {
|
||||||
|
public ImageFile(Path path) {
|
||||||
|
super(path);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getInfo() {
|
||||||
|
try {
|
||||||
|
StringBuilder info = new StringBuilder();
|
||||||
|
info.append("Type: ").append(getFileType().getTypeName()).append("<br>");
|
||||||
|
info.append("Extension: ").append(getExtension().toUpperCase()).append("<br>");
|
||||||
|
BufferedImage image = ImageIO.read(this);
|
||||||
|
info.append("Dimensions: ").append(image.getWidth()).append("x").append(image.getHeight()).append("<br>");
|
||||||
|
info.append("File size: ").append(getFilesizeKB()).append(" KB").append("<br>");
|
||||||
|
info.append("Created at: ").append(getCreatedTime()).append("<br>");
|
||||||
|
info.append("Modified at: ").append(getModificationTime()).append("<br>");
|
||||||
|
return info.toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Lab3/src/main/java/org/lumijiez/base/TextFile.java
Normal file
25
Lab3/src/main/java/org/lumijiez/base/TextFile.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package org.lumijiez.base;
|
||||||
|
|
||||||
|
import org.lumijiez.util.Utils;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class TextFile extends Document {
|
||||||
|
public TextFile(Path path) {
|
||||||
|
super(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfo() {
|
||||||
|
StringBuilder info = new StringBuilder();
|
||||||
|
info.append("Type: ").append(getFileType().getTypeName()).append("<br>");
|
||||||
|
info.append("Extension: ").append(getExtension().toUpperCase()).append("<br>");
|
||||||
|
info.append("File size: ").append(getFilesizeKB()).append(" KB").append("<br>");
|
||||||
|
info.append("Words: ").append(Utils.countWords(this)).append("<br>");
|
||||||
|
info.append("Lines: ").append(Utils.countLines(this)).append("<br>");
|
||||||
|
info.append("Characters: ").append(Utils.countChars(this)).append("<br>");
|
||||||
|
info.append("Created at: ").append(getCreatedTime()).append("<br>");
|
||||||
|
info.append("Modified at: ").append(getModificationTime()).append("<br>");
|
||||||
|
return info.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Lab3/src/main/java/org/lumijiez/enums/DiffType.java
Normal file
15
Lab3/src/main/java/org/lumijiez/enums/DiffType.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package org.lumijiez.enums;
|
||||||
|
|
||||||
|
public enum DiffType {
|
||||||
|
CREATE(StateType.NEW), DELETE(StateType.DELETED), MODIFY(StateType.MODIFIED), NONE(StateType.NONE);
|
||||||
|
|
||||||
|
private final StateType type;
|
||||||
|
|
||||||
|
DiffType(StateType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StateType getState() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
Lab3/src/main/java/org/lumijiez/enums/FileType.java
Normal file
35
Lab3/src/main/java/org/lumijiez/enums/FileType.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package org.lumijiez.enums;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public enum FileType {
|
||||||
|
IMAGE("Image", new ArrayList<>(List.of("jpg", "png"))),
|
||||||
|
PLAINTEXT("Plaintext", new ArrayList<>(List.of("txt", "csv"))),
|
||||||
|
FILE("File", new ArrayList<>(List.of("doc", "pdf", "zip"))),
|
||||||
|
CODE("Code", new ArrayList<>(List.of("java", "cpp", "py"))),
|
||||||
|
NONE("None", new ArrayList<>());
|
||||||
|
|
||||||
|
private final List<String> typeExtensions;
|
||||||
|
private final String typeName;
|
||||||
|
|
||||||
|
FileType(String typeName, ArrayList<String> list) {
|
||||||
|
this.typeName = typeName;
|
||||||
|
this.typeExtensions = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FileType getFileType(String extension) {
|
||||||
|
for (FileType fileType : values()) {
|
||||||
|
if (fileType.typeExtensions.contains(extension.toLowerCase())) {
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypeName() {
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package org.lumijiez.util;
|
package org.lumijiez.enums;
|
||||||
|
|
||||||
public enum StateType {
|
public enum StateType {
|
||||||
NEW("Created"), MODIFIED("Modified"), DELETED("Deleted"), NONE("Nothing");
|
NEW("Created"), MODIFIED("Modified"), DELETED("Deleted"), NONE("Nothing");
|
||||||
|
|
||||||
private final String name;
|
private final String action;
|
||||||
StateType(String name) {
|
StateType(String name) {
|
||||||
this.name = name;
|
this.action = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getAction() {
|
||||||
return this.name;
|
return this.action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,81 +1,81 @@
|
|||||||
package org.lumijiez.gui;
|
package org.lumijiez.gui;
|
||||||
|
import org.lumijiez.base.Document;
|
||||||
import org.lumijiez.tracker.TrackerThread;
|
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.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class MainFrame extends JFrame {
|
public class MainFrame extends JFrame {
|
||||||
|
public static Path FOLDER_PATH;
|
||||||
private final JScrollPane fileListScrollPane = new JScrollPane();
|
private final JScrollPane fileListScrollPane = new JScrollPane();
|
||||||
private final JList<String> fileList = new JList<>();
|
private final JScrollPane fileInfoScrollPane = new JScrollPane();
|
||||||
private final JLabel pathLabel = new JLabel();
|
private final JLabel pathLabel = new JLabel();
|
||||||
private final JScrollPane mainScrollPane = new JScrollPane();
|
private final JScrollPane mainScrollPane = new JScrollPane();
|
||||||
private final JTextPane mainTextPane = new JTextPane();
|
private final JTextPane mainTextPane = new JTextPane();
|
||||||
|
private final JTextPane fileInfoTextPane = new JTextPane();
|
||||||
private final JLabel snapshotLabel = new JLabel();
|
private final JLabel snapshotLabel = new JLabel();
|
||||||
private final JButton CommitButton = new JButton();
|
private final JButton CommitButton = new JButton();
|
||||||
private final JButton StatusButton = new JButton();
|
private final JButton StatusButton = new JButton();
|
||||||
private final JMenuBar MainMenubar = new JMenuBar();
|
private final JMenuBar mainMenubar = new JMenuBar();
|
||||||
private final JMenu fileMenu = new JMenu();
|
private final JMenu fileMenu = new JMenu();
|
||||||
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 final JList<Document> fileList = new JList<>();
|
||||||
|
private final Map<Document, byte[]> fileContents = new HashMap<>();
|
||||||
private TrackerThread tracker;
|
private TrackerThread tracker;
|
||||||
|
|
||||||
public MainFrame() throws IOException {
|
public MainFrame() {
|
||||||
initComponents();
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
|
||||||
|
setResizable(false);
|
||||||
|
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
mainTextPane.setContentType("text/html");
|
mainTextPane.setContentType("text/html");
|
||||||
|
fileInfoTextPane.setContentType("text/html");
|
||||||
|
|
||||||
|
mainTextPane.setEditable(false);
|
||||||
|
fileInfoTextPane.setEditable(false);
|
||||||
|
|
||||||
JFileChooser folderChooser = new JFileChooser();
|
JFileChooser folderChooser = new JFileChooser();
|
||||||
folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
|
|
||||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
if (folderChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
FOLDER_PATH = Path.of(folderChooser.getSelectedFile().getAbsolutePath());
|
||||||
int returnVal = folderChooser.showOpenDialog(this);
|
tracker = new TrackerThread(mainTextPane, fileContents, fileList, fileInfoTextPane);
|
||||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
|
||||||
tracker = new TrackerThread(mainTextPane, Path.of(folderChooser.getSelectedFile().getAbsolutePath()), fileContents, fileList);
|
|
||||||
tracker.start();
|
tracker.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snapshotLabel.setFont(new java.awt.Font("Trebuchet MS", Font.PLAIN, 18));
|
||||||
|
pathLabel.setFont(new java.awt.Font("Trebuchet MS", Font.PLAIN, 18));
|
||||||
|
|
||||||
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.setText("Last snapshot: " + new Date());
|
|
||||||
|
|
||||||
mainScrollPane.setViewportView(mainTextPane);
|
mainScrollPane.setViewportView(mainTextPane);
|
||||||
|
fileInfoScrollPane.setViewportView(fileInfoTextPane);
|
||||||
|
|
||||||
pathLabel.setFont(new java.awt.Font("Trebuchet MS", Font.PLAIN, 18)); // NOI18N
|
|
||||||
pathLabel.setText("Currently tracking: " + folderChooser.getSelectedFile().getAbsolutePath());
|
|
||||||
|
|
||||||
CommitButton.setText("Commit");
|
|
||||||
CommitButton.addActionListener(this::CommitButtonActionPerformed);
|
CommitButton.addActionListener(this::CommitButtonActionPerformed);
|
||||||
|
|
||||||
StatusButton.setText("Status");
|
|
||||||
StatusButton.addActionListener(this::StatusButtonActionPerformed);
|
|
||||||
|
|
||||||
fileMenu.setText("File");
|
|
||||||
|
|
||||||
pickFolder.setText("Pick another folder");
|
|
||||||
fileMenu.add(pickFolder);
|
fileMenu.add(pickFolder);
|
||||||
|
|
||||||
MainMenubar.add(fileMenu);
|
|
||||||
|
|
||||||
settingsMenu.setText("Edit");
|
|
||||||
|
|
||||||
settings.setText("Settings");
|
|
||||||
settingsMenu.add(settings);
|
settingsMenu.add(settings);
|
||||||
|
mainMenubar.add(fileMenu);
|
||||||
|
mainMenubar.add(settingsMenu);
|
||||||
|
|
||||||
MainMenubar.add(settingsMenu);
|
StatusButton.setText("Status");
|
||||||
|
pathLabel.setText("Currently tracking: " + FOLDER_PATH.toString());
|
||||||
|
CommitButton.setText("Commit");
|
||||||
|
snapshotLabel.setText("Last snapshot: " + new Date());
|
||||||
|
fileMenu.setText("File");
|
||||||
|
pickFolder.setText("Pick another folder");
|
||||||
|
settingsMenu.setText("Edit");
|
||||||
|
settings.setText("Settings");
|
||||||
|
|
||||||
setJMenuBar(MainMenubar);
|
setJMenuBar(mainMenubar);
|
||||||
|
|
||||||
GroupLayout layout = new GroupLayout(getContentPane());
|
GroupLayout layout = new GroupLayout(getContentPane());
|
||||||
getContentPane().setLayout(layout);
|
getContentPane().setLayout(layout);
|
||||||
@@ -84,35 +84,31 @@ public class MainFrame extends JFrame {
|
|||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(pathLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
.addComponent(snapshotLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(snapshotLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addComponent(pathLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(fileListScrollPane, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)
|
.addComponent(fileListScrollPane, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(mainScrollPane, GroupLayout.PREFERRED_SIZE, 599, GroupLayout.PREFERRED_SIZE)
|
.addComponent(mainScrollPane, GroupLayout.PREFERRED_SIZE, 599, GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addComponent(CommitButton, GroupLayout.DEFAULT_SIZE, 234, Short.MAX_VALUE)
|
||||||
.addComponent(CommitButton)
|
.addComponent(fileInfoScrollPane))))
|
||||||
.addGap(0, 1, Short.MAX_VALUE))
|
.addContainerGap()));
|
||||||
.addComponent(StatusButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
|
||||||
.addContainerGap())
|
|
||||||
);
|
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||||
.addComponent(snapshotLabel, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
|
.addComponent(snapshotLabel, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(pathLabel, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
|
.addComponent(pathLabel, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
|
.addComponent(fileListScrollPane, GroupLayout.DEFAULT_SIZE, 573, Short.MAX_VALUE)
|
||||||
.addComponent(fileListScrollPane, GroupLayout.DEFAULT_SIZE, 573, Short.MAX_VALUE)
|
.addComponent(mainScrollPane)
|
||||||
.addComponent(mainScrollPane))
|
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(CommitButton)
|
.addComponent(CommitButton)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(StatusButton)))
|
.addComponent(fileInfoScrollPane)))
|
||||||
.addContainerGap()));
|
.addContainerGap()));
|
||||||
pack();
|
pack();
|
||||||
}
|
}
|
||||||
@@ -122,7 +118,4 @@ public class MainFrame extends JFrame {
|
|||||||
mainTextPane.setText("");
|
mainTextPane.setText("");
|
||||||
snapshotLabel.setText("Last snapshot: " + new Date());
|
snapshotLabel.setText("Last snapshot: " + new Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StatusButtonActionPerformed(java.awt.event.ActionEvent evt) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
Lab3/src/main/java/org/lumijiez/interfaces/IDocument.java
Normal file
12
Lab3/src/main/java/org/lumijiez/interfaces/IDocument.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package org.lumijiez.interfaces;
|
||||||
|
|
||||||
|
import org.lumijiez.enums.FileType;
|
||||||
|
|
||||||
|
public interface IDocument {
|
||||||
|
String getExtension();
|
||||||
|
String getCreatedTime();
|
||||||
|
String getModificationTime();
|
||||||
|
FileType getFileType();
|
||||||
|
long getFilesizeKB();
|
||||||
|
String getInfo();
|
||||||
|
}
|
||||||
@@ -1,46 +1,59 @@
|
|||||||
package org.lumijiez.tracker;
|
package org.lumijiez.tracker;
|
||||||
|
|
||||||
import org.lumijiez.util.DiffType;
|
import org.lumijiez.base.Document;
|
||||||
|
import org.lumijiez.gui.MainFrame;
|
||||||
|
import org.lumijiez.enums.DiffType;
|
||||||
import org.lumijiez.util.FileDiffer;
|
import org.lumijiez.util.FileDiffer;
|
||||||
import org.lumijiez.util.StateType;
|
import org.lumijiez.enums.StateType;
|
||||||
|
import org.lumijiez.util.FileFactory;
|
||||||
|
import org.lumijiez.util.NotificationHandler;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.*;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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 JTextPane fileInfoTextPane;
|
||||||
private Map<File, byte[]> fileContents;
|
private final JList<Document> fileList;
|
||||||
private final JList<String> fileList;
|
private Map<Document, byte[]> fileContents;
|
||||||
private final Map<File, StateType> fileStates = new HashMap<>();
|
private final Map<File, StateType> fileStates = new HashMap<>();
|
||||||
|
|
||||||
public TrackerThread(JTextPane textPane, Path path, Map<File, byte[]> files, JList<String> fileList) {
|
public TrackerThread(JTextPane textPane, Map<Document, byte[]> files, JList<Document> fileList, JTextPane fileInfoTextPane) {
|
||||||
this.textPane = textPane;
|
this.textPane = textPane;
|
||||||
this.path = path;
|
|
||||||
this.fileContents = files;
|
this.fileContents = files;
|
||||||
this.fileList = fileList;
|
this.fileList = fileList;
|
||||||
|
this.fileInfoTextPane = fileInfoTextPane;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
System.out.println("Init called");
|
System.out.println("Init called");
|
||||||
fileContents = FileDiffer.crawlDirectory(path);
|
fileContents = FileDiffer.crawlDirectory(MainFrame.FOLDER_PATH);
|
||||||
|
DefaultListModel<Document> listModel = new DefaultListModel<>();
|
||||||
ArrayList<String> fileNames = new ArrayList<>();
|
|
||||||
|
|
||||||
for (File file : fileContents.keySet()) {
|
for (File file : fileContents.keySet()) {
|
||||||
fileNames.add(file.getName());
|
Document doc = FileFactory.getDocument(file.toPath());
|
||||||
|
listModel.addElement(doc);
|
||||||
}
|
}
|
||||||
fileList.setModel(new AbstractListModel<>() {
|
|
||||||
public int getSize() {
|
fileList.setModel(listModel);
|
||||||
return fileNames.size();
|
fileList.setCellRenderer(new DefaultListCellRenderer() {
|
||||||
|
@Override
|
||||||
|
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
|
if (value instanceof Document) {
|
||||||
|
value = ((Document) value).getName();
|
||||||
|
}
|
||||||
|
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||||
}
|
}
|
||||||
public String getElementAt(int i) {
|
});
|
||||||
return fileNames.get(i);
|
|
||||||
|
fileList.addListSelectionListener(e -> {
|
||||||
|
if (!e.getValueIsAdjusting()) {
|
||||||
|
refreshFileInfo();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -49,41 +62,47 @@ public class TrackerThread extends Thread {
|
|||||||
fileStates.clear();
|
fileStates.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refreshFileInfo() {
|
||||||
|
Document selectedDocument = fileList.getSelectedValue();
|
||||||
|
if (selectedDocument != null) {
|
||||||
|
fileInfoTextPane.setText(selectedDocument.getInfo());
|
||||||
|
} else {
|
||||||
|
fileInfoTextPane.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void checkDirectory() {
|
public void checkDirectory() {
|
||||||
Map<DiffType, ArrayList<File>> result = FileDiffer.diff(fileContents, FileDiffer.crawlDirectory(path));
|
Map<DiffType, ArrayList<Document>> result = FileDiffer.diff(fileContents, FileDiffer.crawlDirectory(MainFrame.FOLDER_PATH));
|
||||||
|
|
||||||
StringBuilder toShow = new StringBuilder();
|
StringBuilder toShow = new StringBuilder();
|
||||||
|
|
||||||
boolean created = false, deleted = false, modified = false;
|
boolean somethingNew = false;
|
||||||
if (!result.get(DiffType.CREATE).isEmpty()) {
|
|
||||||
created = true;
|
for (DiffType type : result.keySet()) {
|
||||||
for (File file : result.get(DiffType.CREATE)) {
|
for (File file : result.get(type)) {
|
||||||
fileStates.put(file, StateType.NEW);
|
somethingNew = true;
|
||||||
|
System.out.println("File changed " + file.getName() + " " + type.getState().getAction());
|
||||||
|
fileStates.put(file, type.getState());
|
||||||
}
|
}
|
||||||
System.out.println("Created");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.get(DiffType.DELETE).isEmpty()) {
|
if (somethingNew) {
|
||||||
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();
|
init();
|
||||||
|
refreshFileInfo();
|
||||||
for (File file : fileStates.keySet()) {
|
for (File file : fileStates.keySet()) {
|
||||||
if (fileStates.get(file) != StateType.NONE) {
|
if (fileStates.get(file) != StateType.NONE) {
|
||||||
toShow.append(file.getName()).append(" has been ").append(fileStates.get(file).getName()).append("<br>");
|
if (fileStates.get(file) == StateType.NEW) {
|
||||||
|
toShow.append("<span color=\"green\">");
|
||||||
|
}
|
||||||
|
if (fileStates.get(file) == StateType.DELETED) {
|
||||||
|
toShow.append("<span color=\"red\">");
|
||||||
|
}
|
||||||
|
if (fileStates.get(file) == StateType.MODIFIED) {
|
||||||
|
toShow.append("<span color=\"orange\">");
|
||||||
|
}
|
||||||
|
toShow.append(file.getName()).append(" has been ").append(fileStates.get(file).getAction()).append("</span><br>");
|
||||||
|
NotificationHandler.showNotification(file.getName(), fileStates.get(file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
textPane.setText(toShow.toString());
|
textPane.setText(toShow.toString());
|
||||||
@@ -94,7 +113,6 @@ public class TrackerThread extends Thread {
|
|||||||
public void run() {
|
public void run() {
|
||||||
while(this.isAlive()) {
|
while(this.isAlive()) {
|
||||||
checkDirectory();
|
checkDirectory();
|
||||||
//Thread.sleep(200);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package org.lumijiez.util;
|
|
||||||
|
|
||||||
public enum DiffType {
|
|
||||||
CREATE, DELETE, MODIFY, NONE
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.lumijiez.util;
|
package org.lumijiez.util;
|
||||||
|
|
||||||
import java.io.File;
|
import org.lumijiez.base.Document;
|
||||||
|
import org.lumijiez.enums.DiffType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -11,43 +13,39 @@ import java.util.Map;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class FileDiffer {
|
public class FileDiffer {
|
||||||
public static Map<DiffType, ArrayList<File>> diff(Map<File, byte[]> oldFiles, Map<File, byte[]> newFiles) {
|
public static Map<DiffType, ArrayList<Document>> diff(Map<Document, byte[]> oldFiles, Map<Document, byte[]> newFiles) {
|
||||||
Map<DiffType, ArrayList<File>> result = new HashMap<>();
|
Map<DiffType, ArrayList<Document>> result = Map.of(
|
||||||
|
DiffType.CREATE, new ArrayList<>(),
|
||||||
|
DiffType.DELETE, new ArrayList<>(),
|
||||||
|
DiffType.MODIFY, new ArrayList<>());
|
||||||
|
|
||||||
ArrayList<File> newFileList = new ArrayList<>();
|
for (Document file : oldFiles.keySet()) {
|
||||||
ArrayList<File> deletedFileList = new ArrayList<>();
|
|
||||||
ArrayList<File> modifiedFileList = new ArrayList<>();
|
|
||||||
|
|
||||||
for (File file : oldFiles.keySet()) {
|
|
||||||
if (newFiles.get(file) != null) {
|
if (newFiles.get(file) != null) {
|
||||||
if (Arrays.compare(oldFiles.get(file), newFiles.get(file)) != 0) {
|
if (Arrays.compare(oldFiles.get(file), newFiles.get(file)) != 0) {
|
||||||
modifiedFileList.add(file);
|
result.get(DiffType.MODIFY).add(file);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
deletedFileList.add(file);
|
result.get(DiffType.DELETE).add(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File file : newFiles.keySet()) {
|
for (Document file : newFiles.keySet()) {
|
||||||
if (oldFiles.get(file) == null) {
|
if (oldFiles.get(file) == null) {
|
||||||
newFileList.add(file);
|
result.get(DiffType.CREATE).add(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.put(DiffType.CREATE, newFileList);
|
|
||||||
result.put(DiffType.DELETE, deletedFileList);
|
|
||||||
result.put(DiffType.MODIFY, modifiedFileList);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<File, byte[]> crawlDirectory(Path path) {
|
public static Map<Document, byte[]> crawlDirectory(Path path) {
|
||||||
Map<File, byte[]> newFileContents = new HashMap<>();
|
Map<Document, byte[]> newFileContents = new HashMap<>();
|
||||||
try (Stream<Path> paths = Files.walk(path)) {
|
try (Stream<Path> paths = Files.walk(path)) {
|
||||||
paths.forEach(p -> {
|
paths.forEach(p -> {
|
||||||
if (Files.isRegularFile(p)) {
|
Document doc = new Document(p);
|
||||||
|
if (Files.isRegularFile(doc.toPath())) {
|
||||||
try {
|
try {
|
||||||
newFileContents.put(p.toFile(), Files.readAllBytes(p));
|
newFileContents.put(doc, Files.readAllBytes(doc.toPath()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
26
Lab3/src/main/java/org/lumijiez/util/FileFactory.java
Normal file
26
Lab3/src/main/java/org/lumijiez/util/FileFactory.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package org.lumijiez.util;
|
||||||
|
|
||||||
|
import org.lumijiez.base.*;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class FileFactory {
|
||||||
|
public static Document getDocument(Path path) {
|
||||||
|
Document doc = new Document(path);
|
||||||
|
switch (doc.getFileType()) {
|
||||||
|
case PLAINTEXT -> {
|
||||||
|
return new TextFile(path);
|
||||||
|
}
|
||||||
|
case IMAGE -> {
|
||||||
|
return new ImageFile(path);
|
||||||
|
}
|
||||||
|
case FILE -> {
|
||||||
|
return new ArbitraryFile(path);
|
||||||
|
}
|
||||||
|
case CODE -> {
|
||||||
|
return new CodeFile(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package org.lumijiez.util;
|
||||||
|
|
||||||
|
import org.lumijiez.enums.StateType;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.TrayIcon.MessageType;
|
||||||
|
|
||||||
|
public class NotificationHandler {
|
||||||
|
public static void showNotification(String filename, StateType stateType) {
|
||||||
|
try {
|
||||||
|
SystemTray tray = SystemTray.getSystemTray();
|
||||||
|
Image image = Toolkit.getDefaultToolkit().createImage("some-icon.png");
|
||||||
|
|
||||||
|
TrayIcon trayIcon = new TrayIcon(image, "Java AWT Tray Demo");
|
||||||
|
trayIcon.setImageAutoSize(true);
|
||||||
|
trayIcon.setToolTip("File Tracker");
|
||||||
|
tray.add(trayIcon);
|
||||||
|
trayIcon.displayMessage("File Tracker", filename + " has been " + stateType.getAction(), MessageType.INFO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
92
Lab3/src/main/java/org/lumijiez/util/Utils.java
Normal file
92
Lab3/src/main/java/org/lumijiez/util/Utils.java
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package org.lumijiez.util;
|
||||||
|
|
||||||
|
import org.lumijiez.base.Document;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
public static int countWords(Document doc) {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(doc));
|
||||||
|
int wordCount = 0;
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
String[] words = line.split("\\s+");
|
||||||
|
wordCount += words.length;
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
return wordCount;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int countLines(Document doc) {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(doc));
|
||||||
|
int lineCount = 0;
|
||||||
|
while (reader.readLine() != null) lineCount++;
|
||||||
|
reader.close();
|
||||||
|
return lineCount;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long countChars(Document doc) {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(doc));
|
||||||
|
long characterCount = 0;
|
||||||
|
while (reader.read() != -1) characterCount++;
|
||||||
|
reader.close();
|
||||||
|
return characterCount;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int countClasses(Document doc) {
|
||||||
|
try {
|
||||||
|
int classCount = 0;
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(doc));
|
||||||
|
String line;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (line.contains("class ")) {
|
||||||
|
classCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
return classCount;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int countMethods(Document doc) {
|
||||||
|
try {
|
||||||
|
int methodCount = 0;
|
||||||
|
|
||||||
|
BufferedReader reader = new BufferedReader(new FileReader(doc));
|
||||||
|
String line;
|
||||||
|
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
if (line.matches(".*\\b\\w+\\s+\\w+\\(.*\\)\\s*\\{.*")) {
|
||||||
|
methodCount++;
|
||||||
|
} else if (line.contains("def ")) {
|
||||||
|
methodCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
return methodCount;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user