diff --git a/bukkit/src/main/java/net/byteflux/libby/BukkitLibraryManager.java b/bukkit/src/main/java/net/byteflux/libby/BukkitLibraryManager.java
index 203e50e..221dbcf 100644
--- a/bukkit/src/main/java/net/byteflux/libby/BukkitLibraryManager.java
+++ b/bukkit/src/main/java/net/byteflux/libby/BukkitLibraryManager.java
@@ -4,6 +4,7 @@
import net.byteflux.libby.logging.adapters.JDKLogAdapter;
import org.bukkit.plugin.Plugin;
+import java.io.InputStream;
import java.net.URLClassLoader;
import java.nio.file.Path;
@@ -13,10 +14,19 @@
* A runtime dependency manager for Bukkit plugins.
*/
public class BukkitLibraryManager extends LibraryManager {
+ /**
+ * Default libraries.json name (see Minecrell/plugin-yml repository at GitHub)
+ */
+ private static final String DEFAULT_JSON = "bukkit-libraries.json";
+
/**
* Plugin classpath helper
*/
private final URLClassLoaderHelper classLoader;
+ /**
+ * The plugin
+ */
+ private final Plugin plugin;
/**
* Creates a new Bukkit library manager.
@@ -36,6 +46,7 @@ public BukkitLibraryManager(Plugin plugin) {
public BukkitLibraryManager(Plugin plugin, String directoryName) {
super(new JDKLogAdapter(requireNonNull(plugin, "plugin").getLogger()), plugin.getDataFolder().toPath(), directoryName);
classLoader = new URLClassLoaderHelper((URLClassLoader) plugin.getClass().getClassLoader(), this);
+ this.plugin = plugin;
}
/**
@@ -47,4 +58,23 @@ public BukkitLibraryManager(Plugin plugin, String directoryName) {
protected void addToClasspath(Path file) {
classLoader.addToClasspath(file);
}
+
+ /**
+ * Load the libraries by reading {@link #DEFAULT_JSON} file in the plugin.
+ */
+ public void loadLibrariesInJsonFile() {
+ loadLibrariesInJsonFile(DEFAULT_JSON);
+ }
+
+ /**
+ * Load the libraries by reading provided JSON file in the plugin.
+ *
+ * @param resourcePath The path to the JSON file
+ */
+ public void loadLibrariesInJsonFile(String resourcePath) {
+ final InputStream stream = plugin.getResource(resourcePath);
+ if (stream != null) {
+ loadLibrariesInJsonFile(stream);
+ }
+ }
}
diff --git a/bungee/src/main/java/net/byteflux/libby/BungeeLibraryManager.java b/bungee/src/main/java/net/byteflux/libby/BungeeLibraryManager.java
index a93db6c..c5c2b09 100644
--- a/bungee/src/main/java/net/byteflux/libby/BungeeLibraryManager.java
+++ b/bungee/src/main/java/net/byteflux/libby/BungeeLibraryManager.java
@@ -4,6 +4,7 @@
import net.byteflux.libby.logging.adapters.JDKLogAdapter;
import net.md_5.bungee.api.plugin.Plugin;
+import java.io.InputStream;
import java.net.URLClassLoader;
import java.nio.file.Path;
@@ -13,10 +14,19 @@
* A runtime dependency manager for Bungee plugins.
*/
public class BungeeLibraryManager extends LibraryManager {
+ /**
+ * Default libraries.json name (see Minecrell/plugin-yml repository at GitHub)
+ */
+ private static final String DEFAULT_JSON = "bungee-libraries.json";
+
/**
* Plugin classpath helper
*/
private final URLClassLoaderHelper classLoader;
+ /**
+ * The plugin
+ */
+ private final Plugin plugin;
/**
* Creates a new Bungee library manager.
@@ -36,6 +46,7 @@ public BungeeLibraryManager(Plugin plugin) {
public BungeeLibraryManager(Plugin plugin, String directoryName) {
super(new JDKLogAdapter(requireNonNull(plugin, "plugin").getLogger()), plugin.getDataFolder().toPath(), directoryName);
classLoader = new URLClassLoaderHelper((URLClassLoader) plugin.getClass().getClassLoader(), this);
+ this.plugin = plugin;
}
/**
@@ -47,4 +58,23 @@ public BungeeLibraryManager(Plugin plugin, String directoryName) {
protected void addToClasspath(Path file) {
classLoader.addToClasspath(file);
}
+
+ /**
+ * Load the libraries by reading {@link #DEFAULT_JSON} file in the plugin.
+ */
+ public void loadLibrariesInJsonFile() {
+ loadLibrariesInJsonFile(DEFAULT_JSON);
+ }
+
+ /**
+ * Load the libraries by reading provided JSON file in the plugin.
+ *
+ * @param resourcePath The path to the JSON file
+ */
+ public void loadLibrariesInJsonFile(String resourcePath) {
+ final InputStream stream = plugin.getResourceAsStream(resourcePath);
+ if (stream != null) {
+ loadLibrariesInJsonFile(stream);
+ }
+ }
}
diff --git a/core/pom.xml b/core/pom.xml
index 89e6008..f036ba2 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -42,4 +42,13 @@
+
+
+
+ com.google.code.gson
+ gson
+ 2.10.1
+ compile
+
+
\ No newline at end of file
diff --git a/core/src/main/java/net/byteflux/libby/LibrariesJson.java b/core/src/main/java/net/byteflux/libby/LibrariesJson.java
new file mode 100644
index 0000000..8968dfe
--- /dev/null
+++ b/core/src/main/java/net/byteflux/libby/LibrariesJson.java
@@ -0,0 +1,100 @@
+package net.byteflux.libby;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.regex.Pattern;
+
+/**
+ * A representation of the libraries.json generated by
+ * Minecrell's plugin-yml gradle plugin.
+ * The instance of this class could convert the loaded JSON into {@link Library} instances,
+ * and insert the parsed dependencies to the provided {@link LibraryManager}.
+ *
+ * @author SNWCreations
+ */
+public class LibrariesJson {
+ private static final Pattern QUOTED_DOT;
+
+ static {
+ QUOTED_DOT = Pattern.compile(Pattern.quote("."));
+ }
+
+ private final Map repositories;
+ private final List libraries;
+
+ public LibrariesJson(Map repositories, List libraries) {
+ this.repositories = repositories;
+ this.libraries = libraries;
+ }
+
+ /**
+ * Parse the library notations with default settings defined by
+ * the {@link Library.Builder}.
+ *
+ * @return The parsed {@link Library} instances.
+ * @see #toLibraries(Consumer)
+ */
+ public List toLibraries() {
+ return toLibraries(unused -> {});
+ }
+
+ /**
+ * Convert the library notations defined by this instance to {@link Library} instances.
+ *
+ * @param postBuild Called before building the final {@link Library} instance.
+ * We could do more modification there to customize the result.
+ * For example, we could determine if the library is loaded in an
+ * isolated class loader by calling
+ * {@link Library.Builder#isolatedLoad(boolean)} in the callback.
+ * @return The parsed {@link Library} instances.
+ */
+ public List toLibraries(Consumer postBuild) {
+ final List result = new ArrayList<>();
+ for (String notation : libraries) {
+ final Library.Builder builder = Library.builder();
+ // Dependency notation format: https://stackoverflow.com/q/28713154
+ final String[] split = QUOTED_DOT.split(notation);
+ final String group = split[0];
+ final String artifact = split[1];
+ final String version = split[2];
+ builder.groupId(group);
+ builder.artifactId(artifact);
+ builder.version(version);
+ if (split.length > 3) { // we have classifier!
+ final String finalClassifier;
+ final String classifier = split[3];
+ if (classifier.contains("@")) { // extension detected
+ final String[] splitClassifier = QUOTED_DOT.split(classifier);
+ finalClassifier = splitClassifier[0];
+ // extension is dropped there as we don't need it, we just need JAR
+ // and this should never happen
+ } else {
+ finalClassifier = classifier;
+ }
+ builder.classifier(finalClassifier);
+ }
+ // insert repository urls to the built library object
+ for (String repoUrl : repositories.values()) {
+ builder.repository(repoUrl);
+ }
+ postBuild.accept(builder); // let callback run
+ final Library builtLibrary = builder.build();
+ result.add(builtLibrary);
+ }
+ return result;
+ }
+
+ /**
+ * Let the provided {@link LibraryManager} load the libraries defined in this instance.
+ *
+ * @param loader The {@link LibraryManager} which will be used to load libraries.
+ */
+ public void load(LibraryManager loader) {
+ final List parsedLibraries = toLibraries();
+ for (Library library : parsedLibraries) {
+ loader.loadLibrary(library);
+ }
+ }
+}
diff --git a/core/src/main/java/net/byteflux/libby/LibraryManager.java b/core/src/main/java/net/byteflux/libby/LibraryManager.java
index 9892996..b63c366 100644
--- a/core/src/main/java/net/byteflux/libby/LibraryManager.java
+++ b/core/src/main/java/net/byteflux/libby/LibraryManager.java
@@ -1,5 +1,6 @@
package net.byteflux.libby;
+import com.google.gson.Gson;
import net.byteflux.libby.classloader.IsolatedClassLoader;
import net.byteflux.libby.logging.LogLevel;
import net.byteflux.libby.logging.Logger;
@@ -15,16 +16,19 @@
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -60,6 +64,15 @@
* @see Library
*/
public abstract class LibraryManager {
+ /**
+ * Gson object used to deserialize libraries.json
+ */
+ private static final Gson GSON;
+
+ static {
+ GSON = new Gson();
+ }
+
/**
* Wrapped plugin logger
*/
@@ -593,4 +606,14 @@ public void loadLibrary(Library library) {
addToClasspath(file);
}
}
+
+ protected void loadLibrariesInJsonFile(InputStream stream) {
+ final LibrariesJson librariesJson;
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
+ librariesJson = GSON.fromJson(reader, LibrariesJson.class);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ librariesJson.load(this);
+ }
}
diff --git a/nukkit/src/main/java/net/byteflux/libby/NukkitLibraryManager.java b/nukkit/src/main/java/net/byteflux/libby/NukkitLibraryManager.java
index e6b95bb..126c571 100644
--- a/nukkit/src/main/java/net/byteflux/libby/NukkitLibraryManager.java
+++ b/nukkit/src/main/java/net/byteflux/libby/NukkitLibraryManager.java
@@ -4,6 +4,7 @@
import net.byteflux.libby.classloader.URLClassLoaderHelper;
import net.byteflux.libby.logging.adapters.NukkitLogAdapter;
+import java.io.InputStream;
import java.net.URLClassLoader;
import java.nio.file.Path;
@@ -13,10 +14,19 @@
* A runtime dependency manager for Nukkit plugins.
*/
public class NukkitLibraryManager extends LibraryManager {
+ /**
+ * Default libraries.json name (see Minecrell/plugin-yml repository at GitHub)
+ */
+ private static final String DEFAULT_JSON = "nukkit-libraries.json";
+
/**
* Plugin classpath helper
*/
private final URLClassLoaderHelper classLoader;
+ /**
+ * The plugin
+ */
+ private final Plugin plugin;
/**
* Creates a new Nukkit library manager.
@@ -36,6 +46,7 @@ public NukkitLibraryManager(Plugin plugin) {
public NukkitLibraryManager(Plugin plugin, String directoryName) {
super(new NukkitLogAdapter(requireNonNull(plugin, "plugin").getLogger()), plugin.getDataFolder().toPath(), directoryName);
classLoader = new URLClassLoaderHelper((URLClassLoader) plugin.getClass().getClassLoader(), this);
+ this.plugin = plugin;
}
/**
@@ -47,4 +58,23 @@ public NukkitLibraryManager(Plugin plugin, String directoryName) {
protected void addToClasspath(Path file) {
classLoader.addToClasspath(file);
}
+
+ /**
+ * Load the libraries by reading {@link #DEFAULT_JSON} file in the plugin.
+ */
+ public void loadLibrariesInJsonFile() {
+ loadLibrariesInJsonFile(DEFAULT_JSON);
+ }
+
+ /**
+ * Load the libraries by reading provided JSON file in the plugin.
+ *
+ * @param resourcePath The path to the JSON file
+ */
+ public void loadLibrariesInJsonFile(String resourcePath) {
+ final InputStream stream = plugin.getResource(resourcePath);
+ if (stream != null) {
+ loadLibrariesInJsonFile(stream);
+ }
+ }
}
diff --git a/paper/src/main/java/net/byteflux/libby/PaperLibraryManager.java b/paper/src/main/java/net/byteflux/libby/PaperLibraryManager.java
index af44cac..980526d 100644
--- a/paper/src/main/java/net/byteflux/libby/PaperLibraryManager.java
+++ b/paper/src/main/java/net/byteflux/libby/PaperLibraryManager.java
@@ -4,6 +4,7 @@
import net.byteflux.libby.logging.adapters.JDKLogAdapter;
import org.bukkit.plugin.Plugin;
+import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URLClassLoader;
import java.nio.file.Path;
@@ -15,10 +16,19 @@
* See: Paper docs
*/
public class PaperLibraryManager extends LibraryManager {
+ /**
+ * Default libraries.json name (see Minecrell/plugin-yml repository at GitHub)
+ */
+ private static final String DEFAULT_JSON = "paper-libraries.json";
+
/**
* Plugin classpath helper
*/
private final URLClassLoaderHelper classLoader;
+ /**
+ * The plugin
+ */
+ private final Plugin plugin;
/**
* Creates a new Paper library manager.
@@ -71,6 +81,7 @@ public PaperLibraryManager(Plugin plugin, String directoryName) {
}
classLoader = new URLClassLoaderHelper(libraryLoader, this);
+ this.plugin = plugin;
}
/**
@@ -82,4 +93,23 @@ public PaperLibraryManager(Plugin plugin, String directoryName) {
protected void addToClasspath(Path file) {
classLoader.addToClasspath(file);
}
+
+ /**
+ * Load the libraries by reading {@link #DEFAULT_JSON} file in the plugin.
+ */
+ public void loadLibrariesInJsonFile() {
+ loadLibrariesInJsonFile(DEFAULT_JSON);
+ }
+
+ /**
+ * Load the libraries by reading provided JSON file in the plugin.
+ *
+ * @param resourcePath The path to the JSON file
+ */
+ public void loadLibrariesInJsonFile(String resourcePath) {
+ final InputStream stream = plugin.getResource(resourcePath);
+ if (stream != null) {
+ loadLibrariesInJsonFile(stream);
+ }
+ }
}