Basic functioning plugin completed.
This commit is contained in:
parent
fd1961d5f3
commit
4bf7d5f82f
35
.devcontainer/devcontainer.json
Normal file
35
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,35 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/java
|
||||
{
|
||||
"name": "Java",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"image": "mcr.microsoft.com/devcontainers/java:1-21-bullseye",
|
||||
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/java:1": {
|
||||
"version": "none",
|
||||
"installMaven": "true",
|
||||
"installGradle": "false"
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"redhat.java",
|
||||
"redhat.vscode-xml"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "java -version",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
130
.gitignore
vendored
Normal file
130
.gitignore
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,gradle,java,kotlin,maven
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,linux,gradle,java,kotlin,maven
|
||||
|
||||
### Java ###
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
### Kotlin ###
|
||||
# Compiled class file
|
||||
|
||||
# Log file
|
||||
|
||||
# BlueJ files
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
|
||||
# Package Files #
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# Eclipse m2e generated files
|
||||
# Eclipse Core
|
||||
.project
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
### Gradle ###
|
||||
.gradle
|
||||
**/build/
|
||||
!src/**/build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Avoid ignore Gradle wrappper properties
|
||||
!gradle-wrapper.properties
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
# Eclipse Gradle plugin generated files
|
||||
# Eclipse Core
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
|
||||
### Gradle Patch ###
|
||||
# Java heap dump
|
||||
*.hprof
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,gradle,java,kotlin,maven
|
||||
|
||||
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
||||
|
||||
buildtools/*
|
||||
!buildtools/install.sh
|
||||
devserver/*
|
||||
!devserver/start.sh
|
||||
!devserver/loadplugin.sh
|
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"java.configuration.updateBuildConfiguration": "automatic",
|
||||
"java.compile.nullAnalysis.mode": "automatic"
|
||||
}
|
15
.vscode/tasks.json
vendored
Normal file
15
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "java (buildArtifact)",
|
||||
"targetPath": "${workspaceFolder}/devserver/plugins/${workspaceFolderBasename}.jar",
|
||||
"elements": [
|
||||
"${compileOutput}",
|
||||
"${dependencies}"
|
||||
],
|
||||
"problemMatcher": [],
|
||||
"label": "Build SpigotResourceSync to plugins"
|
||||
}
|
||||
]
|
||||
}
|
6
buildtools/install.sh
Normal file
6
buildtools/install.sh
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl -o BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
|
||||
java -jar BuildTools.jar --rev 1.20.4 --final-name spigot.jar
|
||||
cp spigot.jar ../devserver/.
|
||||
echo "Moved spigot.jar to ../devserver/."
|
3
devserver/loadplugin.sh
Normal file
3
devserver/loadplugin.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
cp ../target/*.jar ./plugins/.
|
3
devserver/start.sh
Executable file
3
devserver/start.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
java -Xmx2G -XX:+UseG1GC -jar spigot.jar nogui
|
58
pom.xml
Normal file
58
pom.xml
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>systems.reslate.entertainment.spigotresourcesync</groupId>
|
||||
<artifactId>spigotresourcesync</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.17.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
<version>2.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>2.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,121 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import solutions.reslate.entertainment.spigotresourcesync.data.Configuration;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.events.ObjectLoadListener;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.serialisation.Serialiser;
|
||||
|
||||
public class ConfigManager extends FileConfiguration {
|
||||
private Serialiser<Configuration> serialiser;
|
||||
private Configuration config;
|
||||
private File file;
|
||||
private Logger logger;
|
||||
private Collection<ObjectLoadListener<Configuration>> configLoadListener;
|
||||
|
||||
|
||||
public ConfigManager(File file, Serialiser<Configuration> serialiser, Logger logger) {
|
||||
super();
|
||||
this.serialiser = serialiser;
|
||||
this.config = new Configuration();
|
||||
this.file = file;
|
||||
this.logger = logger;
|
||||
this.configLoadListener = new HashSet<>();
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
try {
|
||||
save(this.file);
|
||||
} catch (IOException e) {
|
||||
logger.severe(String.format("Unable to save configuration to \"%s\". %s", this.file.getAbsolutePath(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(String file) throws IOException {
|
||||
this.save(new File(file));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(File file) throws IOException {
|
||||
this.serialiser.flushTo(file, this.config);
|
||||
logger.info(String.format("Saved configuration to \"%s\".", this.file.getAbsolutePath()));
|
||||
}
|
||||
|
||||
public void load() {
|
||||
try {
|
||||
this.load(file);
|
||||
} catch (IOException | InvalidConfigurationException e) {
|
||||
logger.severe(String.format("Unable to load configuration from \"%s\".", file.getAbsolutePath(), e.getMessage()));
|
||||
if (file.exists()) {
|
||||
logger.severe(String.format("Found pre-existing file. No overwriting will occur. Delete \"%s\" and restart to generate new configuration.", this.file.getAbsolutePath()));
|
||||
} else {
|
||||
flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void load(String file) throws FileNotFoundException, IOException, InvalidConfigurationException {
|
||||
this.load(new File(file));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(File file) throws FileNotFoundException, IOException, InvalidConfigurationException {
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
this.load(reader);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Reader reader) throws IOException, InvalidConfigurationException {
|
||||
this.config = this.serialiser.load(reader, Configuration.class);
|
||||
logger.info(String.format("Successfully loaded configuration from \"%s\".", this.file.getAbsolutePath()));
|
||||
onLoadConfig();
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
private void onLoadConfig() {
|
||||
for (ObjectLoadListener<Configuration> objectUpdateListener : configLoadListener) {
|
||||
objectUpdateListener.objectLoaded(config);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveToString() {
|
||||
return serialiser.serialize(this.config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromString(String contents) throws InvalidConfigurationException {
|
||||
this.config = serialiser.deserialize(contents, Configuration.class);
|
||||
onLoadConfig();
|
||||
}
|
||||
|
||||
public void addConfigLoadListener(ObjectLoadListener<Configuration> listener) {
|
||||
this.configLoadListener.add(listener);
|
||||
}
|
||||
|
||||
public void removeConfigLoadListener(ObjectLoadListener<Configuration> listener) {
|
||||
this.configLoadListener.remove(listener);
|
||||
}
|
||||
|
||||
public void resetConfiguration() {
|
||||
this.config = new Configuration();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import solutions.reslate.entertainment.spigotresourcesync.serialisation.JacksonYamlSerialiser;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.synchronisation.ApacheCommonsIOSynchroniser;
|
||||
|
||||
public class SpigotResourceSync extends JavaPlugin {
|
||||
private ConfigManager configManager;
|
||||
private SyncListManager syncListManager;
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
configManager.flush();
|
||||
super.onDisable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
configManager = new ConfigManager(new File("plugins", getName() + ".yml"), new JacksonYamlSerialiser<>(), getLogger());
|
||||
configManager.load();
|
||||
syncListManager = new SyncListManager(configManager.getConfiguration(), new ApacheCommonsIOSynchroniser(), getLogger());
|
||||
configManager.addConfigLoadListener(syncListManager);
|
||||
if (configManager.getConfiguration().getSyncOnLoad()) {
|
||||
syncListManager.synchroniseAllSyncList();
|
||||
}
|
||||
super.onLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileConfiguration getConfig() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConfig() {
|
||||
configManager.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDefaultConfig() {
|
||||
configManager.resetConfiguration();
|
||||
configManager.flush();
|
||||
super.saveDefaultConfig();
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import solutions.reslate.entertainment.spigotresourcesync.data.Configuration;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.data.SyncPair;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.events.ObjectLoadListener;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.synchronisation.Synchroniser;
|
||||
|
||||
public class SyncListManager implements ObjectLoadListener<Configuration> {
|
||||
private Configuration configuration;
|
||||
private Synchroniser synchroniser;
|
||||
private Logger logger;
|
||||
|
||||
public SyncListManager(Configuration configuration, Synchroniser synchroniser, Logger logger) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
this.configuration = configuration;
|
||||
this.synchroniser = synchroniser;
|
||||
}
|
||||
|
||||
public void synchroniseAllSyncList() {
|
||||
logger.info("Synchronising all sync pairs...");
|
||||
for (SyncPair syncPair : this.configuration.getSyncList().gatherAllSyncPairs()) {
|
||||
File source = new File(syncPair.getSource());
|
||||
File dest = new File(syncPair.getDestination());
|
||||
try {
|
||||
synchroniser.sync(source, dest);
|
||||
logger.info(String.format("Synchronised \"%s\" to \"%s\"!", source.getName(), dest.getName()));
|
||||
} catch (IOException e) {
|
||||
logger.warning(String.format("Failed to synchronise \"%s\" to \"%s\". %s", source.getAbsolutePath(), dest.getAbsolutePath(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
logger.info("Done synchronising.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void objectLoaded(Configuration obj) {
|
||||
logger.info("Updating synchronisation list due to recently loading configuration...");
|
||||
this.configuration = obj;
|
||||
synchroniseAllSyncList();
|
||||
logger.info("Done.");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Configuration implements Serializable {
|
||||
private boolean enabled;
|
||||
private boolean syncOnLoad;
|
||||
private SyncList syncList;
|
||||
|
||||
public Configuration() {
|
||||
super();
|
||||
enabled = true;
|
||||
syncOnLoad = true;
|
||||
syncList = new SyncList();
|
||||
syncList.addSynchronisationPair("exampleA", "exampleB", "general");
|
||||
}
|
||||
|
||||
public boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean getSyncOnLoad() {
|
||||
return syncOnLoad;
|
||||
}
|
||||
|
||||
public void setSyncOnLoad(boolean syncOnLoad) {
|
||||
this.syncOnLoad = syncOnLoad;
|
||||
}
|
||||
|
||||
public SyncList getSyncList() {
|
||||
return syncList;
|
||||
}
|
||||
|
||||
public void setSyncList(SyncList syncList) {
|
||||
this.syncList = syncList;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
import java.util.SequencedMap;
|
||||
|
||||
|
||||
public class SyncList implements Serializable {
|
||||
private SequencedMap<String, SequencedCollection<SyncPair>> syncPairs;
|
||||
|
||||
public SyncList() {
|
||||
super();
|
||||
this.syncPairs = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public List<SyncPair> gatherAllSyncPairs() {
|
||||
List<SyncPair> allSyncPairs = new ArrayList<>();
|
||||
for (SequencedCollection<SyncPair> syncPairs : this.syncPairs.values()) {
|
||||
allSyncPairs.addAll(syncPairs);
|
||||
}
|
||||
return allSyncPairs;
|
||||
}
|
||||
|
||||
public void addSynchronisationPair(String source, String dest, String group) {
|
||||
this.addSynchronisationPair(new SyncPair(source, dest), group);
|
||||
}
|
||||
|
||||
public void addSynchronisationPair(SyncPair syncPair, String group) {
|
||||
addSynchronisationGroup(group);
|
||||
this.syncPairs.get(group).add(syncPair);
|
||||
}
|
||||
|
||||
public void removeSynchronisationSet(String source, String dest, String group) {
|
||||
if (this.syncPairs.containsKey(group)) {
|
||||
this.syncPairs.get(group).remove(new SyncPair(source, dest));
|
||||
}
|
||||
}
|
||||
|
||||
public void addSynchronisationGroup(String group) {
|
||||
if (!this.syncPairs.containsKey(group)) {
|
||||
this.syncPairs.put(group, new LinkedHashSet<>());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSynchronisationGroup(String group) {
|
||||
if (this.syncPairs.containsKey(group)) {
|
||||
this.syncPairs.remove(group);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> gatherSynchronisationGroups() {
|
||||
return new ArrayList<>(this.syncPairs.keySet());
|
||||
}
|
||||
|
||||
public SequencedMap<String, SequencedCollection<SyncPair>> getSyncPairs() {
|
||||
return syncPairs;
|
||||
}
|
||||
|
||||
public void setSyncPairs(SequencedMap<String, SequencedCollection<SyncPair>> syncPairs) {
|
||||
this.syncPairs = syncPairs;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SyncPair implements Serializable {
|
||||
private String source;
|
||||
private String destination;
|
||||
|
||||
public SyncPair(String source, String destination) {
|
||||
super();
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public SyncPair() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public void setDestination(String destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public String getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.source, this.destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SyncPair syncPair = (SyncPair) obj;
|
||||
return this.source.equals(syncPair.source)
|
||||
&& this.destination.equals(syncPair.destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%s, %s)", this.source, this.destination);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.events;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface ObjectLoadListener<T> extends EventListener {
|
||||
void objectLoaded(T obj);
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.serialisation;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
|
||||
|
||||
public class JacksonYamlSerialiser<T> implements Serialiser<T> {
|
||||
|
||||
private ObjectMapper mapper;
|
||||
|
||||
public JacksonYamlSerialiser() {
|
||||
super();
|
||||
YAMLFactory yamlFactory = new YAMLFactory()
|
||||
.disable(Feature.WRITE_DOC_START_MARKER);
|
||||
mapper = new ObjectMapper(yamlFactory)
|
||||
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushTo(File file, T serialisable) throws IOException {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
mapper.writeValue(writer, serialisable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T load(File file, Class<T> type) throws IOException {
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
return this.load(reader, type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T load(Reader reader, Class<T> type) throws IOException {
|
||||
try {
|
||||
return mapper.readValue(reader, type);
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialize(T serialisable) {
|
||||
try {
|
||||
return mapper.writeValueAsString(serialisable);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("Given type cannot be serialised.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T deserialize(String data, Class<T> type) {
|
||||
try {
|
||||
return mapper.readValue(data, type);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("Given string cannot be deserialised.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.serialisation;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
public interface Serialiser<T> {
|
||||
void flushTo(File file, T serialisable) throws IOException;
|
||||
String serialize(T serialisable);
|
||||
T load(File file, Class<T> type) throws IOException;
|
||||
T load(Reader reader, Class<T> type) throws IOException;
|
||||
T deserialize(String data, Class<T> type);
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.synchronisation;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
public class ApacheCommonsIOSynchroniser implements Synchroniser {
|
||||
|
||||
@Override
|
||||
public void sync(File source, File dest, File root) throws IOException {
|
||||
if (root != null) {
|
||||
source = Path.of(root.getPath(), source.getPath()).toFile();
|
||||
source = Path.of(root.getPath(), dest.getPath()).toFile();
|
||||
}
|
||||
|
||||
if (source.isDirectory()) {
|
||||
if (dest.isDirectory()) {
|
||||
FileUtils.copyDirectory(source, dest);
|
||||
} else {
|
||||
throw new IOException("Cannot synchronise directy to non-directory!");
|
||||
// TODO add more detail to error message.
|
||||
}
|
||||
} else {
|
||||
if (dest.isDirectory()) {
|
||||
FileUtils.copyFileToDirectory(source, dest);
|
||||
} else {
|
||||
FileUtils.copyFile(source, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sync(String source, String dest, String root) throws IOException {
|
||||
this.sync(new File(source), new File(dest), root != null ? new File(root) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sync(File source, File dest) throws IOException {
|
||||
sync(source, dest, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sync(String source, String dest) throws IOException {
|
||||
sync(source, dest, null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.synchronisation;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Synchroniser {
|
||||
void sync(File source, File dest, File root) throws IOException;
|
||||
void sync(File source, File dest) throws IOException;
|
||||
void sync(String source, String dest, String root) throws IOException;
|
||||
void sync(String source, String dest) throws IOException;
|
||||
}
|
3
src/main/resources/plugin.yml
Normal file
3
src/main/resources/plugin.yml
Normal file
@ -0,0 +1,3 @@
|
||||
name: SpigotResourceSync
|
||||
version: 1.0.0
|
||||
main: solutions.reslate.entertainment.spigotresourcesync.SpigotResourceSync
|
@ -0,0 +1,32 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import solutions.reslate.entertainment.spigotresourcesync.data.Configuration;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.data.SyncPair;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.serialisation.JacksonYamlSerialiser;
|
||||
import solutions.reslate.entertainment.spigotresourcesync.serialisation.Serialiser;
|
||||
|
||||
public class TestConfigManager {
|
||||
@Test
|
||||
void persistConfiguration() throws IOException {
|
||||
File dummyConfig = File.createTempFile("dummy_config", ".yml");
|
||||
Serialiser<Configuration> dummySerialiser = new JacksonYamlSerialiser<>();
|
||||
Logger logger = Logger.getLogger(this.getClass().getName());
|
||||
ConfigManager initialConfigManager = new ConfigManager(dummyConfig, dummySerialiser, logger);
|
||||
SyncPair dummySyncPair = new SyncPair("abc", "def");
|
||||
initialConfigManager.getConfiguration().getSyncList().addSynchronisationPair(dummySyncPair, "a");
|
||||
initialConfigManager.flush();
|
||||
assumeTrue(dummyConfig.exists());
|
||||
ConfigManager finalConfigManager = new ConfigManager(dummyConfig, dummySerialiser, logger);
|
||||
finalConfigManager.load();
|
||||
assertEquals(dummySyncPair, finalConfigManager.getConfiguration().getSyncList().gatherAllSyncPairs().get(0));
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TestSyncListManager {
|
||||
@Test
|
||||
void testDirectorySync() {
|
||||
// TODO Write directory sync test.
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.data;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TestSynchronisationPair {
|
||||
@Test
|
||||
void dataEqualsThereforeObjectEquals() {
|
||||
SyncPair firstPair = new SyncPair("abc", "def");
|
||||
SyncPair secondPair = new SyncPair("abc", "def");
|
||||
assertEquals(firstPair, secondPair);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.serialisation;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
import java.util.SequencedMap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import solutions.reslate.entertainment.spigotresourcesync.data.SyncPair;
|
||||
|
||||
public class TestJacksonYamlSerialiser {
|
||||
@Test
|
||||
void testListSerialisation() throws IOException {
|
||||
ArrayList<String> dummyList = new ArrayList<>();
|
||||
dummyList.add("abc");
|
||||
dummyList.add("def");
|
||||
File dummyFile = File.createTempFile("dummy_file", ".yml");
|
||||
JacksonYamlSerialiser<List<String>> dummyJacksonYamlSerialiser = new JacksonYamlSerialiser<>();
|
||||
dummyJacksonYamlSerialiser.flushTo(dummyFile, dummyList);
|
||||
assumeTrue(dummyFile.exists());
|
||||
List<String> writtenLines = Files.readAllLines(dummyFile.toPath());
|
||||
assertEquals(2, writtenLines.size());
|
||||
assertEquals("- \"abc\"", writtenLines.get(0));
|
||||
assertEquals("- \"def\"", writtenLines.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSyncPairSerialisation() throws IOException {
|
||||
File dummyFile = File.createTempFile("dummy_file", ".yml");
|
||||
SyncPair dummySyncPair = new SyncPair("abc", "def");
|
||||
JacksonYamlSerialiser<SyncPair> dummyJacksonYamlSerialiser = new JacksonYamlSerialiser<>();
|
||||
dummyJacksonYamlSerialiser.flushTo(dummyFile, dummySyncPair);
|
||||
assumeTrue(dummyFile.exists());
|
||||
List<String> writtenLines = Files.readAllLines(dummyFile.toPath());
|
||||
assertEquals(2, writtenLines.size());
|
||||
assertEquals("source: \"abc\"", writtenLines.get(0));
|
||||
assertEquals("destination: \"def\"", writtenLines.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSequencedCollectionSerialisation() throws IOException {
|
||||
File dummyFile = File.createTempFile("dummy_file", ".yml");
|
||||
SequencedCollection<String> collection = new LinkedHashSet<>();
|
||||
collection.add("abc");
|
||||
collection.add("def");
|
||||
JacksonYamlSerialiser<SequencedCollection<String>> dummyJacksonYamlSerialiser = new JacksonYamlSerialiser<>();
|
||||
dummyJacksonYamlSerialiser.flushTo(dummyFile, collection);
|
||||
assumeTrue(dummyFile.exists());
|
||||
List<String> writtenLines = Files.readAllLines(dummyFile.toPath());
|
||||
assertEquals(2, writtenLines.size());
|
||||
assertEquals("- \"abc\"", writtenLines.get(0));
|
||||
assertEquals("- \"def\"", writtenLines.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSequencedMapSerialisation() throws IOException {
|
||||
File dummyFile = File.createTempFile("dummy_file", ".yml");
|
||||
SequencedMap<String, String> collection = new LinkedHashMap<>();
|
||||
collection.put("abc", "def");
|
||||
collection.put("123", "456");
|
||||
JacksonYamlSerialiser<SequencedMap<String, String>> dummyJacksonYamlSerialiser = new JacksonYamlSerialiser<>();
|
||||
dummyJacksonYamlSerialiser.flushTo(dummyFile, collection);
|
||||
assumeTrue(dummyFile.exists());
|
||||
List<String> writtenLines = Files.readAllLines(dummyFile.toPath());
|
||||
assertEquals(2, writtenLines.size());
|
||||
assertEquals("abc: \"def\"", writtenLines.get(0));
|
||||
assertEquals("\"123\": \"456\"", writtenLines.get(1));
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package solutions.reslate.entertainment.spigotresourcesync.synchroniser;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import solutions.reslate.entertainment.spigotresourcesync.synchronisation.ApacheCommonsIOSynchroniser;
|
||||
|
||||
public class TestApacheCommonsIOSynchroniser {
|
||||
@Test
|
||||
void testDir2DirSync() throws IOException {
|
||||
ApacheCommonsIOSynchroniser dummySynchroniser = new ApacheCommonsIOSynchroniser();
|
||||
File dummyDirA = Files.createTempDirectory("dir_A").toFile();
|
||||
File dummyDirB = Files.createTempDirectory("dir_B").toFile();
|
||||
File dummyFileA = File.createTempFile("file_A", ".txt", dummyDirA);
|
||||
dummySynchroniser.sync(dummyDirA, dummyDirB);
|
||||
assertTrue(new File(dummyDirB, dummyFileA.getName()).exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFile2DirSync() throws IOException {
|
||||
ApacheCommonsIOSynchroniser dummySynchroniser = new ApacheCommonsIOSynchroniser();
|
||||
File dummyDirA = Files.createTempDirectory("dir_A").toFile();
|
||||
File dummyDirB = Files.createTempDirectory("dir_B").toFile();
|
||||
File dummyFileA = File.createTempFile("file_A", ".txt", dummyDirA);
|
||||
dummySynchroniser.sync(dummyFileA, dummyDirB);
|
||||
assertTrue(new File(dummyDirB, dummyFileA.getName()).exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFile2FileSync() throws IOException {
|
||||
ApacheCommonsIOSynchroniser dummySynchroniser = new ApacheCommonsIOSynchroniser();
|
||||
File dummyDirA = Files.createTempDirectory("dir_A").toFile();
|
||||
File dummyDirB = Files.createTempDirectory("dir_B").toFile();
|
||||
File dummyFileA = File.createTempFile("file_A", ".txt", dummyDirA);
|
||||
File dummyFileB = new File(dummyDirB, "file_B");
|
||||
dummySynchroniser.sync(dummyFileA, dummyFileB);
|
||||
assertTrue(dummyFileB.exists());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user