Index: 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteClient.java
===================================================================
diff -u
--- 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteClient.java (revision 0)
+++ 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteClient.java (revision d1558f68d1dbddfdfdc8d301d831d025c8a916d7)
@@ -0,0 +1,915 @@
+package net.gjerull.etherpad.client;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A client for talking to Etherpad Lite's HTTP JSON API.
+ *
+ * Example:
+ *
+ *
+ * EPLiteClient api = new EPLiteClient("http://etherpad.mysite.com", "FJ7jksalksdfj83jsdflkj");
+ * Map pad = api.getText("my_pad");
+ * String pad = pad.get("text").toString();
+ *
+ */
+public class EPLiteClient {
+ private static final String DEFAULT_API_VERSION = "1.2.13";
+ private static final String DEFAULT_ENCODING = "UTF-8";
+ private final EPLiteConnection connection;
+
+ /**
+ * Initializes a new net.gjerull.etherpad.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, DEFAULT_ENCODING);
+ }
+
+ /**
+ * Initializes a new net.gjerull.etherpad.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, String encoding) {
+ this.connection = new EPLiteConnection(url, apiKey, apiVersion, encoding);
+ }
+
+ // 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 Map.
+ *
+ * @return Map with groupID
+ */
+ public Map 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 Map.
+ *
+ * @param groupMapper your group mapper string
+ * @return Map with groupID
+ */
+ public Map createGroupIfNotExistsFor(String groupMapper) {
+ Map args = new HashMap<>();
+ args.put("groupMapper", groupMapper);
+ return this.connection.post("createGroupIfNotExistsFor", args);
+ }
+
+ /**
+ * Delete group.
+ *
+ * @param groupID string
+ */
+ public void deleteGroup(String groupID) {
+ Map 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 Map
+ */
+ public Map listPads(String groupID) {
+ Map args = new HashMap<>();
+ args.put("groupID", groupID);
+ return this.connection.get("listPads", args);
+ }
+
+ /**
+ * Create a pad in this group.
+ *
+ * @param groupID the group the pad belongs to
+ * @param padName name of the pad
+ */
+ public Map createGroupPad(String groupID, String padName) {
+ Map args = new HashMap<>();
+ args.put("groupID", groupID);
+ args.put("padName", padName);
+ return this.connection.post("createGroupPad", args);
+ }
+
+ /**
+ * Create a pad in this group, with initial text.
+ *
+ * @param groupID the group the pad belongs to
+ * @param padName name of the pad
+ * @param text Initial text in the pad
+ */
+ public Map createGroupPad(String groupID, String padName, String text) {
+ Map args = new HashMap<>();
+ args.put("groupID", groupID);
+ args.put("padName", padName);
+ args.put("text", text);
+ return this.connection.post("createGroupPad", args);
+ }
+
+ /**
+ * Lists all existing groups. The group ids are returned in "groupIDs".
+ *
+ * @return Map with list of groupIDs
+ */
+ public Map 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 Map with authorID
+ */
+ public Map createAuthor() {
+ return this.connection.get("createAuthor");
+ }
+
+ /**
+ * Create a new author with the given name. The author id is returned in "authorID".
+ *
+ * @param name string
+ * @return Map with authorID
+ */
+ public Map createAuthor(String name) {
+ Map 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 Map with authorID
+ */
+ public Map createAuthorIfNotExistsFor(String authorMapper) {
+ Map 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 Map with authorID
+ */
+ public Map createAuthorIfNotExistsFor(String authorMapper, String name) {
+ Map 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 Map
+ */
+ public Map listPadsOfAuthor(String authorId) {
+ Map 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 authorName
+ */
+ public String getAuthorName(String authorId) {
+ Map args = new HashMap<>();
+ args.put("authorID", authorId);
+ return (String) this.connection.getObject("getAuthorName", args);
+ }
+
+ // 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.
+ *
+ * Example:
+ *
+ *
+ * import java.util.Date;
+ * ...
+ * Date now = new Date();
+ * long in1Hour = (now.getTime() + (60L * 60L * 1000L) / 1000L);
+ * String sessID1 = api.createSession(groupID, authorID, in1Hour);
+ *
+ *
+ * @param groupID string
+ * @param authorID string
+ * @param validUntil long UNIX timestamp in seconds
+ * @return Map with sessionID
+ */
+ public Map createSession(String groupID, String authorID, long validUntil) {
+ Map 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.
+ *
+ * Example:
+ *
+ *
+ * // in 2 hours
+ * String sessID1 = api.createSession(groupID, authorID, 2);
+ *
+ *
+ * @param groupID string
+ * @param authorID string
+ * @param sessionDuration int duration of session in hours
+ * @return Map with sessionID
+ */
+ public Map createSession(String groupID, String authorID, int sessionDuration) {
+ long inNHours = ((new Date()).getTime() + ((long)sessionDuration * 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.
+ *
+ * Example:
+ *
+ *
+ * import java.util.Date;
+ * 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);
+ *
+ *
+ * @param groupID string
+ * @param authorID string
+ * @param validUntil Date
+ * @return Map with sessionID
+ */
+ public Map 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) {
+ Map 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 Map
+ */
+ public Map getSessionInfo(String sessionID) {
+ Map args = new HashMap<>();
+ args.put("sessionID", sessionID);
+ return this.connection.get("getSessionInfo", args);
+ }
+
+ /**
+ * List all the sessions IDs in a group. Returned as a Map of sessionIDs keys, with values of Maps containing
+ * groupID, authorID, and validUntil.
+ *
+ * @param groupID string
+ * @return Map
+ */
+ public Map listSessionsOfGroup(String groupID) {
+ Map 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 Map of sessionIDs keys, with values of Maps containing
+ * groupID, authorID, and validUntil.
+ *
+ * @param authorID string
+ * @return Map
+ */
+ public Map listSessionsOfAuthor(String authorID) {
+ Map args = new HashMap<>();
+ args.put("authorID", authorID);
+ return this.connection.get("listSessionsOfAuthor", args);
+ }
+
+ // Pad content
+
+ /**
+ * Returns a Map containing the latest revision of the pad's text.
+ * The text is stored under "text".
+ *
+ * @param padId the pad's id string
+ * @return a Map with the text content of pad
+ */
+ public Map getText(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getText", args);
+ }
+
+ /**
+ * Returns a Map 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 a Map with the text content of pad in given revision
+ */
+ public Map getText(String padId, long rev) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("rev", rev);
+ return this.connection.get("getText", args);
+ }
+
+ /**
+ * Creates a new revision with the given text.
+ *
+ * @param padId the pad's id string
+ * @param text the pad's new text
+ */
+ public void setText(String padId, String text) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("text", text);
+ this.connection.post("setText", args);
+ }
+
+ /**
+ * Creates a new revision with the given text appended to the existing text.
+ *
+ * API >= 1.2.13
+ *
+ * @param padId the pad's id string
+ * @param text the pad's new text
+ */
+ public void appendText(String padId, String text) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("text", text);
+ this.connection.post("appendText", args);
+ }
+
+ /**
+ * Returns a Map 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 a Map with the HTML content of pad
+ */
+ public Map getHTML(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getHTML", args);
+ }
+
+ /**
+ * Returns a Map 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 a Map with the HTML content of pad in given revision
+ */
+ public Map getHTML(String padId, long rev) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("rev", rev);
+ return this.connection.get("getHTML", args);
+ }
+
+ /**
+ * Creates a new revision with the given html.
+ *
+ * @param padId the pad's id string
+ * @param html the pad's new html text
+ */
+ public void setHTML(String padId, String html) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("html", html);
+ this.connection.post("setHTML", args);
+ }
+
+ /**
+ * Returns the attribute pool of a pad
+ *
+ * API >= 1.2.8
+ *
+ * @param padId the pad's id string
+ * @return a Map with the attribute pool of a pad
+ */
+ public Map getAttributePool(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getAttributePool", args);
+ }
+
+ /**
+ * Get the changeset at the last revision.
+ *
+ * API >= 1.2.8
+ *
+ * @param padId the pad's id string
+ * @return the changeset at the last revision.
+ */
+ public String getRevisionChangeset(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return (String) this.connection.getObject("getRevisionChangeset", args);
+ }
+
+ /**
+ * Get the changeset at a given revision.
+ *
+ * API >= 1.2.8
+ *
+ * @param padId the pad's id string
+ * @param rev the revision number
+ * @return the changeset at a given revision.
+ */
+ public String getRevisionChangeset(String padId, long rev) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("rev", rev);
+ return (String) this.connection.getObject("getRevisionChangeset", args);
+ }
+
+ /**
+ * Returns an object of diffs from 2 points in a pad
+ *
+ * API >= 1.2.7
+ *
+ * @param padId the pad's id string
+ * @param startRev the start revision number
+ * @param endRev the end revision number
+ * @return a Map of diffs from 2 points in a pad
+ */
+ public Map createDiffHTML(String padId, long startRev, long endRev) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("startRev", startRev);
+ args.put("endRev", endRev);
+ return this.connection.get("createDiffHTML", args);
+ }
+
+ // Chat
+
+ /**
+ * Returns the complete chat history of pad
+ *
+ * API >= 1.2.7
+ *
+ * @param padId the pad's id string
+ * @return the whole chat histroy
+ */
+ public Map getChatHistory(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getChatHistory", args);
+ }
+
+ /**
+ * Returns the chat history of pad with index between start and end
+ *
+ * API >= 1.2.7
+ *
+ * @param padId the pad's id string
+ * @param start the start index
+ * @param end the end index
+ * @return a part of the chat history, between start and end
+ */
+ public Map getChatHistory(String padId, long start, long end) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("start", start);
+ args.put("end", end);
+ return this.connection.get("getChatHistory", args);
+ }
+
+ /**
+ * Returns the chatHead (last number of the last chat-message) of the pad
+ *
+ * API >= 1.2.7
+ *
+ * @param padId the pad's id string
+ * @return the last number of the last chat-message
+ */
+ public Map getChatHead(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getChatHead", args);
+ }
+
+ /**
+ * Creates a chat message, saves it to the database and sends it to all
+ * connected clients of this pad, using the current time as timestamp.
+ *
+ * API >= 1.2.12
+ *
+ * @param padId the pad's id string
+ * @param text the text of this chat entry
+ * @param authorId the author of this chat entry
+ */
+ public Map appendChatMessage(String padId, String text, String authorId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("text", text);
+ args.put("authorID", authorId);
+ return this.connection.post("appendChatMessage", args);
+ }
+
+ /**
+ * Creates a chat message, saves it to the database and sends it to all
+ * connected clients of this pad.
+ *
+ * API >= 1.2.12
+ *
+ * @param padId the pad's id string
+ * @param text the text of this chat entry
+ * @param authorId the author of this chat entry
+ * @param time the timestamp of this chat entry
+ */
+ public Map appendChatMessage(String padId, String text, String authorId, long time) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("text", text);
+ args.put("authorID", authorId);
+ args.put("time", time);
+ return this.connection.post("appendChatMessage", 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.
+
+ /**
+ * Returns a list of all pads.
+ *
+ * @return a Map with list of pad id's
+ */
+ public Map listAllPads() {
+ return this.connection.get("listAllPads");
+ }
+
+ /**
+ * Create a new pad.
+ *
+ * @param padId the pad's id string
+ */
+ public void createPad(String padId) {
+ Map 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) {
+ Map 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 a Map with the number of revisions
+ */
+ public Map getRevisionsCount(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getRevisionsCount", args);
+ }
+
+ /**
+ * Returns the number of saved revisions of this pad
+ *
+ * API >= 1.2.11
+ *
+ * @param padId the pad's id string
+ * @return a Map with number of saved revisions
+ */
+ public Map getSavedRevisionsCount(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getSavedRevisionsCount", args);
+ }
+
+ /**
+ * returns the list of saved revisions of this pad
+ *
+ * API >= 1.2.11
+ *
+ * @param padId the pad's id string
+ * @return a Map with the list of saved revision numbers
+ */
+ public Map listSavedRevisions(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("listSavedRevisions", args);
+ }
+
+ /**
+ * Saves the latest revision
+ *
+ * API >= 1.2.11
+ *
+ * @param padId the pad's id string
+ */
+ public void saveRevision(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ this.connection.post("saveRevision", args);
+ }
+
+ /**
+ * Saves the given revision
+ *
+ * API >= 1.2.11
+ *
+ * @param padId the pad's id string
+ * @param rev the revision to be saved
+ */
+ public void saveRevision(String padId, long rev) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("rev", rev);
+ this.connection.post("saveRevision", args);
+ }
+
+ /**
+ * Get the number of users currently editing a pad.
+ *
+ * @param padId the pad's id string
+ * @return a Map with the padUsersCount
+ */
+ public Map padUsersCount(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("padUsersCount", args);
+ }
+
+ /**
+ * Returns the list of users that are currently editing this pad.
+ * A padUser has the values: "colorId", "name" and "timestamp".
+ *
+ * @param padId the pad's id string
+ * @return a Map with a List of pad user maps
+ */
+ public Map padUsers(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("padUsers", args);
+ }
+
+ /**
+ * Deletes a pad.
+ *
+ * @param padId the pad's id string
+ */
+ public void deletePad(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ this.connection.post("deletePad", args);
+ }
+
+ /**
+ * Copies a pad with full history and chat. If the destination exists the copy will fail.
+ *
+ * API >= 1.2.8
+ *
+ * @param sourcePadId the id of the source pad
+ * @param destinationPadId the id of the destination pad
+ */
+ public void copyPad(String sourcePadId, String destinationPadId) {
+ copyPad(sourcePadId, destinationPadId, false);
+ }
+
+ /**
+ * Copies a pad with full history and chat.
+ *
+ * API >= 1.2.8
+ *
+ * @param sourcePadId the id of the source pad
+ * @param destinationPadId the id of the destination pad
+ * @param force if force is true and the destination pad exists, it will be overwritten.
+ */
+ public void copyPad(String sourcePadId, String destinationPadId, boolean force) {
+ Map args = new HashMap<>();
+ args.put("sourceID", sourcePadId);
+ args.put("destinationID", destinationPadId);
+ args.put("force", force);
+ this.connection.post("copyPad", args);
+ }
+
+ /**
+ * Moves a pad. If the destination exists the copy will fail.
+ *
+ * API >= 1.2.8
+ *
+ * @param sourcePadId the id of the source pad
+ * @param destinationPadId the id of the destination pad
+ */
+ public void movePad(String sourcePadId, String destinationPadId) {
+ copyPad(sourcePadId, destinationPadId, false);
+ }
+
+ /**
+ * Moves a pad.
+ *
+ * API >= 1.2.8
+ *
+ * @param sourcePadId the id of the source pad
+ * @param destinationPadId the id of the destination pad
+ * @param force if force is true and the destination pad exists, it will be overwritten.
+ */
+ public void movePad(String sourcePadId, String destinationPadId, boolean force) {
+ Map args = new HashMap<>();
+ args.put("sourceID", sourcePadId);
+ args.put("destinationID", destinationPadId);
+ args.put("force", force);
+ this.connection.post("movePad", args);
+ }
+
+ /**
+ * Get the pad's read-only id.
+ *
+ * @param padId the pad's id string
+ * @return a Map with the readOnlyID
+ */
+ public Map getReadOnlyID(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getReadOnlyID", args);
+ }
+
+ /**
+ * Get the pad's id from the read only id
+ *
+ * API >= 1.2.10
+ *
+ * @param readOnlyPadId the pad's read only id string
+ * @return a Map with the padID
+ */
+ public Map getPadID(String readOnlyPadId) {
+ Map args = new HashMap<>();
+ args.put("roID", readOnlyPadId);
+ return this.connection.get("getPadID", 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) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("publicStatus", publicStatus);
+ this.connection.post("setPublicStatus", args);
+ }
+
+ /**
+ * Gets the pad's public status.
+ *
+ * @param padId the pad's id string
+ * @return a Map with the Boolean publicStatus
+ */
+ public Map getPublicStatus(String padId) {
+ Map 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) {
+ Map 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.
+ *
+ * @param padId the pad's id string
+ * @return a Map with the Boolean passwordProtection
+ */
+ public Map isPasswordProtected(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("isPasswordProtected", args);
+ }
+
+ /**
+ * List the ids of authors who have edited a pad.
+ *
+ * @param padId the pad's id string
+ * @return a Map with a List of author ids
+ */
+ public Map listAuthorsOfPad(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("listAuthorsOfPad", args);
+ }
+
+ /**
+ * Get the pad's last edit date.
+ *
+ * @param padId the pad's id string
+ * @return a Map with lastEdited timestamp.
+ */
+ public Map getLastEdited(String padId) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ return this.connection.get("getLastEdited", args);
+ }
+
+ /**
+ * Sends a custom message of type msg to the pad.
+ *
+ * @param padId the pad's id string
+ * @param msg the message to send
+ */
+ public void sendClientsMessage(String padId, String msg) {
+ Map args = new HashMap<>();
+ args.put("padID", padId);
+ args.put("msg", msg);
+ this.connection.post("sendClientsMessage", args);
+ }
+
+ /**
+ * Runs without error if current api token is valid
+ *
+ * API >= 1.2
+ */
+ public void checkToken() {
+ this.connection.get("checkToken");
+ }
+
+ /**
+ * Returns true if the connection is using SSL/TLS, false if not.
+ *
+ * @return boolean
+ */
+ public boolean isSecure() {
+ return (this.connection.uri.getPort() == 443);
+ }
+}
Index: 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteConnection.java
===================================================================
diff -u
--- 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteConnection.java (revision 0)
+++ 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteConnection.java (revision d1558f68d1dbddfdfdc8d301d831d025c8a916d7)
@@ -0,0 +1,317 @@
+package net.gjerull.etherpad.client;
+
+import java.io.UnsupportedEncodingException;
+import java.net.*;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+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 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 final URI uri;
+
+ /**
+ * The API key
+ */
+ public final String apiKey;
+
+ /**
+ * The Etherpad Lite API version
+ */
+ public final String apiVersion;
+
+ /**
+ * The character encoding of your application
+ */
+ public final String encoding;
+
+ /**
+ * Initializes a new net.gjerull.etherpad.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, String encoding) {
+ if (url.endsWith("/")) {
+ url = url.substring(0, url.length()-1);
+ }
+ this.uri = URI.create(url);
+ this.apiKey = apiKey;
+ this.apiVersion = apiVersion;
+ this.encoding = encoding;
+ }
+
+ /**
+ * GETs from the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @return Object
+ */
+ public Object getObject(String apiMethod) {
+ return this.getObject(apiMethod, new HashMap());
+ }
+
+ /**
+ * GETs from the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @return Map
+ */
+ public Map get(String apiMethod) {
+ Map response = (Map) this.getObject(apiMethod);
+ return (response != null) ? response : 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 Object
+ */
+ public Object getObject(String apiMethod, Map apiArgs) {
+ String path = this.apiPath(apiMethod);
+ String query = this.queryString(apiArgs, false);
+ URL url = apiUrl(path, query);
+ Request request = new GETRequest(url);
+ return this.call(request);
+ }
+
+ /**
+ * 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 Map
+ */
+ public Map get(String apiMethod, Map apiArgs) {
+ Map response = (Map) this.getObject(apiMethod, apiArgs);
+ return (response != null) ? response : new HashMap();
+ }
+
+ /**
+ * POSTs to the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @return Object
+ */
+ public Object postObject(String apiMethod) {
+ return this.postObject(apiMethod, new HashMap());
+ }
+
+ /**
+ * POSTs to the HTTP JSON API.
+ *
+ * @param apiMethod the name of the API method to call
+ * @return Map
+ */
+ public Map post(String apiMethod) {
+ Map response = (Map) this.postObject(apiMethod);
+ return (response != null) ? response : 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 Object
+ */
+ public Object postObject(String apiMethod, Map apiArgs) {
+ String path = this.apiPath(apiMethod);
+ String query = this.queryString(apiArgs, true);
+ URL url = apiUrl(path, null);
+ Request request = new POSTRequest(url, query);
+ return this.call(request);
+ }
+
+ /**
+ * 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 Map
+ */
+ public Map post(String apiMethod, Map apiArgs) {
+ Map response = (Map) this.postObject(apiMethod, apiArgs);
+ return (response != null) ? response : new HashMap();
+ }
+
+ /**
+ * Handle error condition and returns the parsed content
+ *
+ * @param jsonString a valid JSON string
+ * @return Object
+ */
+ protected Object handleResponse(String jsonString) {
+ try {
+ JSONParser parser = new JSONParser();
+ Map response = (Map) parser.parse(jsonString);
+ // Act on the response code
+ if (response.get("code") != null) {
+ int code = ((Long) response.get("code")).intValue();
+ switch ( code ) {
+ // Valid code, parse the response
+ case CODE_OK:
+ return response.get("data");
+ // Invalid code, throw an exception with the message
+ case CODE_INVALID_PARAMETERS:
+ case CODE_INTERNAL_ERROR:
+ case CODE_INVALID_METHOD:
+ case CODE_INVALID_API_KEY:
+ 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 unexpected response from the server: " + jsonString);
+ }
+ } catch (ParseException e) {
+ throw new EPLiteException("Unable to parse JSON response (" + jsonString + ")", e);
+ }
+ }
+
+ /**
+ * Returns the URL for the api path and query.
+ *
+ * @param path the api path
+ * @param query the query string (may be null)
+ * @return URL
+ */
+ protected URL apiUrl(String path, String query) {
+ try {
+ return new URL(new URI(this.uri.getScheme(), null, this.uri.getHost(), this.uri.getPort(), path, query, null).toString());
+ } catch (MalformedURLException | URISyntaxException e) {
+ throw new EPLiteException("Error in the URL to the Etherpad Lite instance (" + e.getClass() + "): " + e.getMessage());
+ }
+ }
+
+ /**
+ * Returns a URI path for the API method
+ *
+ * @param apiMethod the api method
+ * @return String
+ */
+ protected 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
+ */
+ protected String queryString(Map apiArgs, boolean urlEncode) {
+ StringBuilder strArgs = new StringBuilder();
+ apiArgs.put("apikey", this.apiKey);
+ Iterator i = apiArgs.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry entry = (Map.Entry)i.next();
+ Object key = entry.getKey();
+ Object value = entry.getValue();
+ if (urlEncode) {
+ try {
+ if (key instanceof String) {
+ URLEncoder.encode((String) key, this.encoding);
+ }
+ if (value instanceof String) {
+ value = URLEncoder.encode((String) value, this.encoding);
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new EPLiteException(String.format(
+ "Unable to URLEncode using encoding '%s'", this.encoding), e);
+ }
+ }
+ strArgs.append(key).append("=").append(value);
+ if (i.hasNext()) {
+ strArgs.append("&");
+ }
+ }
+ return strArgs.toString();
+ }
+
+ /**
+ * Calls the HTTP JSON API.
+ *
+ * @param request the request object to send
+ * @return HashMap
+ */
+ private Object call(Request request) {
+ trustServerAndCertificate();
+
+ try {
+ String response = request.send();
+ return this.handleResponse(response);
+ }
+ catch (EPLiteException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new EPLiteException("Unable to connect to Etherpad Lite instance (" + e.getClass() + "): " + e.getMessage());
+ }
+ }
+
+ /**
+ * 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 (NoSuchAlgorithmException | KeyManagementException e) {
+ throw new EPLiteException("Unable to create SSL context", e);
+ }
+
+ HostnameVerifier hv = new HostnameVerifier() {
+ //@Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ };
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+ }
+}
Index: 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteException.java
===================================================================
diff -u
--- 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteException.java (revision 0)
+++ 3rdParty_sources/etherpad/net/gjerull/etherpad/client/EPLiteException.java (revision d1558f68d1dbddfdfdc8d301d831d025c8a916d7)
@@ -0,0 +1,11 @@
+package net.gjerull.etherpad.client;
+
+public class EPLiteException extends RuntimeException {
+ public EPLiteException(String message) {
+ super(message);
+ }
+
+ public EPLiteException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
Index: 3rdParty_sources/etherpad/net/gjerull/etherpad/client/GETRequest.java
===================================================================
diff -u
--- 3rdParty_sources/etherpad/net/gjerull/etherpad/client/GETRequest.java (revision 0)
+++ 3rdParty_sources/etherpad/net/gjerull/etherpad/client/GETRequest.java (revision d1558f68d1dbddfdfdc8d301d831d025c8a916d7)
@@ -0,0 +1,44 @@
+package net.gjerull.etherpad.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);
+ * String resp = req.send();
+ *
+ */
+public class GETRequest implements Request {
+ private final 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()));
+ StringBuilder response = new StringBuilder();
+ String buffer;
+ while ((buffer = in.readLine()) != null) {
+ response.append(buffer);
+ }
+ in.close();
+ return response.toString();
+ }
+}
Index: 3rdParty_sources/etherpad/net/gjerull/etherpad/client/POSTRequest.java
===================================================================
diff -u
--- 3rdParty_sources/etherpad/net/gjerull/etherpad/client/POSTRequest.java (revision 0)
+++ 3rdParty_sources/etherpad/net/gjerull/etherpad/client/POSTRequest.java (revision d1558f68d1dbddfdfdc8d301d831d025c8a916d7)
@@ -0,0 +1,56 @@
+package net.gjerull.etherpad.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.
+ *
+ * Example:
+ *
+ *
+ * Request req = new POSTRequest(url_object);
+ * String resp = req.send();
+ *
+ */
+public class POSTRequest implements Request {
+ private final URL url;
+ private final String body;
+
+ /**
+ * Instantiates a new POSTRequest.
+ *
+ * @param url the URL object
+ * @param body url-encoded (application/x-www-form-urlencoded) request body
+ */
+ public POSTRequest(URL url, String body) {
+ this.url = url;
+ this.body = body;
+ }
+
+ /**
+ * 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.body);
+ out.close();
+
+ BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ StringBuilder response = new StringBuilder();
+ String buffer;
+ while ((buffer = in.readLine()) != null) {
+ response.append(buffer);
+ }
+ in.close();
+ return response.toString();
+ }
+}
Index: 3rdParty_sources/etherpad/net/gjerull/etherpad/client/Request.java
===================================================================
diff -u
--- 3rdParty_sources/etherpad/net/gjerull/etherpad/client/Request.java (revision 0)
+++ 3rdParty_sources/etherpad/net/gjerull/etherpad/client/Request.java (revision d1558f68d1dbddfdfdc8d301d831d025c8a916d7)
@@ -0,0 +1,5 @@
+package net.gjerull.etherpad.client;
+
+public interface Request {
+ String send() throws Exception;
+}
Index: 3rdParty_sources/versions.txt
===================================================================
diff -u -r2ab1076d8852ca61f6e633ea31de878497c3023a -rd1558f68d1dbddfdfdc8d301d831d025c8a916d7
--- 3rdParty_sources/versions.txt (.../versions.txt) (revision 2ab1076d8852ca61f6e633ea31de878497c3023a)
+++ 3rdParty_sources/versions.txt (.../versions.txt) (revision d1558f68d1dbddfdfdc8d301d831d025c8a916d7)
@@ -27,6 +27,8 @@
CSRF Guard master from 2020.01.07 with a custom modification in CsrfGuard.java
+Etherpad Client 1.2.13
+
Hibernate Core 5.3.6
httpunit 1.7