From d4fe28020152387012503f835694a4e2078cfd29 Mon Sep 17 00:00:00 2001
From: skylarmt
It will still exist online.
+ *
+ * @param id the pad ID.
+ */
+ public static void delPad(String id) {
+ String pads = PrefStorage.getSetting("pads");
+ String result = "";
+ int i = 0;
+ for (String pad : pads.split("\\|")) {
+ if (!pad.equals(id)) {
+ if (i > 0) {
+ result += "|";
+ }
+ result += pad;
+ i++;
+ }
+ }
+
+ PrefStorage.saveSetting("pads", result);
+ }
+
+ /**
+ * Get an array of saved pads.
+ *
+ * @return String[] of pad IDs
+ */
+ public static String[] getPads() {
+ String pads = PrefStorage.getSetting("pads");
+ if (!pads.equals("")) {
+ if (pads.contains("|")) {
+ return pads.split("\\|");
+ } else {
+ String[] padlist = {pads};
+ return padlist;
+ }
+ } else {
+ String[] padlist = {};
+ return padlist;
+ }
+ }
+
+ /**
+ * Create a new pad on the server with the given ID.
+ *
+ * @param id The pad ID to create. If blank is auto-generated.
+ * @param content Text to initialize the pad with.
+ * @return Created pad ID.
+ * @throws Exception if things break.
+ */
+ public static String genPad(String id, String content) throws Exception {
+ // Generate ID if blank
+ if (id.equals("")) {
+ id = genID();
+ }
+
+ // Create pad with given text.
+ try {
+ getClient().createPad(id, content);
+ } catch (EPLiteException ex) {
+ getClient().setText(id, content);
+ }
+ return id;
+ }
+
+ /**
+ * Generate a random pad ID.
+ *
+ * @return the ID.
+ */
+ public static String genID() {
+ int length = 15;
+ String[] chars = ("0123456789"
+ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ + "abcdefghijklmnopqrstuvwxyz").split("");
+ String out = "";
+ Random rng = new Random();
+
+ for (int i = 0; i < length; i++) {
+ out += chars[rng.nextInt(chars.length)];
+ }
+
+ return out;
+ }
+
+ /**
+ * Get a client for the pad API.
+ *
+ * @return the client.
+ * @throws IOException if things break.
+ */
+ public static EPLiteClient getClient() throws Exception {
+ // Load the API key from a file, so it's not included with Git.
+ String apikey;
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(
+ Pads.class
+ .getResourceAsStream("/padkey")));
+ apikey = reader.readLine();
+
+ // New client
+ return new EPLiteClient(PADS_URL, apikey);
+ }
+
+ /**
+ * Get the pad text.
+ *
+ * @param id the pad ID.
+ * @return the text, or error message.
+ */
+ public static String getPad(String id) {
+ String text = "";
+ try {
+ text = getClient().getText(id).getOrDefault("text", "").toString();
+ } catch (Exception ex) {
+ text = "Error: Could not get pad contents: " + ex.getMessage();
+ }
+ return text;
+ }
+
+ public static void setPad(String id, String content) {
+ try {
+ getClient().setText(id, content);
+ } catch (Exception ex) {
+ Debug.stacktrace(ex);
+ JOptionPane.showInternalMessageDialog(
+ MainGUI.mainPane,
+ "Could not sync pad contents: " + ex.getMessage(),
+ "Error",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ /**
+ * Delete the given pad ID.
+ *
+ * @param id the pad ID.
+ * @param purge If true will delete from server also.
+ */
+ public static void delPad(String id, boolean purge) {
+ delPad(id);
+ if (purge) {
+ try {
+ getClient().deletePad(id);
+ } catch (Exception ex) {
+ // Meh. No big deal.
+ }
+ }
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // Loading...
");
}
});
@@ -117,7 +118,9 @@ public class WebBrowser extends javax.swing.JInternalFrame {
case FORUM_LOGO:
setFrameIcon(new ImageIcon(getClass().getResource("/net/apocalypselabs/symat/icons/forum.png")));
break;
- case DEFAULT_LOGO:
+ case PAD_LOGO:
+ setFrameIcon(new ImageIcon(getClass().getResource("/net/apocalypselabs/symat/icons/editor.png")));
+ break;
default:
setFrameIcon(new ImageIcon(getClass().getResource("/net/apocalypselabs/symat/icons/browser.png")));
}
@@ -215,8 +218,8 @@ public class WebBrowser extends javax.swing.JInternalFrame {
@Override
public void run() {
jfxPanel.setSize(getWidth(), getHeight());
- browser.setPrefSize(getWidth()-12, getHeight()-12);
- browser.resize(getWidth() - 12, getHeight() - 12);
+ browser.setPrefSize(getWidth() - 12, getHeight() - 32);
+ browser.resize(getWidth() - 12, getHeight() - 32);
}
});
}
diff --git a/src/net/apocalypselabs/symat/help/licenses.html b/src/net/apocalypselabs/symat/help/licenses.html
index e826281..6ac32b9 100644
--- a/src/net/apocalypselabs/symat/help/licenses.html
+++ b/src/net/apocalypselabs/symat/help/licenses.html
@@ -48,7 +48,7 @@
contact Apocalypse Laboratories. If Apocalypse Laboratories allows or denies
you permission, that decision is considered final and binding.
Symja (parser), log4j, Java-Prettify:
+Symja (parser), log4j, Java-Prettify, json-simple, java-etherpad-lite:
Licensed under the Apache License, Version 2.0 (the "License"); _!8*@gVzNaDm+v{pVTaIP|CFG7ynoc#4xuKKB
z$q?nTHU~)csBG?@FpsRMsdU@T{U4sbq0r6R(iz(FopksWT%&<;#HGP2Hs0tnBor+{
zXfcKIXr12o!@pWp>~6D%p17}7NY@K=bY{B0{m)ySR7^Yj)9it)xAvXw|I(9zy2G~;TnBpN{Pv2UvfiB}aLM!n
zl#4wNZv1F$@{OI%vD;o5&mP@UAG>w`kQPao&+~$Z_{IUYJ%0`F-g}5`(K_7b2RYOH
zAZHrB$)J90WzhclmsSLN+w`iHr+5k~Bhw61KLtg&Lu#FhDm1h?hdy)Yn9B5FXr@r@
zcK#%BHyH(Go*@NAM7ABBj9vR)(rO&7#BYCXsC=R$RD08b;pqCVeCW#FjNLL?k!T`P
z()4akI{RE%bIh0ac(=Ny(62W!rbmM@E2C?sXB=A*PuF%fXEq(7a9AU_OveoANJT?a
zrq02HH5jT7WHe00z*cmuDNrocz*48cr^?6o5*ADE2^_fU7y96o7iI$?5HkZxIafZn
zY&vLu)mJ9pch}|ns_pm)F-JupP&84hxk`UO*eVD6pD)~nCuC(5^!jtLpVk$Eh8wN@
zMqJH^IpvGBEl_yxTd8`fD2fOYm2)1
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
diff --git a/src/net/apocalypselabs/symat/images/pads.png b/src/net/apocalypselabs/symat/images/pads.png
new file mode 100644
index 0000000000000000000000000000000000000000..d392b3a9bead224d6f0897d6fad6217249822e5d
GIT binary patch
literal 3257
zcmV;q3`X;bP)9tC`$nRaRWb2L+puoc89z4lHKGPGdHHkh>}?AyHAN2*K*2
+ *
+ * Example:
+ *
+ *
+ * EPLiteClient api = new EPLiteClient("http://etherpad.mysite.com", "FJ7jksalksdfj83jsdflkj");
+ */
+public class EPLiteClient {
+ /**
+ * The Etherpad Lite API version this client targets by default
+ */
+ public static final String DEFAULT_API_VERSION = "1.2.11";
+
+ /**
+ * The connection object
+ */
+ public EPLiteConnection connection;
+
+ /**
+ * Initializes a new org.etherpad_lite_client.EPLiteClient object.
+ * The default Etherpad Lite API version (in DEFAULT_API_VERSION) will be used.
+ *
+ * @param url an absolute url, including protocol, to the EPL api
+ * @param apiKey the API Key
+ */
+ public EPLiteClient(String url, String apiKey) {
+ this.connection = new EPLiteConnection(url, apiKey, DEFAULT_API_VERSION);
+ }
+
+ /**
+ * Initializes a new org.etherpad_lite_client.EPLiteClient object.
+ * The specified Etherpad Lite API version will be used.
+ *
+ * @param url an absolute url, including protocol, to the EPL api
+ * @param apiKey the API Key
+ * @param apiVersion the API version
+ */
+ public EPLiteClient(String url, String apiKey, String apiVersion) {
+ this.connection = new EPLiteConnection(url, apiKey, apiVersion);
+ }
+
+ // Groups
+ // Pads may belong to a group. These pads are not considered "public", and won't be available through the Web UI without a session.
+
+ /**
+ * Creates a new Group. The group id is returned in "groupID" in the HashMap.
+ *
+ * @return HashMap
+ */
+ public HashMap createGroup() {
+ return this.connection.post("createGroup");
+ }
+
+ /**
+ * Creates a new Group for groupMapper if one doesn't already exist. Helps you map your application's groups to Etherpad Lite's groups.
+ * The group id is returned in "groupID" in the HashMap.
+ *
+ * @param groupMapper your group mapper string
+ * @return HashMap
+ */
+ public HashMap createGroupIfNotExistsFor(String groupMapper) {
+ HashMap args = new HashMap();
+ args.put("groupMapper", groupMapper);
+ return this.connection.post("createGroupIfNotExistsFor", args);
+ }
+
+ /**
+ * Delete group.
+ *
+ * @param groupID string
+ */
+ public void deleteGroup(String groupID) {
+ HashMap args = new HashMap();
+ args.put("groupID", groupID);
+ this.connection.post("deleteGroup", args);
+ }
+
+ /**
+ * List all the padIDs in a group. They will be in an array inside "padIDs".
+ *
+ * @param groupID string
+ * @return HashMap
+ */
+ public HashMap listPads(String groupID) {
+ HashMap args = new HashMap();
+ args.put("groupID", groupID);
+ return this.connection.get("listPads", args);
+ }
+
+ /**
+ * Create a pad in this group.
+ *
+ * @param groupID string
+ * @param padName string
+ */
+ public HashMap createGroupPad(String groupID, String padName) {
+ HashMap args = new HashMap();
+ args.put("groupID", groupID);
+ args.put("padName", padName);
+ return this.connection.post("createGroupPad", args);
+ }
+
+ /**
+ * Create a pad in this group.
+ *
+ * @param groupID string
+ * @param padName string
+ * @param text string
+ */
+ public void createGroupPad(String groupID, String padName, String text) {
+ HashMap args = new HashMap();
+ args.put("groupID", groupID);
+ args.put("padName", padName);
+ args.put("text", text);
+ this.connection.post("createGroupPad", args);
+ }
+
+ /**
+ * Lists all existing groups. The group ids are returned in "groupIDs".
+ *
+ * @return HashMap
+ */
+ public HashMap listAllGroups() {
+ return this.connection.get("listAllGroups");
+ }
+
+ // Authors
+ // These authors are bound to the attributes the users choose (color and name). The author id is returned in "authorID".
+
+ /**
+ * Create a new author.
+ *
+ * @return HashMap
+ */
+ public HashMap createAuthor() {
+ return this.connection.post("createAuthor");
+ }
+
+ /**
+ * Create a new author with the given name. The author id is returned in "authorID".
+ *
+ * @param name string
+ * @return HashMap
+ */
+ public HashMap createAuthor(String name) {
+ HashMap args = new HashMap();
+ args.put("name", name);
+ return this.connection.post("createAuthor", args);
+ }
+
+ /**
+ * Creates a new Author for authorMapper if one doesn't already exist. Helps you map your application's authors to Etherpad Lite's authors.
+ * The author id is returned in "authorID".
+ *
+ * @param authorMapper string
+ * @return HashMap
+ */
+ public HashMap createAuthorIfNotExistsFor(String authorMapper) {
+ HashMap args = new HashMap();
+ args.put("authorMapper", authorMapper);
+ return this.connection.post("createAuthorIfNotExistsFor", args);
+ }
+
+ /**
+ * Creates a new Author for authorMapper if one doesn't already exist. Helps you map your application's authors to Etherpad Lite's authors.
+ * The author id is returned in "authorID".
+ *
+ * @param authorMapper string
+ * @param name string
+ * @return HashMap
+ */
+ public HashMap createAuthorIfNotExistsFor(String authorMapper, String name) {
+ HashMap args = new HashMap();
+ args.put("authorMapper", authorMapper);
+ args.put("name", name);
+ return this.connection.post("createAuthorIfNotExistsFor", args);
+ }
+
+ /**
+ * List the ids of pads the author has edited. They will be in an array inside "padIDs".
+ *
+ * @param authorId the authors's id string
+ * @return HashMap
+ */
+ public HashMap listPadsOfAuthor(String authorId) {
+ HashMap args = new HashMap();
+ args.put("authorID", authorId);
+ return this.connection.get("listPadsOfAuthor", args);
+ }
+
+ /**
+ * Returns the Author Name of the author.
+ *
+ * @param authorId the author's id string
+ * @return String
+ */
+ public String getAuthorName(String authorId) {
+ HashMap args = new HashMap();
+ args.put("authorID", authorId);
+ return this.connection.get("getAuthorName", args).toString();
+ }
+
+ // Sessions
+ // Sessions can be created between a group and an author. This allows an author to access more than one group. The sessionID will be set as a
+ // cookie to the client and is valid until a certain date. Only users with a valid session for this group, can access group pads. You can create a
+ // session after you authenticated the user at your web application, to give them access to the pads. You should save the sessionID of this session
+ // and delete it after the user logged out.
+
+ /**
+ * Create a new session for the given author in the given group, valid until the given UNIX time.
+ * The session id will be returned in "sessionID".
+ * HashMap pad = api.getText("my_pad");
+ * String pad = pad.get("text").toString();
+ *
+ *
+ * Example:
+ *
+ *
+ * import java.util.Date;
+ *
+ * @param groupID string
+ * @param authorID string
+ * @param validUntil long UNIX timestamp in seconds
+ * @return HashMap
+ */
+ public HashMap createSession(String groupID, String authorID, long validUntil) {
+ HashMap args = new HashMap();
+ args.put("groupID", groupID);
+ args.put("authorID", authorID);
+ args.put("validUntil", String.valueOf(validUntil));
+ return this.connection.post("createSession", args);
+ }
+
+ /**
+ * Create a new session for the given author in the given group valid for the given number of hours.
+ * The session id will be returned in "sessionID".
+ * ...
+ * Date now = new Date();
+ * long in1Hour = (now.getTime() + (60L * 60L * 1000L) / 1000L);
+ * String sessID1 = api.createSession(groupID, authorID, in1Hour).get("sessionID").toString();
+ *
+ *
+ * Example:
+ *
+ *
+ * // in 2 hours
+ *
+ * @param groupID string
+ * @param authorID string
+ * @param validUntil int length of session in hours
+ * @return HashMap
+ */
+ public HashMap createSession(String groupID, String authorID, int length) {
+ long inNHours = ((new Date()).getTime() + ((long)length * 60L * 60L * 1000L)) / 1000L;
+ return this.createSession(groupID, authorID, inNHours);
+ }
+
+ /**
+ * Create a new session for the given author in the given group, valid until the given datetime.
+ * The session id will be returned in "sessionID".
+ * String sessID1 = api.createSession(groupID, authorID, 2).get("sessionID").toString();
+ *
+ *
+ * Example:
+ *
+ *
+ * import java.util.Date;
+ *
+ * @param groupID string
+ * @param authorID string
+ * @param validUntil Date
+ * @return HashMap
+ */
+ public HashMap createSession(String groupID, String authorID, Date validUntil) {
+ long seconds = validUntil.getTime() / 1000L;
+ return this.createSession(groupID, authorID, seconds);
+ }
+
+ /**
+ * Delete a session.
+ *
+ * @param sessionID string
+ */
+ public void deleteSession(String sessionID) {
+ HashMap args = new HashMap();
+ args.put("sessionID", sessionID);
+ this.connection.post("deleteSession", args);
+ }
+
+ /**
+ * Returns information about a session: authorID, groupID and validUntil.
+ *
+ * @param sessionID string
+ * @return HashMap
+ */
+ public HashMap getSessionInfo(String sessionID) {
+ HashMap args = new HashMap();
+ args.put("sessionID", sessionID);
+ return this.connection.get("getSessionInfo", args);
+ }
+
+ /**
+ * List all the sessions IDs in a group. Returned as a HashMap of sessionIDs keys, with values of HashMaps containing
+ * groupID, authorID, and validUntil.
+ *
+ * @param groupID string
+ * @return HashMap
+ */
+ public HashMap listSessionsOfGroup(String groupID) {
+ HashMap args = new HashMap();
+ args.put("groupID", groupID);
+ return this.connection.get("listSessionsOfGroup", args);
+ }
+
+ /**
+ * List all the sessions IDs belonging to an author. Returned as a HashMap of sessionIDs keys, with values of HashMaps containing
+ * groupID, authorID, and validUntil.
+ *
+ * @param authorID string
+ * @return HashMap
+ */
+ public HashMap listSessionsOfAuthor(String authorID) {
+ HashMap args = new HashMap();
+ args.put("authorID", authorID);
+ return this.connection.get("listSessionsOfAuthor", args);
+ }
+
+ // Pad content
+
+ /**
+ * Returns a list of all pads.
+ *
+ * @return HashMap
+ */
+ public HashMap listAllPads() {
+ return this.connection.get("listAllPads");
+ }
+
+ /**
+ * Returns a HashMap containing the latest revision of the pad's text.
+ * The text is stored under "text".
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap getText(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("getText", args);
+ }
+
+ /**
+ * Returns a HashMap containing the a specific revision of the pad's text.
+ * The text is stored under "text".
+ *
+ * @param padId the pad's id string
+ * @param rev the revision number
+ * @return HashMap
+ */
+ public HashMap getText(String padId, int rev) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("rev", new Integer(rev));
+ return this.connection.get("getText", args);
+ }
+
+ /**
+ * Creates a new revision with the given text (or creates a new pad).
+ *
+ * @param padId the pad's id string
+ * @param text the pad's new text
+ */
+ public void setText(String padId, String text) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("text", text);
+ this.connection.post("setText", args);
+ }
+
+ /**
+ * Returns a HashMap containing the current revision of the pad's text as HTML.
+ * The html is stored under "html".
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap getHTML(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("getHTML", args);
+ }
+
+ /**
+ * Returns a HashMap containing the a specific revision of the pad's text as HTML.
+ * The html is stored under "html".
+ *
+ * @param padId the pad's id string
+ * @param rev the revision number
+ * @return HashMap
+ */
+ public HashMap getHTML(String padId, int rev) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("rev", new Integer(rev));
+ return this.connection.get("getHTML", args);
+ }
+
+ /**
+ * Creates a new revision with the given html (or creates a new pad).
+ *
+ * @param padId the pad's id string
+ * @param html the pad's new html text
+ */
+ public void setHTML(String padId, String html) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("html", html);
+ this.connection.post("setHTML", args);
+ }
+
+ // Pads
+ // Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and its
+ // forbidden for normal pads to include a $ in the name.
+
+ /**
+ * Create a new pad.
+ *
+ * @param padId the pad's id string
+ */
+ public void createPad(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ this.connection.post("createPad", args);
+ }
+
+ /**
+ * Create a new pad with the given initial text.
+ *
+ * @param padId the pad's id string
+ * @param text the initial text string
+ */
+ public void createPad(String padId, String text) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("text", text);
+ this.connection.post("createPad", args);
+ }
+
+ /**
+ * Returns the number of revisions of this pad. The number is in "revisions".
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap getRevisionsCount(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("getRevisionsCount", args);
+ }
+
+ /**
+ * List the ids of authors who have edited a pad. They will be in an array inside "authorIDs".
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap listAuthorsOfPad(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("listAuthorsOfPad", args);
+ }
+
+ /**
+ * Deletes a pad.
+ *
+ * @param padId the pad's id string
+ */
+ public void deletePad(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ this.connection.post("deletePad", args);
+ }
+
+ /**
+ * Get the pad's read-only id. The id will be in "readOnlyID".
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap getReadOnlyID(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("getReadOnlyID", args);
+ }
+
+ /**
+ * Get the pad's last edit date as a Unix timestamp. The timestamp will be in "lastEdited".
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap getLastEdited(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("getLastEdited", args);
+ }
+
+ /**
+ * Get the number of users currently editing a pad.
+ *
+ * @param padId the pad's id string
+ * @return Long
+ */
+ public Long padUsersCount(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ Long userCount = (Long) this.connection.get("padUsersCount", args).get("padUsersCount");
+ return userCount;
+ }
+
+ /**
+ * Returns the list of users that are currently editing this pad.
+ * A padUser has the values: "colorId", "name" and "timestamp".
+ *
+ * @param padId
+ * @return HashMap
+ */
+ public HashMap padUsers(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("padUsers", args);
+ }
+
+ /**
+ * Sets the pad's public status.
+ * This is only applicable to group pads.
+ *
+ * @param padId the pad's id string
+ * @param publicStatus boolean
+ */
+ public void setPublicStatus(String padId, Boolean publicStatus) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("publicStatus", publicStatus);
+ this.connection.post("setPublicStatus", args);
+ }
+
+ /**
+ * Gets the pad's public status. The boolean is in "publicStatus".
+ * This is only applicable to group pads.
+ * import java.text.DateFormat;
+ * import java.text.SimpleDateFormat;
+ * import java.util.TimeZone;
+ * ...
+ * DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ * dfm.setTimeZone(TimeZone.getTimeZone("GMT-5"));
+ * Date longTime = dfm.parse("2056-01-15 20:15:00");
+ * String sessID = api.createSession(groupID, authorID, longTime).get("sessionID").toString();
+ *
+ *
+ * Example:
+ *
+ *
+ * Boolean is_public = (Boolean)api.getPublicStatus("g.kjsdfj7ask$foo").get("publicStatus");
+ *
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap getPublicStatus(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("getPublicStatus", args);
+ }
+
+ /**
+ * Sets the pad's password. This is only applicable to group pads.
+ *
+ * @param padId the pad's id string
+ * @param password string
+ */
+ public void setPassword(String padId, String password) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("password", password);
+ this.connection.post("setPassword", args);
+ }
+
+ /**
+ * Checks whether the pad is password-protected or not. The boolean is in "isPasswordProtected".
+ * This is only applicable to group pads.
+ *
+ * Example:
+ *
+ *
+ * Boolean pass = (Boolean)api.isPasswordProtected("g.kjsdfj7ask$foo").get("isPasswordProtected");
+ *
+ *
+ * @param padId the pad's id string
+ * @return HashMap
+ */
+ public HashMap isPasswordProtected(String padId) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ return this.connection.get("isPasswordProtected", args);
+ }
+
+ /**
+ * Sends a custom message of type msg to the pad.
+ *
+ * @param padId
+ * @param msg
+ */
+ public void sendClientsMessage(String padId, String msg) {
+ HashMap args = new HashMap();
+ args.put("padID", padId);
+ args.put("msg", msg);
+ this.connection.post("sendClientsMessage", args);
+ }
+
+ /**
+ * Returns true if the connection is using SSL/TLS, false if not.
+ *
+ * @return boolean
+ */
+ public boolean isSecure() {
+ if (this.connection.uri.getPort() == 443) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/org/etherpad_lite_client/EPLiteConnection.java b/src/org/etherpad_lite_client/EPLiteConnection.java
new file mode 100644
index 0000000..857202c
--- /dev/null
+++ b/src/org/etherpad_lite_client/EPLiteConnection.java
@@ -0,0 +1,258 @@
+package org.etherpad_lite_client;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import net.apocalypselabs.symat.Debug;
+
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+/**
+ * Connection object for talking to and parsing responses from the Etherpad Lite Server.
+ */
+public class EPLiteConnection {
+ public static final int CODE_OK = 0;
+ public static final int CODE_INVALID_PARAMETERS = 1;
+ public static final int CODE_INTERNAL_ERROR = 2;
+ public static final int CODE_INVALID_METHOD = 3;
+ public static final int CODE_INVALID_API_KEY = 4;
+
+ /**
+ * The url of the API
+ */
+ public URI uri;
+
+ /**
+ * The API key
+ */
+ public String apiKey;
+
+ /**
+ * The Etherpad Lite API version
+ */
+ public String apiVersion;
+
+ /**
+ * Initializes a new org.etherpad_lite_client.EPLiteConnection object.
+ *
+ * @param url an absolute url, including protocol, to the EPL api
+ * @param apiKey the API Key
+ * @param apiVersion the API version
+ */
+ public EPLiteConnection(String url, String apiKey, String apiVersion) {
+ this.uri = URI.create(url);
+ this.apiKey = apiKey;
+ this.apiVersion = apiVersion;
+ }
+
+ /**
+ * GETs from the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @return HashMap
+ */
+ public HashMap get(String apiMethod) {
+ return this.get(apiMethod, new HashMap());
+ }
+
+ /**
+ * GETs from the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @param apiArgs a HashMap of url/form parameters. apikey will be set automatically
+ * @return HashMap
+ */
+ public HashMap get(String apiMethod, HashMap apiArgs) {
+ String path = this.apiPath(apiMethod);
+ String query = this.queryString(apiArgs);
+ URL url = apiUrl(path, query);
+ Request request = new GETRequest(url);
+ return this.call(request);
+ }
+
+ /**
+ * POSTs to the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @return HashMap
+ */
+ public HashMap post(String apiMethod) {
+ return this.post(apiMethod, new HashMap());
+ }
+
+ /**
+ * POSTs to the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @param apiArgs a HashMap of url/form parameters. apikey will be set automatically
+ * @return HashMap
+ */
+ public HashMap post(String apiMethod, HashMap apiArgs) {
+ String path = this.apiPath(apiMethod);
+ String query = this.queryString(apiArgs);
+ URL url = apiUrl(path, null);
+ Request request = new POSTRequest(url, query);
+ return this.call(request);
+ }
+
+ /**
+ * Calls the HTTP JSON API.
+ *
+ * @param request the request object to send
+ * @return HashMap
+ */
+ private HashMap call(Request request) {
+ trustServerAndCertificate();
+
+ try {
+ String response = request.send();
+ return this.handleResponse(response);
+ }
+ catch (EPLiteException e) {
+ throw new EPLiteException(e.getMessage());
+ }
+ catch (Exception e) {
+ throw new EPLiteException("Unable to connect to SyMAT: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Converts the API resonse's JSON string into a HashMap.
+ *
+ * @param jsonString a valid JSON string
+ * @return HashMap
+ */
+ private HashMap handleResponse(String jsonString) {
+ try {
+ JSONParser parser = new JSONParser();
+ Map response = (Map) parser.parse(jsonString);
+ // Act on the response code
+ if (!response.get("code").equals(null)) {
+ int code = ((Long) response.get("code")).intValue();
+ switch ( code ) {
+ // Valid code, parse the response
+ case CODE_OK:
+ HashMap data = (HashMap) response.get("data");
+ return data != null ? data: new HashMap();
+ // Invalid code, throw an exception with the message
+ case CODE_INVALID_PARAMETERS:
+ case CODE_INVALID_API_KEY:
+ case CODE_INVALID_METHOD:
+ throw new EPLiteException((String)response.get("message"));
+ default:
+ throw new EPLiteException("An unknown error has occurred while handling the response: " + jsonString);
+ }
+ // No response code, something's really wrong
+ } else {
+ throw new EPLiteException("An unknown error has occurred while handling the response: " + jsonString);
+ }
+ } catch (ParseException e) {
+ System.err.println("Unable to parse JSON response (" + jsonString + "): " + e.getMessage());
+ return new HashMap();
+ }
+ }
+
+ /**
+ * Returns the URL for the api path and query.
+ *
+ * @param path the api path
+ * @param query the query string (may be null)
+ * @return URL
+ */
+ private URL apiUrl(String path, String query) {
+ try {
+ URL url = new URL(new URI(this.uri.getScheme(), null, this.uri.getHost(), this.uri.getPort(), path, query, null).toString());
+ return url;
+ } catch (Exception e) {
+ throw new EPLiteException("Unable to connect to SyMAT: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Returns a URI path for the API method
+ *
+ * @param apiMethod the api method
+ * @return String
+ */
+ private String apiPath(String apiMethod) {
+ return this.uri.getPath() + "/api/" + this.apiVersion + "/" + apiMethod;
+ }
+
+ /**
+ * Returns a query string made from HashMap keys and values
+ *
+ * @param apiArgs the api arguments in a HashMap
+ * @return String
+ */
+ private String queryString(HashMap apiArgs) {
+ String strArgs = "";
+ apiArgs.put("apikey", this.apiKey);
+ Iterator i = apiArgs.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry e = (Map.Entry)i.next();
+ Object value = e.getValue();
+ if (value != null) {
+ try {
+ strArgs += e.getKey() + "=" + URLEncoder.encode(value.toString(), "utf-8");
+ } catch (UnsupportedEncodingException ex) {
+ Debug.stacktrace(ex);
+ }
+ if (i.hasNext()) {
+ strArgs += "&";
+ }
+ }
+ }
+ return strArgs;
+ }
+
+ /**
+ * Creates a trust manager to trust all certificates if you open a ssl connection
+ */
+ private void trustServerAndCertificate() {
+ // Create a trust manager that does not validate certificate chains
+ TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ }
+ };
+
+ // Install the all-trusting trust manager
+ try {
+ SSLContext sc = SSLContext.getInstance("SSL");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+ } catch (Exception e) {
+ }
+
+ HostnameVerifier hv = new HostnameVerifier() {
+ //@Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ };
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+ }
+}
diff --git a/src/org/etherpad_lite_client/EPLiteException.java b/src/org/etherpad_lite_client/EPLiteException.java
new file mode 100644
index 0000000..773af32
--- /dev/null
+++ b/src/org/etherpad_lite_client/EPLiteException.java
@@ -0,0 +1,7 @@
+package org.etherpad_lite_client;
+
+public class EPLiteException extends RuntimeException {
+ public EPLiteException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/org/etherpad_lite_client/GETRequest.java b/src/org/etherpad_lite_client/GETRequest.java
new file mode 100644
index 0000000..c9186d3
--- /dev/null
+++ b/src/org/etherpad_lite_client/GETRequest.java
@@ -0,0 +1,47 @@
+package org.etherpad_lite_client;
+
+import java.net.URL;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * A class for easily executing an HTTP GET request.
+ *
+ * Example:
+ *
+ *
+ * Request req = new GETRequest(url_object);
+ */
+public class GETRequest implements Request {
+ /**
+ * The URL object.
+ */
+ private URL url;
+
+ /**
+ * Instantiates a new GETRequest.
+ *
+ * @param url the URL object
+ */
+ public GETRequest(URL url) {
+ this.url = url;
+ }
+
+ /**
+ * Sends the request and returns the response.
+ *
+ * @return String
+ */
+ public String send() throws Exception {
+ BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
+ String response = "";
+ String buffer;
+ while ((buffer = in.readLine()) != null) {
+ response += buffer;
+ }
+ in.close();
+ return response;
+ }
+}
diff --git a/src/org/etherpad_lite_client/POSTRequest.java b/src/org/etherpad_lite_client/POSTRequest.java
new file mode 100644
index 0000000..bf8d619
--- /dev/null
+++ b/src/org/etherpad_lite_client/POSTRequest.java
@@ -0,0 +1,59 @@
+package org.etherpad_lite_client;
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+
+/**
+ * A class for easily executing an HTTP POST request.
+ * String resp = req.send();
+ *
+ *
+ * Example:
+ *
+ *
+ * Request req = new POSTRequest(url_object);
+ */
+public class POSTRequest implements Request {
+ /**
+ * The URL object.
+ */
+ private URL url;
+
+ /**
+ * Instantiates a new POSTRequest.
+ *
+ * @param url the URL object
+ */
+ private String args;
+
+ public POSTRequest(URL url, String args) {
+ this.url = url;
+ this.args = args;
+ }
+
+ /**
+ * Sends the request and returns the response.
+ *
+ * @return String
+ */
+ public String send() throws Exception {
+ URLConnection con = this.url.openConnection();
+ con.setDoOutput(true);
+
+ OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
+ out.write(this.args);
+ out.close();
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ String response = "";
+ String buffer;
+ while ((buffer = in.readLine()) != null) {
+ response += buffer;
+ }
+ in.close();
+ return response;
+ }
+}
diff --git a/src/org/etherpad_lite_client/Request.java b/src/org/etherpad_lite_client/Request.java
new file mode 100644
index 0000000..add1941
--- /dev/null
+++ b/src/org/etherpad_lite_client/Request.java
@@ -0,0 +1,9 @@
+package org.etherpad_lite_client;
+
+import java.net.URL;
+
+public interface Request {
+ URL url = null;
+
+ public abstract String send() throws Exception;
+}
+ * String resp = req.send();
+ *