diff --git a/pom.xml b/pom.xml
index 0949061fc..9c04f1e21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,6 +9,7 @@
UTF-8
UNKNOWN
+ bitly-access-token
@@ -69,6 +70,17 @@
${env.BUILD_NUMBER}
+
+ bitly
+
+
+ env.BITLY_ACCESS_TOKEN
+
+
+
+ ${env.BITLY_ACCESS_TOKEN}
+
+
@@ -90,21 +102,44 @@
1.4.1
+ replace-bitly-access-token
+ generate-sources
+
+ replace
+
+
+ ${project.build.sourceDirectory}
+
+ com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java
+
+
+
+ bitly-access-token
+ ${project.bitly-access-token}
+
+
+
+
+
+ replace-maven-version-number
prepare-package
replace
+
+ ${project.build.directory}/classes
+
+ plugin.yml
+
+
+
+ maven-version-number
+ ${project.version}-b${project.build.number}
+
+
+
-
- target/classes/plugin.yml
-
-
- maven-version-number
- ${project.version}-b${project.build.number}
-
-
-
diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/VersionCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/VersionCommand.java
index b2ac51e40..3f4b26f52 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/commands/VersionCommand.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/commands/VersionCommand.java
@@ -10,12 +10,13 @@
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
-import com.onarandombox.MultiverseCore.utils.webpaste.BitlyURLShortener;
import com.onarandombox.MultiverseCore.utils.webpaste.PasteFailedException;
import com.onarandombox.MultiverseCore.utils.webpaste.PasteService;
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceFactory;
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceType;
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortener;
+import com.onarandombox.MultiverseCore.utils.webpaste.URLShortenerFactory;
+import com.onarandombox.MultiverseCore.utils.webpaste.URLShortenerType;
import com.pneumaticraft.commandhandler.CommandHandler;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
@@ -24,9 +25,12 @@
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.scheduler.BukkitRunnable;
-import org.bukkit.util.StringUtil;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -35,94 +39,89 @@
* Dumps version info to the console.
*/
public class VersionCommand extends MultiverseCommand {
- private static final URLShortener SHORTENER = new BitlyURLShortener();
+ private static final URLShortener SHORTENER = URLShortenerFactory.getService(URLShortenerType.BITLY);
public VersionCommand(MultiverseCore plugin) {
super(plugin);
this.setName("Multiverse Version");
- this.setCommandUsage("/mv version " + ChatColor.GOLD + "-[bh] [--include-plugin-list]");
+ this.setCommandUsage("/mv version " + ChatColor.GOLD + "-[bhp] [--include-plugin-list]");
this.setArgRange(0, 2);
this.addKey("mv version");
this.addKey("mvv");
this.addKey("mvversion");
this.setPermission("multiverse.core.version",
- "Dumps version info to the console, optionally to pastie.org with -p or pastebin.com with a -b.", PermissionDefault.TRUE);
+ "Dumps version info to the console, optionally to pastebin.com with -b, to hastebin.com using -h, or to paste.gg with -p.", PermissionDefault.TRUE);
}
private String getLegacyString() {
- StringBuilder legacyFile = new StringBuilder();
- legacyFile.append("[Multiverse-Core] Multiverse-Core Version: ").append(this.plugin.getDescription().getVersion()).append('\n');
- legacyFile.append("[Multiverse-Core] Bukkit Version: ").append(this.plugin.getServer().getVersion()).append('\n');
- legacyFile.append("[Multiverse-Core] Loaded Worlds: ").append(this.plugin.getMVWorldManager().getMVWorlds()).append('\n');
- legacyFile.append("[Multiverse-Core] Multiverse Plugins Loaded: ").append(this.plugin.getPluginCount()).append('\n');
- legacyFile.append("[Multiverse-Core] Economy being used: ").append(plugin.getEconomist().getEconomyName()).append('\n');
- legacyFile.append("[Multiverse-Core] Permissions Plugin: ").append(this.plugin.getMVPerms().getType()).append('\n');
- legacyFile.append("[Multiverse-Core] Dumping Config Values: (version ")
- .append(this.plugin.getMVConfig().getVersion()).append(")").append('\n');
- legacyFile.append("[Multiverse-Core] messagecooldown: ").append(plugin.getMessaging().getCooldown()).append('\n');
- legacyFile.append("[Multiverse-Core] teleportcooldown: ").append(plugin.getMVConfig().getTeleportCooldown()).append('\n');
- legacyFile.append("[Multiverse-Core] worldnameprefix: ").append(plugin.getMVConfig().getPrefixChat()).append('\n');
- legacyFile.append("[Multiverse-Core] worldnameprefixFormat: ").append(plugin.getMVConfig().getPrefixChatFormat()).append('\n');
- legacyFile.append("[Multiverse-Core] enforceaccess: ").append(plugin.getMVConfig().getEnforceAccess()).append('\n');
- legacyFile.append("[Multiverse-Core] displaypermerrors: ").append(plugin.getMVConfig().getDisplayPermErrors()).append('\n');
- legacyFile.append("[Multiverse-Core] teleportintercept: ").append(plugin.getMVConfig().getTeleportIntercept()).append('\n');
- legacyFile.append("[Multiverse-Core] firstspawnoverride: ").append(plugin.getMVConfig().getFirstSpawnOverride()).append('\n');
- legacyFile.append("[Multiverse-Core] firstspawnworld: ").append(plugin.getMVConfig().getFirstSpawnWorld()).append('\n');
- legacyFile.append("[Multiverse-Core] debug: ").append(plugin.getMVConfig().getGlobalDebug()).append('\n');
- legacyFile.append("[Multiverse-Core] Special Code: FRN002").append('\n');
- return legacyFile.toString();
+ return "[Multiverse-Core] Multiverse-Core Version: " + this.plugin.getDescription().getVersion() + System.lineSeparator() +
+ "[Multiverse-Core] Bukkit Version: " + this.plugin.getServer().getVersion() + System.lineSeparator() +
+ "[Multiverse-Core] Loaded Worlds: " + this.plugin.getMVWorldManager().getMVWorlds() + System.lineSeparator() +
+ "[Multiverse-Core] Multiverse Plugins Loaded: " + this.plugin.getPluginCount() + System.lineSeparator() +
+ "[Multiverse-Core] Economy being used: " + plugin.getEconomist().getEconomyName() + System.lineSeparator() +
+ "[Multiverse-Core] Permissions Plugin: " + this.plugin.getMVPerms().getType() + System.lineSeparator() +
+ "[Multiverse-Core] Dumping Config Values: (version " + this.plugin.getMVConfig().getVersion() + ")" + System.lineSeparator() +
+ "[Multiverse-Core] messagecooldown: " + plugin.getMessaging().getCooldown() + System.lineSeparator() +
+ "[Multiverse-Core] teleportcooldown: " + plugin.getMVConfig().getTeleportCooldown() + System.lineSeparator() +
+ "[Multiverse-Core] worldnameprefix: " + plugin.getMVConfig().getPrefixChat() + System.lineSeparator() +
+ "[Multiverse-Core] worldnameprefixFormat: " + plugin.getMVConfig().getPrefixChatFormat() + System.lineSeparator() +
+ "[Multiverse-Core] enforceaccess: " + plugin.getMVConfig().getEnforceAccess() + System.lineSeparator() +
+ "[Multiverse-Core] displaypermerrors: " + plugin.getMVConfig().getDisplayPermErrors() + System.lineSeparator() +
+ "[Multiverse-Core] teleportintercept: " + plugin.getMVConfig().getTeleportIntercept() + System.lineSeparator() +
+ "[Multiverse-Core] firstspawnoverride: " + plugin.getMVConfig().getFirstSpawnOverride() + System.lineSeparator() +
+ "[Multiverse-Core] firstspawnworld: " + plugin.getMVConfig().getFirstSpawnWorld() + System.lineSeparator() +
+ "[Multiverse-Core] debug: " + plugin.getMVConfig().getGlobalDebug() + System.lineSeparator() +
+ "[Multiverse-Core] Special Code: FRN002" + System.lineSeparator();
}
private String getMarkdownString() {
- StringBuilder markdownString = new StringBuilder();
- markdownString.append("# Multiverse-Core\n");
- markdownString.append("## Overview\n");
- markdownString.append("| Name | Value |\n");
- markdownString.append("| --- | --- |\n");
- markdownString.append("| Multiverse-Core Version | `").append(this.plugin.getDescription().getVersion()).append("` |\n");
- markdownString.append("| Bukkit Version | `").append(this.plugin.getServer().getVersion()).append("` |\n");
- //markdownString.append("| Loaded Worlds | `").append(this.plugin.getMVWorldManager().getMVWorlds()).append("` |\n");
- markdownString.append("| Multiverse Plugins Loaded | `").append(this.plugin.getPluginCount()).append("` |\n");
- markdownString.append("| Economy being used | `").append(plugin.getEconomist().getEconomyName()).append("` |\n");
- markdownString.append("| Permissions Plugin | `").append(this.plugin.getMVPerms().getType()).append("` |\n");
- markdownString.append("## Parsed Config\n");
- markdownString.append("These are what Multiverse thought the in-memory values of the config were.\n\n");
- markdownString.append("| Config Key | Value |\n");
- markdownString.append("| --- | --- |\n");
- markdownString.append("| version | `").append(this.plugin.getMVConfig().getVersion()).append("` |\n");
- markdownString.append("| messagecooldown | `").append(plugin.getMessaging().getCooldown()).append("` |\n");
- markdownString.append("| teleportcooldown | `").append(plugin.getMVConfig().getTeleportCooldown()).append("` |\n");
- markdownString.append("| worldnameprefix | `").append(plugin.getMVConfig().getPrefixChat()).append("` |\n");
- markdownString.append("| worldnameprefixFormat | `").append(plugin.getMVConfig().getPrefixChatFormat()).append("` |\n");
- markdownString.append("| enforceaccess | `").append(plugin.getMVConfig().getEnforceAccess()).append("` |\n");
- markdownString.append("| displaypermerrors | `").append(plugin.getMVConfig().getDisplayPermErrors()).append("` |\n");
- markdownString.append("| teleportintercept | `").append(plugin.getMVConfig().getTeleportIntercept()).append("` |\n");
- markdownString.append("| firstspawnoverride | `").append(plugin.getMVConfig().getFirstSpawnOverride()).append("` |\n");
- markdownString.append("| firstspawnworld | `").append(plugin.getMVConfig().getFirstSpawnWorld()).append("` |\n");
- markdownString.append("| debug | `").append(plugin.getMVConfig().getGlobalDebug()).append("` |\n");
- return markdownString.toString();
+ return "# Multiverse-Core" + System.lineSeparator() +
+ "## Overview" + System.lineSeparator() +
+ "| Name | Value |" + System.lineSeparator() +
+ "| --- | --- |" + System.lineSeparator() +
+ "| Multiverse-Core Version | `" + this.plugin.getDescription().getVersion() + "` |" + System.lineSeparator() +
+ "| Bukkit Version | `" + this.plugin.getServer().getVersion() + "` |" + System.lineSeparator() +
+ "| Loaded Worlds | `" + this.plugin.getMVWorldManager().getMVWorlds() + "` |" + System.lineSeparator() +
+ "| Multiverse Plugins Loaded | `" + this.plugin.getPluginCount() + "` |" + System.lineSeparator() +
+ "| Economy being used | `" + plugin.getEconomist().getEconomyName() + "` |" + System.lineSeparator() +
+ "| Permissions Plugin | `" + this.plugin.getMVPerms().getType() + "` |" + System.lineSeparator() +
+ "## Parsed Config" + System.lineSeparator() +
+ "These are what Multiverse thought the in-memory values of the config were." + System.lineSeparator() + System.lineSeparator() +
+ "| Config Key | Value |" + System.lineSeparator() +
+ "| --- | --- |" + System.lineSeparator() +
+ "| version | `" + this.plugin.getMVConfig().getVersion() + "` |" + System.lineSeparator() +
+ "| messagecooldown | `" + plugin.getMessaging().getCooldown() + "` |" + System.lineSeparator() +
+ "| teleportcooldown | `" + plugin.getMVConfig().getTeleportCooldown() + "` |" + System.lineSeparator() +
+ "| worldnameprefix | `" + plugin.getMVConfig().getPrefixChat() + "` |" + System.lineSeparator() +
+ "| worldnameprefixFormat | `" + plugin.getMVConfig().getPrefixChatFormat() + "` |" + System.lineSeparator() +
+ "| enforceaccess | `" + plugin.getMVConfig().getEnforceAccess() + "` |" + System.lineSeparator() +
+ "| displaypermerrors | `" + plugin.getMVConfig().getDisplayPermErrors() + "` |" + System.lineSeparator() +
+ "| teleportintercept | `" + plugin.getMVConfig().getTeleportIntercept() + "` |" + System.lineSeparator() +
+ "| firstspawnoverride | `" + plugin.getMVConfig().getFirstSpawnOverride() + "` |" + System.lineSeparator() +
+ "| firstspawnworld | `" + plugin.getMVConfig().getFirstSpawnWorld() + "` |" + System.lineSeparator() +
+ "| debug | `" + plugin.getMVConfig().getGlobalDebug() + "` |" + System.lineSeparator();
}
private String readFile(final String filename) {
- String result;
+ StringBuilder result;
try {
FileReader reader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
- result = "";
+ result = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
- result += line + '\n';
+ result.append(line).append(System.lineSeparator());
}
} catch (FileNotFoundException e) {
Logging.severe("Unable to find %s. Here's the traceback: %s", filename, e.getMessage());
e.printStackTrace();
- result = String.format("ERROR: Could not load: %s", filename);
+ result = new StringBuilder(String.format("ERROR: Could not load: %s", filename));
} catch (IOException e) {
Logging.severe("Something bad happend when reading %s. Here's the traceback: %s", filename, e.getMessage());
e.printStackTrace();
- result = String.format("ERROR: Could not load: %s", filename);
+ result = new StringBuilder(String.format("ERROR: Could not load: %s", filename));
}
- return result;
+ return result.toString();
}
private Map getVersionFiles() {
@@ -135,7 +134,7 @@ private Map getVersionFiles() {
File configFile = new File(this.plugin.getDataFolder(), "config.yml");
files.put(configFile.getName(), this.readFile(configFile.getAbsolutePath()));
- // Add the config.yml
+ // Add the worlds.yml
File worldConfig = new File(this.plugin.getDataFolder(), "worlds.yml");
files.put(worldConfig.getName(), this.readFile(worldConfig.getAbsolutePath()));
return files;
@@ -149,19 +148,20 @@ public void runCommand(final CommandSender sender, final List args) {
}
MVVersionEvent versionEvent = new MVVersionEvent(this.getLegacyString(), this.getVersionFiles());
- final Map files = this.getVersionFiles();
this.plugin.getServer().getPluginManager().callEvent(versionEvent);
String versionInfo = versionEvent.getVersionInfo();
+ Map files = versionEvent.getDetailedVersionInfo();
if (CommandHandler.hasFlag("--include-plugin-list", args)) {
- versionInfo = versionInfo + "\nPlugins: " + getPluginList();
+ versionInfo = versionInfo + System.lineSeparator() + "Plugins: " + getPluginList();
+ files.put("plugins.txt", "Plugins: " + getPluginList());
}
final String data = versionInfo;
// log to console
- String[] lines = data.split("\n");
+ String[] lines = data.split(System.lineSeparator());
for (String line : lines) {
if (!line.isEmpty()) {
Logging.info(line);
@@ -176,9 +176,15 @@ public void run() {
if (CommandHandler.hasFlag("-b", args)) {
// private post to pastebin
pasteUrl = postToService(PasteServiceType.PASTEBIN, true, data, files);
+ } else if (CommandHandler.hasFlag("-g", args)) {
+ // private post to github
+ pasteUrl = postToService(PasteServiceType.GITHUB, true, data, files);
} else if (CommandHandler.hasFlag("-h", args)) {
- // private post to pastebin
+ // private post to hastebin
pasteUrl = postToService(PasteServiceType.HASTEBIN, true, data, files);
+ } else if (CommandHandler.hasFlag("-p", args)) {
+ // private post to paste.gg
+ pasteUrl = postToService(PasteServiceType.PASTEGG, true, data, files);
} else {
return;
}
@@ -204,20 +210,25 @@ public void run() {
* @param pasteFiles Map of filenames/contents of debug info.
* @return URL of visible paste
*/
- private static String postToService(PasteServiceType type, boolean isPrivate, String pasteData,
- Map pasteFiles) {
+ private static String postToService(PasteServiceType type, boolean isPrivate, String pasteData, Map pasteFiles) {
PasteService ps = PasteServiceFactory.getService(type, isPrivate);
+
try {
String result;
if (ps.supportsMultiFile()) {
- result = ps.postData(ps.encodeData(pasteFiles), ps.getPostURL());
+ result = ps.postData(pasteFiles);
} else {
- result = ps.postData(ps.encodeData(pasteData), ps.getPostURL());
+ result = ps.postData(pasteData);
}
- return SHORTENER.shorten(result);
+
+ if (SHORTENER != null) return SHORTENER.shorten(result);
+ return result;
} catch (PasteFailedException e) {
- System.out.print(e);
- return "Error posting to service";
+ e.printStackTrace();
+ return "Error posting to service.";
+ } catch (NullPointerException e) {
+ e.printStackTrace();
+ return "That service isn't supported yet.";
}
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/event/MVVersionEvent.java b/src/main/java/com/onarandombox/MultiverseCore/event/MVVersionEvent.java
index 43c1ddfc1..a63d7020a 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/event/MVVersionEvent.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/event/MVVersionEvent.java
@@ -66,4 +66,13 @@ public Map getDetailedVersionInfo() {
public void appendVersionInfo(String moreVersionInfo) {
this.versionInfoBuilder.append(moreVersionInfo);
}
+
+ /**
+ * Adds a file to to the detailed version-info currently saved in this event.
+ * @param filename The name of the file.
+ * @param text The file's content.
+ */
+ public void putDetailedVersionInfo(String filename, String text) {
+ this.detailedVersionInfo.put(filename, text);
+ }
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java
index e700c2e32..96fadd226 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java
@@ -1,19 +1,41 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
import java.io.IOException;
+import java.util.Map;
/**
- * An {@link URLShortener} using {@code bit.ly}.
+ * A {@link URLShortener} using {@code bit.ly}. Requires an access token.
*/
-public class BitlyURLShortener extends HttpAPIClient implements URLShortener {
- private static final String GENERIC_BITLY_REQUEST_FORMAT = "https://api-ssl.bitly.com/v3/shorten?format=txt&apiKey=%s&login=%s&longUrl=%s";
+class BitlyURLShortener extends URLShortener {
+ private static final String ACCESS_TOKEN = "Bearer bitly-access-token";
+ private static final String BITLY_POST_REQUEST = "https://api-ssl.bitly.com/v4/shorten";
+
+ BitlyURLShortener() {
+ super(BITLY_POST_REQUEST, ACCESS_TOKEN);
+ if (ACCESS_TOKEN.endsWith("access-token")) throw new UnsupportedOperationException();
+ }
- // I think it's no problem that these are public
- private static final String USERNAME = "multiverse2";
- private static final String API_KEY = "R_9dbff4862a3bc0c4218a7d78cc10d0e0";
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ String encodeData(String data) {
+ JSONObject json = new JSONObject();
+ json.put("domain", "j.mp");
+ json.put("long_url", data);
+ return json.toJSONString();
+ }
- public BitlyURLShortener() {
- super(String.format(GENERIC_BITLY_REQUEST_FORMAT, API_KEY, USERNAME, "%s"));
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ String encodeData(Map data) {
+ throw new UnsupportedOperationException();
}
/**
@@ -22,13 +44,11 @@ public BitlyURLShortener() {
@Override
public String shorten(String longUrl) {
try {
- String result = this.exec(longUrl);
- if (!result.startsWith("http://j.mp/")) // ... then it's failed :/
- throw new IOException(result);
- return result;
- } catch (IOException e) {
+ String stringJSON = this.exec(encodeData(longUrl), ContentType.JSON);
+ return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("link");
+ } catch (IOException | ParseException e) {
e.printStackTrace();
- return longUrl; // sorry ...
+ return longUrl;
}
}
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/GitHubPasteService.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/GitHubPasteService.java
new file mode 100644
index 000000000..717ac3c4a
--- /dev/null
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/GitHubPasteService.java
@@ -0,0 +1,88 @@
+package com.onarandombox.MultiverseCore.utils.webpaste;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Pastes to {@code gist.github.com}. Requires an access token with the {@code gist} scope.
+ */
+class GitHubPasteService extends PasteService {
+ private final boolean isPrivate;
+ // this access token must have the "gist" scope
+ private static final String ACCESS_TOKEN = "token github-access-token";
+ private static final String GITHUB_POST_REQUEST = "https://api.github.com/gists";
+
+ GitHubPasteService(boolean isPrivate) {
+ super(GITHUB_POST_REQUEST, ACCESS_TOKEN);
+ this.isPrivate = isPrivate;
+ if (ACCESS_TOKEN.endsWith("access-token")) throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ String encodeData(String data) {
+ Map mapData = new HashMap();
+ mapData.put("multiverse.txt", data);
+ return this.encodeData(mapData);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ String encodeData(Map files) {
+ JSONObject root = new JSONObject();
+ root.put("description", "Multiverse-Core Debug Info");
+ root.put("public", !this.isPrivate);
+ JSONObject fileList = new JSONObject();
+ for (Map.Entry entry : files.entrySet()) {
+ JSONObject fileObject = new JSONObject();
+ fileObject.put("content", entry.getValue());
+ fileList.put(entry.getKey(), fileObject);
+ }
+
+ root.put("files", fileList);
+ return root.toJSONString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String postData(String data) throws PasteFailedException {
+ try {
+ String stringJSON = this.exec(encodeData(data), ContentType.JSON);
+ return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
+ } catch (IOException | ParseException e) {
+ throw new PasteFailedException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String postData(Map data) throws PasteFailedException {
+ try {
+ String stringJSON = this.exec(encodeData(data), ContentType.JSON);
+ return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
+ } catch (IOException | ParseException e) {
+ throw new PasteFailedException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean supportsMultiFile() {
+ return true;
+ }
+}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/GithubPasteService.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/GithubPasteService.java
deleted file mode 100644
index 6d8409692..000000000
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/GithubPasteService.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.onarandombox.MultiverseCore.utils.webpaste;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonPrimitive;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class GithubPasteService implements PasteService {
-
- private final boolean isPrivate;
-
- public GithubPasteService(boolean isPrivate) {
- this.isPrivate = isPrivate;
- }
-
- @Override
- public String encodeData(String data) {
- Map mapData = new HashMap();
- mapData.put("multiverse.txt", data);
- return this.encodeData(mapData);
- }
-
- @Override
- public String encodeData(Map files) {
- JsonObject root = new JsonObject();
- root.add("description", new JsonPrimitive("Multiverse-Core Debug Info"));
- root.add("public", new JsonPrimitive(!this.isPrivate));
- JsonObject fileList = new JsonObject();
- for (Map.Entry entry : files.entrySet())
- {
- JsonObject fileObject = new JsonObject();
- fileObject.add("content", new JsonPrimitive(entry.getValue()));
- fileList.add(entry.getKey(), fileObject);
- }
- root.add("files", fileList);
- return root.toString();
- }
-
- @Override
- public URL getPostURL() {
- try {
- return new URL("https://api.github.com/gists");
- //return new URL("http://jsonplaceholder.typicode.com/posts");
- } catch (MalformedURLException e) {
- return null; // should never hit here
- }
- }
-
- @Override
- public String postData(String encodedData, URL url) throws PasteFailedException {
- OutputStreamWriter wr = null;
- BufferedReader rd = null;
- try {
- URLConnection conn = url.openConnection();
- conn.setDoOutput(true);
- wr = new OutputStreamWriter(conn.getOutputStream());
- wr.write(encodedData);
- wr.flush();
-
- rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- String line;
- String pastieUrl = "";
- //Pattern pastiePattern = this.getURLMatchingPattern();
- StringBuilder responseString = new StringBuilder();
-
- while ((line = rd.readLine()) != null) {
- responseString.append(line);
- }
- return new JsonParser().parse(responseString.toString()).getAsJsonObject().get("html_url").getAsString();
- } catch (Exception e) {
- throw new PasteFailedException(e);
- } finally {
- if (wr != null) {
- try {
- wr.close();
- } catch (IOException ignore) { }
- }
- if (rd != null) {
- try {
- rd.close();
- } catch (IOException ignore) { }
- }
- }
- }
-
- @Override
- public boolean supportsMultiFile() {
- return true;
- }
-}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HastebinPasteService.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HastebinPasteService.java
index 69438cfd7..46af2d29c 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HastebinPasteService.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HastebinPasteService.java
@@ -1,79 +1,67 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
import java.util.Map;
/**
* Pastes to {@code hastebin.com}.
*/
-public class HastebinPasteService implements PasteService {
+class HastebinPasteService extends PasteService {
+ private static final String HASTEBIN_POST_REQUEST = "https://hastebin.com/documents";
+ HastebinPasteService() {
+ super(HASTEBIN_POST_REQUEST, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String encodeData(String data) {
+ String encodeData(String data) {
return data;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String encodeData(Map data) {
+ String encodeData(Map data) {
throw new UnsupportedOperationException();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public URL getPostURL() {
+ public String postData(String data) throws PasteFailedException {
try {
- return new URL("https://hastebin.com/documents");
- } catch (MalformedURLException e) {
- return null; // should never hit here
+ String stringJSON = this.exec(encodeData(data), ContentType.PLAINTEXT);
+ return "https://hastebin.com/" + ((JSONObject) new JSONParser().parse(stringJSON)).get("key");
+ } catch (IOException | ParseException e) {
+ throw new PasteFailedException(e);
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String postData(String encodedData, URL url) throws PasteFailedException {
- OutputStreamWriter wr = null;
- BufferedReader rd = null;
+ public String postData(Map data) throws PasteFailedException {
try {
- URLConnection conn = url.openConnection();
- conn.setDoOutput(true);
-
- wr = new OutputStreamWriter(conn.getOutputStream());
- rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
-
- wr.write(encodedData);
- wr.flush();
-
- String line;
- StringBuilder responseString = new StringBuilder();
- while ((line = rd.readLine()) != null) {
- responseString.append(line);
- }
- String key = new JsonParser().parse(responseString.toString()).getAsJsonObject().get("key").getAsString();
-
- return "https://hastebin.com/" + key;
- } catch (Exception e) {
+ String stringJSON = this.exec(encodeData(data), ContentType.PLAINTEXT);
+ return "https://hastebin.com/" + ((JSONObject) new JSONParser().parse(stringJSON)).get("key");
+ } catch (IOException | ParseException e) {
throw new PasteFailedException(e);
- } finally {
- if (wr != null) {
- try {
- wr.close();
- } catch (IOException ignore) { }
- }
- if (rd != null) {
- try {
- rd.close();
- } catch (IOException ignore) { }
- }
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean supportsMultiFile() {
return false;
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HttpAPIClient.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HttpAPIClient.java
index 55d69c5c0..8e423fcce 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HttpAPIClient.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/HttpAPIClient.java
@@ -1,50 +1,120 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
+import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import java.net.URL;
-import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
/**
* HTTP API-client.
*/
-public abstract class HttpAPIClient {
+abstract class HttpAPIClient {
/**
- * The URL for this API-request.
+ * The URL for this API-request, and if necessary, the access token.
+ * If an access token is not necessary, it should be set to null.
*/
- protected final String urlFormat;
+ private final String url;
+ private final String accessToken;
- public HttpAPIClient(String urlFormat) {
- this.urlFormat = urlFormat;
+ /**
+ * Types of data that can be sent.
+ */
+ enum ContentType {
+ JSON,
+ PLAINTEXT,
+ URLENCODED
+ }
+
+ HttpAPIClient(String url, String accessToken) {
+ this.url = url;
+ this.accessToken = accessToken;
}
+ /**
+ * Returns the HTTP Content-Type header that corresponds with each ContentType.
+ * @param type The type of data.
+ * @return The HTTP Content-Type header that corresponds with the type of data.
+ */
+ private String getContentHeader(ContentType type) {
+ switch (type) {
+ case JSON:
+ return "application/json; charset=utf-8";
+ case PLAINTEXT:
+ return "text/plain; charset=utf-8";
+ case URLENCODED:
+ return "application/x-www-form-urlencoded; charset=utf-8";
+ default:
+ throw new IllegalStateException("Unexpected value: " + type);
+ }
+ }
+
+ /**
+ * Encode the given String data into a format suitable for transmission in an HTTP request.
+ *
+ * @param data The raw data to encode.
+ * @return A URL-encoded string.
+ */
+ abstract String encodeData(String data);
+
+ /**
+ * Encode the given Map data into a format suitable for transmission in an HTTP request.
+ *
+ * @param data The raw data to encode.
+ * @return A URL-encoded string.
+ */
+ abstract String encodeData(Map data);
+
/**
* Executes this API-Request.
- * @param args Format-args.
+ * @param payload The data that will be sent.
+ * @param type The type of data that will be sent.
* @return The result (as text).
* @throws IOException When the I/O-operation failed.
*/
- protected final String exec(Object... args) throws IOException {
+ final String exec(String payload, ContentType type) throws IOException {
+ BufferedReader rd = null;
+ OutputStreamWriter wr = null;
- URLConnection conn = new URL(String.format(this.urlFormat, args)).openConnection();
- conn.connect();
- StringBuilder ret = new StringBuilder();
- BufferedReader reader = null;
try {
- reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- while (!reader.ready()); // wait until reader is ready, may not be necessary, SUPPRESS CHECKSTYLE: EmptyStatement
+ HttpsURLConnection conn = (HttpsURLConnection) new URL(this.url).openConnection();
+ conn.setRequestMethod("POST");
+ conn.setDoOutput(true);
- while (reader.ready()) {
- ret.append(reader.readLine()).append('\n');
- }
+ // we can receive anything!
+ conn.addRequestProperty("Accept", "*/*");
+ // set a dummy User-Agent
+ conn.addRequestProperty("User-Agent", "placeholder");
+ // this isn't required, but is technically correct
+ conn.addRequestProperty("Content-Type", getContentHeader(type));
+ // only some API requests require an access token
+ if (this.accessToken != null) conn.addRequestProperty("Authorization", this.accessToken);
+
+ wr = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8.newEncoder());
+ wr.write(payload);
+ wr.flush();
+
+ String line;
+ StringBuilder responseString = new StringBuilder();
+ // this has to be initialized AFTER the data has been flushed!
+ rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
+
+ while ((line = rd.readLine()) != null) responseString.append(line);
+ return responseString.toString();
} finally {
- if (reader != null) {
+ if (wr != null) {
+ try {
+ wr.close();
+ } catch (IOException ignore) { }
+ }
+ if (rd != null) {
try {
- reader.close();
+ rd.close();
} catch (IOException ignore) { }
}
}
- return ret.toString();
}
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteFailedException.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteFailedException.java
index 85a803a4b..82792f499 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteFailedException.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteFailedException.java
@@ -1,7 +1,7 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
/**
- * Thrown when pasting failed.
+ * Thrown when pasting fails.
*/
public class PasteFailedException extends Exception {
public PasteFailedException() {
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteGGPasteService.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteGGPasteService.java
new file mode 100644
index 000000000..179bba003
--- /dev/null
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteGGPasteService.java
@@ -0,0 +1,90 @@
+package com.onarandombox.MultiverseCore.utils.webpaste;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Pastes to {@code paste.gg}.
+ */
+class PasteGGPasteService extends PasteService {
+ private final boolean isPrivate;
+ private static final String PASTEGG_POST_REQUEST = "https://api.paste.gg/v1/pastes";
+
+ PasteGGPasteService(boolean isPrivate) {
+ super(PASTEGG_POST_REQUEST, null);
+ this.isPrivate = isPrivate;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ String encodeData(String data) {
+ Map mapData = new HashMap();
+ mapData.put("multiverse.txt", data);
+ return this.encodeData(mapData);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ String encodeData(Map files) {
+ JSONObject root = new JSONObject();
+ root.put("name", "Multiverse-Core Debug Info");
+ root.put("visibility", this.isPrivate ? "unlisted" : "public");
+ JSONArray fileList = new JSONArray();
+ for (Map.Entry entry : files.entrySet()) {
+ JSONObject fileObject = new JSONObject();
+ JSONObject contentObject = new JSONObject();
+ fileObject.put("name", entry.getKey());
+ fileObject.put("content", contentObject);
+ contentObject.put("format", "text");
+ contentObject.put("value", entry.getValue());
+ fileList.add(fileObject);
+ }
+
+ root.put("files", fileList);
+ return root.toJSONString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String postData(String data) throws PasteFailedException {
+ try {
+ String stringJSON = this.exec(encodeData(data), ContentType.JSON);
+ return (String) ((JSONObject) ((JSONObject) new JSONParser().parse(stringJSON)).get("result")).get("id");
+ } catch (IOException | ParseException e) {
+ throw new PasteFailedException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String postData(Map data) throws PasteFailedException {
+ try {
+ String stringJSON = this.exec(encodeData(data), ContentType.JSON);
+ return "https://paste.gg/" + ((JSONObject) ((JSONObject) new JSONParser().parse(stringJSON)).get("result")).get("id");
+ } catch (IOException | ParseException e) {
+ throw new PasteFailedException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean supportsMultiFile() {
+ return true;
+ }
+}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteService.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteService.java
index 403f5ab83..0c474c9e8 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteService.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteService.java
@@ -1,63 +1,48 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
-import java.net.URL;
import java.util.Map;
/**
- * An interface to a web-based text-pasting service. Classes implementing this
- * interface should implement its methods to send data to an online text-sharing
- * service, such as pastebin.com. Conventionally, a paste is accomplished by (given
- * some PasteService instance ps):
+ * An interface to a web-based text-pasting service. Classes extending this
+ * should implement its methods to send data to an online text-sharing service,
+ * such as pastebin.com. Given some PasteService instance ps, a paste is accomplished by:
*
- * {@code ps.postData(ps.encodeData(someString), ps.getPostURL());}
+ * {@code ps.postData(someString);}
*
* Services that provide a distinction between "public" and "private" pastes
- * should implement a custom constructor that specifies which kind the PasteService
+ * should implement a constructor that specifies which kind the PasteService
* instance is submitting; an example of this is the PastebinPasteService class.
*/
-public interface PasteService {
+public abstract class PasteService extends HttpAPIClient {
+ PasteService(String url, String accessToken) {
+ super(url, accessToken);
+ }
/**
- * Encode the given String data into a format suitable for transmission in an HTTP request.
+ * Post data to the Web.
*
- * @param data The raw data to encode.
- * @return A URL-encoded string.
- */
- String encodeData(String data);
-
- /**
- * Encode the given Map data into a format suitable for transmission in an HTTP request.
- *
- * @param data The raw data to encode.
- * @return A URL-encoded string.
- */
- String encodeData(Map data);
-
- /**
- * Get the URL to which this paste service sends new pastes.
- *
- * @return The URL that will be accessed to complete the paste.
+ * @param data A String to post to the web.
+ * @throws PasteFailedException When pasting/posting the data failed.
+ * @return The URL at which the new paste is visible.
*/
- URL getPostURL();
+ public abstract String postData(String data) throws PasteFailedException;
/**
- * Post encoded data to the Web.
+ * Post data to the Web.
*
- * @param encodedData A URL-encoded String containing the full request to post to
- * the given URL. Can be the result of calling #encodeData().
- * @param url The URL to which to paste. Can be the result of calling #getPostURL().
+ * @param data A Map to post to the web.
* @throws PasteFailedException When pasting/posting the data failed.
* @return The URL at which the new paste is visible.
*/
- String postData(String encodedData, URL url) throws PasteFailedException;
+ public abstract String postData(Map data) throws PasteFailedException;
/**
* Does this service support uploading multiple files.
*
- * Newer services like gist support multi-file which allows us to upload configs
- * in addition to the standard logs.
+ * Newer services like GitHub's Gist support multi-file pastes,
+ * which allows us to upload configs in addition to the standard logs.
*
* @return True if this service supports multiple file upload.
*/
- boolean supportsMultiFile();
+ public abstract boolean supportsMultiFile();
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceFactory.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceFactory.java
index df4fb8315..f6f63a1ce 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceFactory.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceFactory.java
@@ -14,12 +14,14 @@ private PasteServiceFactory() { }
*/
public static PasteService getService(PasteServiceType type, boolean isPrivate) {
switch(type) {
+ case PASTEGG:
+ return new PasteGGPasteService(isPrivate);
case PASTEBIN:
return new PastebinPasteService(isPrivate);
case HASTEBIN:
return new HastebinPasteService();
case GITHUB:
- return new GithubPasteService(isPrivate);
+ return new GitHubPasteService(isPrivate);
default:
return null;
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceType.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceType.java
index 0bd93e635..09424c0b5 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceType.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PasteServiceType.java
@@ -7,6 +7,10 @@
* @see PasteServiceFactory
*/
public enum PasteServiceType {
+ /**
+ * @see PasteGGPasteService
+ */
+ PASTEGG,
/**
* @see PastebinPasteService
*/
@@ -16,7 +20,7 @@ public enum PasteServiceType {
*/
HASTEBIN,
/**
- * @see GithubPasteService
+ * @see GitHubPasteService
*/
GITHUB
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PastebinPasteService.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PastebinPasteService.java
index 3f06f612e..ce7a44532 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PastebinPasteService.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/PastebinPasteService.java
@@ -1,24 +1,19 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;
/**
* Pastes to {@code pastebin.com}.
*/
-public class PastebinPasteService implements PasteService {
+class PastebinPasteService extends PasteService {
+ private final boolean isPrivate;
+ private static final String PASTEBIN_POST_REQUEST = "https://pastebin.com/api/api_post.php";
- private boolean isPrivate;
-
- public PastebinPasteService(boolean isPrivate) {
+ PastebinPasteService(boolean isPrivate) {
+ super(PASTEBIN_POST_REQUEST, null);
this.isPrivate = isPrivate;
}
@@ -26,11 +21,16 @@ public PastebinPasteService(boolean isPrivate) {
* {@inheritDoc}
*/
@Override
- public URL getPostURL() {
+ String encodeData(String data) {
try {
- return new URL("http://pastebin.com/api/api_post.php");
- } catch (MalformedURLException e) {
- return null; // should never hit here
+ return URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8") +
+ "&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8") +
+ "&" + URLEncoder.encode("api_paste_code", "UTF-8") + "=" + URLEncoder.encode(data, "UTF-8") +
+ "&" + URLEncoder.encode("api_paste_private", "UTF-8") + "=" + URLEncoder.encode(this.isPrivate ? "1" : "0", "UTF-8") +
+ "&" + URLEncoder.encode("api_paste_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8") +
+ "&" + URLEncoder.encode("api_paste_name", "UTF-8") + "=" + URLEncoder.encode("Multiverse-Core Debug Info", "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ return ""; // should never hit here
}
}
@@ -38,61 +38,37 @@ public URL getPostURL() {
* {@inheritDoc}
*/
@Override
- public String encodeData(String data) {
- try {
- String encData = URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8");
- encData += "&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8");
- encData += "&" + URLEncoder.encode("api_paste_code", "UTF-8") + "=" + URLEncoder.encode(data, "UTF-8");
- encData += "&" + URLEncoder.encode("api_paste_private", "UTF-8") + "=" + URLEncoder.encode(this.isPrivate ? "1" : "0", "UTF-8");
- encData += "&" + URLEncoder.encode("api_paste_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8");
- return encData;
- } catch (UnsupportedEncodingException e) {
- return ""; // should never hit here
- }
+ String encodeData(Map data) {
+ throw new UnsupportedOperationException();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public String encodeData(Map data) {
- return null;
+ public String postData(String data) throws PasteFailedException {
+ try {
+ return this.exec(encodeData(data), ContentType.URLENCODED);
+ } catch (IOException e) {
+ throw new PasteFailedException(e);
+ }
}
/**
* {@inheritDoc}
*/
@Override
- public String postData(String encodedData, URL url) throws PasteFailedException {
- OutputStreamWriter wr = null;
- BufferedReader rd = null;
+ public String postData(Map data) throws PasteFailedException {
try {
- URLConnection conn = url.openConnection();
- conn.setDoOutput(true);
- wr = new OutputStreamWriter(conn.getOutputStream());
- wr.write(encodedData);
- wr.flush();
-
- rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- String line;
- String pastebinUrl = "";
- while ((line = rd.readLine()) != null) {
- pastebinUrl = line;
- }
- return pastebinUrl;
- } catch (Exception e) {
+ return this.exec(encodeData(data), ContentType.URLENCODED);
+ } catch (IOException e) {
throw new PasteFailedException(e);
- } finally {
- if (wr != null) {
- try {
- wr.close();
- } catch (IOException ignore) { }
- }
- if (rd != null) {
- try {
- rd.close();
- } catch (IOException ignore) { }
- }
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean supportsMultiFile() {
return false;
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortener.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortener.java
index 75d50f634..be3d61b18 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortener.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortener.java
@@ -1,13 +1,23 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
/**
- * URL-Shortener.
+ * An interface to a web-based URL Shortener. Classes extending this should
+ * implement its methods to shorten links using the service. Given some
+ * URLShortener instance us, a URL is shortened by:
+ *
+ * {@code us.shorten(longUrl);}
+ *
+ * An example of this, is the BitlyURLShortener.
*/
-public interface URLShortener {
+public abstract class URLShortener extends HttpAPIClient {
+ URLShortener(String url, String accessToken) {
+ super(url, accessToken);
+ }
+
/**
- * Shorten an URL.
+ * Shorten a URL.
* @param longUrl The long form.
* @return The shortened URL.
*/
- String shorten(String longUrl);
+ public abstract String shorten(String longUrl);
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortenerFactory.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortenerFactory.java
new file mode 100644
index 000000000..c0f3cafac
--- /dev/null
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortenerFactory.java
@@ -0,0 +1,23 @@
+package com.onarandombox.MultiverseCore.utils.webpaste;
+
+/**
+ * Used to construct {@link URLShortener}s.
+ */
+public class URLShortenerFactory {
+ private URLShortenerFactory() { }
+
+ /**
+ * Constructs a new {@link URLShortener}.
+ * @param type The {@link URLShortenerType}.
+ * @return The newly created {@link URLShortener}.
+ */
+ public static URLShortener getService(URLShortenerType type) {
+ if (type == URLShortenerType.BITLY) {
+ try {
+ return new BitlyURLShortener();
+ } catch (UnsupportedOperationException ignored) {}
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortenerType.java b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortenerType.java
new file mode 100644
index 000000000..d2c809f51
--- /dev/null
+++ b/src/main/java/com/onarandombox/MultiverseCore/utils/webpaste/URLShortenerType.java
@@ -0,0 +1,14 @@
+package com.onarandombox.MultiverseCore.utils.webpaste;
+
+/**
+ * An enum containing all known {@link URLShortener}s.
+ *
+ * @see URLShortener
+ * @see URLShortenerFactory
+ */
+public enum URLShortenerType {
+ /**
+ * @see BitlyURLShortener
+ */
+ BITLY
+}