summaryrefslogtreecommitdiff
path: root/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie
diff options
context:
space:
mode:
authorMarkus Warg <markus@mawaunix.mawa.sls>2010-03-31 10:12:32 +0200
committerMarkus Warg <markus@mawaunix.mawa.sls>2010-03-31 10:12:32 +0200
commit8398c9048d34a1f51212ae770998fc082fc93b69 (patch)
tree000a3afc899508e8087de4dc2312f45a1fc22895 /external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie
parentbd05b1ed77d06a4936b1253d5166c25ee66b0702 (diff)
downloadcacert-mgr-8398c9048d34a1f51212ae770998fc082fc93b69.tar.gz
cacert-mgr-8398c9048d34a1f51212ae770998fc082fc93b69.tar.xz
cacert-mgr-8398c9048d34a1f51212ae770998fc082fc93b69.zip
initially import ZendFramework-1.9.5 into repository
code was modified slightly, so the code differs from the original downloadable 1.9.5 version
Diffstat (limited to 'external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie')
-rw-r--r--external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Document.java109
-rw-r--r--external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Documents.java331
-rw-r--r--external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Main.java46
-rw-r--r--external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieException.java22
-rw-r--r--external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieServlet.java423
5 files changed, 931 insertions, 0 deletions
diff --git a/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Document.java b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Document.java
new file mode 100644
index 0000000..1f5b455
--- /dev/null
+++ b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Document.java
@@ -0,0 +1,109 @@
+package org.dojo.moxie;
+
+import java.util.*;
+import java.util.regex.*;
+
+/**
+ @author Brad Neuberg, bkn3@columbia.edu
+*/
+public class Document{
+ protected Integer id = null;
+ protected Integer origId = null;
+ protected String fileName = null;
+ protected long createdOn;
+ protected long lastUpdated;
+ protected String content = null;
+
+ /**
+ @param id The ID of this document; this can either be a positive
+ number if this document exists in the database; it can also be null
+ or negative to indicate that no database-assigned id exists yet.
+ @throws IllegalArgumentException Thrown if fileName,
+ createdOn, or lastUpdated are null or if fileName is invalid.
+ */
+ public Document(Integer id, String fileName, long createdOn,
+ long lastUpdated, String content)
+ throws MoxieException{
+ if(validFileName(fileName) == false){
+ throw new MoxieException("Invalid file name");
+ }
+
+ this.id = id;
+ this.fileName = fileName;
+ this.createdOn = createdOn;
+ this.lastUpdated = lastUpdated;
+ this.content = content;
+ }
+
+ public void setId(Integer Id){
+ this.id = id;
+ }
+
+ public Integer getId(){
+ return this.id;
+ }
+
+ public void setOrigId(Integer origId){
+ this.origId = origId;
+ }
+
+ public Integer getOrigId(){
+ return this.origId;
+ }
+
+ public void setFileName(String fileName){
+ this.fileName = fileName;
+ }
+
+ public String getFileName(){
+ return fileName;
+ }
+
+ public void setCreatedOn(long createdOn){
+ this.createdOn = createdOn;
+ }
+
+ public long getCreatedOn(){
+ return this.createdOn;
+ }
+
+ public void setLastUpdated(long lastUpdated){
+ this.lastUpdated = lastUpdated;
+ }
+
+ public long getLastUpdated(){
+ return this.lastUpdated;
+ }
+
+ public void setContent(String content){
+ this.content = content;
+ }
+
+ public String getContent(){
+ return content;
+ }
+
+ public String toString(){
+ StringBuffer results = new StringBuffer();
+ results.append("{");
+ results.append("id: " + this.id + ", ");
+ if(this.origId != null){
+ results.append("origID: " + this.origId + ", ");
+ }
+ results.append("fileName: '" + this.fileName + "', ");
+ results.append("createdOn: " + this.createdOn + ", ");
+ results.append("lastUpdated: " + this.lastUpdated + ", ");
+ results.append("content: '" + this.content + "'");
+ results.append("}");
+
+ return results.toString();
+ }
+
+ public static boolean validFileName(String fileName){
+ if(fileName == null || fileName.trim().equals("")){
+ return false;
+ }
+
+ return Pattern.matches("^[0-9A-Za-z_]*$", fileName);
+ }
+}
diff --git a/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Documents.java b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Documents.java
new file mode 100644
index 0000000..946a1eb
--- /dev/null
+++ b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Documents.java
@@ -0,0 +1,331 @@
+package org.dojo.moxie;
+
+import java.util.*;
+import java.sql.*;
+
+/**
+ FIXME: We simply synchronize every method in this static class in order
+ to ensure that our JDBC Connection is thread safe. This is fine for our simple
+ uses as a demo app, but if Moxie needs to be used in an environment with lots
+ of accesses it should be rewritten to use a thread-safe JDBC connection
+ pooling library instead; JDBC Connections are not necessarily thread-safe
+ by default.
+
+ @author Brad Neuberg, bkn3@columbia.edu
+*/
+public final class Documents{
+ private static Connection con;
+
+ // use PreparedStatements to protect against SQL Injection Attacks
+ private static PreparedStatement listSQL = null;
+ private static PreparedStatement findByFileNameSQL = null;
+ private static PreparedStatement findByIDSQL = null;
+ private static PreparedStatement newItemSQL = null;
+ private static PreparedStatement deleteItemSQL = null;
+ private static PreparedStatement updateItemSQL = null;
+
+ /**
+ Initializes our Documents object and underlying database connection.
+ */
+ public synchronized static void initialize(String jdbcURL, String userName,
+ String password, String driver)
+ throws MoxieException{
+ try {
+ // open the database
+ Class.forName(driver).newInstance();
+ con = DriverManager.getConnection(jdbcURL, userName, password);
+
+ // create the schema if necessary
+ Documents.createDb();
+ }catch(Exception e) {
+ throw new MoxieException(e);
+ }
+ }
+
+ /** Returns all available documents. */
+ public synchronized static List<Document> list() throws MoxieException{
+ try{
+ if(listSQL == null){
+ listSQL = Documents.con.prepareStatement(
+ "SELECT * FROM DOCUMENTS");
+ }
+
+ List<Document> allDocs = new ArrayList<Document>();
+ ResultSet results = listSQL.executeQuery();
+
+ while(results.next()){
+ Document doc = fromResultSet(results);
+ allDocs.add(doc);
+ }
+
+ return allDocs;
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+
+ /**
+ Finds the given Document based on the filename. If this file name
+ does not exist than null is returned.
+ */
+ public synchronized static Document findByFileName(String fileName)
+ throws MoxieException{
+ try{
+ if(findByFileNameSQL == null){
+ findByFileNameSQL = con.prepareStatement(
+ "SELECT * FROM DOCUMENTS WHERE file_name=?");
+ }
+
+ // execute our query
+ findByFileNameSQL.setString(1, fileName);
+ ResultSet results = findByFileNameSQL.executeQuery();
+
+ // try to get the first result
+ if(results.next() == false){ // no results
+ return null;
+ }
+
+ Document doc = fromResultSet(results);
+
+ return doc;
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+
+ /**
+ Finds the given Document based on it's ID. If no Document with this
+ ID exists than null is returned.
+ */
+ public synchronized static Document findByID(int id)
+ throws MoxieException{
+ try{
+ if(findByIDSQL == null){
+ findByIDSQL = con.prepareStatement(
+ "SELECT * FROM DOCUMENTS WHERE ID=?");
+ }
+
+ // execute our query
+ findByIDSQL.setInt(1, id);
+ ResultSet results = findByIDSQL.executeQuery();
+
+ // try to get the first result
+ if(results.next() == false){ // no results
+ return null;
+ }
+
+ Document doc = fromResultSet(results);
+
+ return doc;
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+
+ /**
+ Creates a new document based on the given document object.
+
+ @param doc A Document object with it's values filled in; the id
+ field should be a negative number to indicate that no actual id
+ has been assigned to this document yet.
+
+ @returns Document The new document created, with it's id field filled
+ out to be an actual, assigned ID and origID filled out with the original
+ value of ID. For example, if a document is passed in with ID "-2", then
+ the document returned will be an actual ID such as "2000" and origID will
+ be "-2".
+
+ @throws MoxieException Thrown if a document with the given file name
+ already exists.
+ */
+ public synchronized static Document newItem(Document doc)
+ throws MoxieException{
+ try{
+ if(newItemSQL == null){
+ newItemSQL = con.prepareStatement(
+ "INSERT INTO DOCUMENTS (file_name, created_on, last_updated, content) "
+ + "VALUES (?, ?, ?, ?)");
+ }
+
+ // see if we exist yet
+ if(exists(doc.getFileName())){
+ throw new MoxieException("The document '" + doc.getFileName()
+ + "' already exists");
+ }
+
+ // setup our SQL values
+ newItemSQL.setString(1, doc.getFileName());
+ java.sql.Timestamp createdOnTimestamp =
+ new java.sql.Timestamp(doc.getCreatedOn());
+ java.sql.Timestamp lastUpdatedTimestamp =
+ new java.sql.Timestamp(doc.getLastUpdated());
+ newItemSQL.setTimestamp(2, createdOnTimestamp);
+ newItemSQL.setTimestamp(3, lastUpdatedTimestamp);
+ newItemSQL.setString(4, doc.getContent());
+
+ // execute our insert
+ newItemSQL.executeUpdate();
+
+ // look the Document back up to get its
+ // new ID
+ Document newDoc = findByFileName(doc.getFileName());
+ newDoc.setOrigId(doc.getId());
+
+ return newDoc;
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+
+ public synchronized static void deleteItem(Document doc)
+ throws MoxieException{
+ Documents.deleteItem(doc.getId());
+ }
+
+ /*
+ Deletes a Document with the given ID.
+ */
+ public synchronized static void deleteItem(int id)
+ throws MoxieException{
+ try{
+ if(deleteItemSQL == null){
+ deleteItemSQL = con.prepareStatement(
+ "DELETE FROM DOCUMENTS WHERE ID = ?");
+ }
+
+ // execute our query
+ deleteItemSQL.setInt(1, id);
+ deleteItemSQL.executeUpdate();
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+
+ /**
+ Updates the given Document with new data.
+
+ @throws MoxieException Thrown if a different document already
+ exists with the given new file name, if a new file name
+ is given.
+ */
+ public synchronized static void updateItem(Document doc)
+ throws MoxieException{
+ try{
+ if(updateItemSQL == null){
+ updateItemSQL = con.prepareStatement(
+ "UPDATE DOCUMENTS SET file_name = ?, "
+ + "created_on = ?, "
+ + "last_updated = ?, "
+ + "content = ? "
+ + "WHERE id = ?");
+ }
+
+ // see if we even exist with this ID
+ if(exists(doc.getId()) == false){
+ return;
+ }
+
+ // see if this file name is already taken,
+ // just in case it was renamed to something already
+ // existing
+ Document compareMe = findByFileName(doc.getFileName());
+ if(compareMe != null && compareMe.getFileName().equals(doc.getFileName())
+ && compareMe.getId() != null
+ && doc.getId() != null
+ && compareMe.getId().equals(doc.getId()) == false){
+ throw new MoxieException("A different document with the file name "
+ + "'" + doc.getFileName() + "' already exists");
+ }
+
+ // setup our SQL values
+ updateItemSQL.setString(1, doc.getFileName());
+ java.sql.Timestamp createdOnTimestamp =
+ new java.sql.Timestamp(doc.getCreatedOn());
+ java.sql.Timestamp lastUpdatedTimestamp =
+ new java.sql.Timestamp(doc.getLastUpdated());
+ updateItemSQL.setTimestamp(2, createdOnTimestamp);
+ updateItemSQL.setTimestamp(3, lastUpdatedTimestamp);
+ updateItemSQL.setString(4, doc.getContent());
+ updateItemSQL.setInt(5, doc.getId());
+
+ // execute our insert
+ updateItemSQL.executeUpdate();
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+
+ public synchronized static boolean exists(String fileName)
+ throws MoxieException{
+ Document doc = findByFileName(fileName);
+ return (doc != null);
+ }
+
+ public synchronized static boolean exists(int id)
+ throws MoxieException{
+ Document doc = findByID(id);
+ return (doc != null);
+ }
+
+ private static Document fromResultSet(ResultSet results)
+ throws MoxieException{
+ try{
+ // create a Document object with our values
+ int id = results.getInt("id");
+ String fileName = results.getString("file_name");
+ String content = results.getString("content");
+
+ // convert java.sql.Date objects to java.util.Date objects
+ long createdOnTime = results.getTimestamp("created_on").getTime();
+
+ long lastUpdatedTime = results.getTimestamp("last_updated").getTime();
+
+ Document doc = new Document(id, fileName, createdOnTime, lastUpdatedTime,
+ content);
+
+ return doc;
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+
+ private static void createDb() throws MoxieException{
+ try{
+ Statement s = con.createStatement();
+
+ // see if the DOCUMENTS table exists yet
+ DatabaseMetaData metaData = con.getMetaData();
+ ResultSet rs = metaData.getTables(null, null, "DOCUMENTS", null);
+ boolean exist = false;
+ if(rs.next()){
+ exist = true;
+ }
+
+ if(exist){
+ return;
+ }
+
+ s.execute("CREATE TABLE DOCUMENTS ("
+ + "id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, "
+ + "file_name VARCHAR(255) NOT NULL, "
+ + "created_on TIMESTAMP NOT NULL, "
+ + "last_updated TIMESTAMP NOT NULL, "
+ + "content CLOB(500K) NOT NULL, "
+ + "PRIMARY KEY(id), "
+ + "UNIQUE(file_name) "
+ + ")");
+
+ // create some fake data
+ s.execute("INSERT INTO DOCUMENTS (file_name, created_on, last_updated, content) "
+ + "VALUES ('message', CURRENT TIMESTAMP, CURRENT TIMESTAMP, 'Watson, come quickly!')");
+ s.execute("INSERT INTO DOCUMENTS (file_name, created_on, last_updated, content) "
+ + "VALUES ('message2', CURRENT TIMESTAMP, CURRENT TIMESTAMP, 'Hello World!')");
+ s.execute("INSERT INTO DOCUMENTS (file_name, created_on, last_updated, content) "
+ + "VALUES ('message3', CURRENT TIMESTAMP, CURRENT TIMESTAMP, 'Goodbye World!')");
+ s.execute("INSERT INTO DOCUMENTS (file_name, created_on, last_updated, content) "
+ + "VALUES ('message4', CURRENT TIMESTAMP, CURRENT TIMESTAMP, 'Brad Neuberg was here')");
+ }catch(Exception e){
+ throw new MoxieException(e);
+ }
+ }
+} \ No newline at end of file
diff --git a/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Main.java b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Main.java
new file mode 100644
index 0000000..becd520
--- /dev/null
+++ b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/Main.java
@@ -0,0 +1,46 @@
+package org.dojo.moxie;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.mortbay.jetty.*;
+import org.mortbay.jetty.handler.*;
+import org.mortbay.jetty.servlet.*;
+
+/**
+ A quick starter class that enables users to run the Moxie
+ server-side extremely quickly. We use the embedded Derby
+ database that comes bundled with Java, coupled with an
+ embedded version of the tiny Jetty embedded web-server.
+
+ @author Brad Neuberg, bkn3@columbia.edu
+*/
+public class Main{
+ public static void main(String args[]){
+ try{
+ // start our embedded web server, Jetty
+ Server server = new Server(8000);
+
+ // serve up our Moxie/Dojo files
+ ResourceHandler resourceHandler = new ResourceHandler();
+ resourceHandler.setResourceBase("../../../..");
+ server.addHandler(resourceHandler);
+
+ // add the Moxie servlet
+ Context moxieRoot = new Context(server, "/moxie", Context.SESSIONS);
+ Servlet moxieServlet = new MoxieServlet("jdbc:derby:moxie;create=true", null, null,
+ "org.apache.derby.jdbc.EmbeddedDriver");
+ moxieRoot.addServlet(new ServletHolder(moxieServlet), "/*");
+
+ System.out.println("Starting web server on port 8000...");
+ server.start();
+
+ System.out.println("Moxie ready to try on port 8000.");
+ System.out.println("Open a web browser and go to:");
+ System.out.println("http://localhost:8000/demos/offline/editor/editor.html");
+ }catch(Exception e){
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
diff --git a/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieException.java b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieException.java
new file mode 100644
index 0000000..00f6702
--- /dev/null
+++ b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieException.java
@@ -0,0 +1,22 @@
+package org.dojo.moxie;
+
+/**
+ @author Brad Neuberg, bkn3@columbia.edu
+*/
+public class MoxieException extends Exception{
+ public MoxieException(){
+ super();
+ }
+
+ public MoxieException(String s){
+ super(s);
+ }
+
+ public MoxieException(String s, Throwable cause){
+ super(s, cause);
+ }
+
+ public MoxieException(Throwable cause){
+ super(cause);
+ }
+} \ No newline at end of file
diff --git a/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieServlet.java b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieServlet.java
new file mode 100644
index 0000000..1b357de
--- /dev/null
+++ b/external/ZendFramework-1.9.5/externals/dojo/demos/offline/editor/server/org/dojo/moxie/MoxieServlet.java
@@ -0,0 +1,423 @@
+package org.dojo.moxie;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+/**
+ Exposes a simple RESTian API for working with Moxie documents.
+ The objects we expose are Moxie documents with their filenames:
+
+ /somePageName1
+ /somePageName2
+
+ etc.
+
+ To view a page, simply do a GET on it's page name. If a page
+ does not exist you will get a 404 (Not Found); if it is an incorrect filename
+ you will get a 403 (Forbidden).
+
+ To see a list of all page's, simply do a GET on /*
+
+ If your HTTP client has sent "text/html" as one of the things
+ it accepts in it's Accept header, then a simple HTML page
+ will be returned that uses an unordered list
+ of links to point to all of our pages:
+
+ <html><body>
+ <ul>
+ <li><a href="somePageName1">somePageName1</a></li>
+ <li><a href="somePageName2">somePageName2</a></li>
+ </ul>
+ </body></html>
+
+ If your client doesn't send "text/html" but sends "text/javascript"
+ than we return this list of page names as JSON:
+
+ [
+ "somePageName1", "somePageName2"
+ ]
+
+ To create a new page or update an existing page, do a POST to
+ what the page name will be or is,
+ such as /aNewPage1 or /updateMe. The payload can either be URL encoded form
+ values or can be a simple HTML page. If it is a URL encoded
+ form value, the Content-Type header must be
+ "application/x-www-form-urlencoded"; there should be one form
+ value, with the key name 'content' and the values URL encoded.
+
+ If the payload is a simple HTML page, the Content-Type should
+ be "text/html" and the POSt content can just be plain, normal
+ HTML.
+
+ The server responds with either a 201 (Created); a
+ 403 (Forbidden) if the page already exists or has a malformed name,
+ or 200 OK if the update was successful.
+
+ To delete a page, we need to simulate a DELETE request to the / URL
+ of the page name. Safari and Opera have issues with the DELETE method,
+ so we use 'X-Method-Override: DELETE' on these. The server
+ returns a 410 (Gone) request if successful,
+ 404 (Not Found) if there was no page there originally, or
+ 403 (Not Allowed) if the file name is mangled.
+
+ If clients can correctly send DELETE requests, you can bypass
+ having to send 'X-Method-Override' and simply do a normal DELETE
+ request as outlined above.
+
+ We also expose /download/, called with a GET, which will download
+ a JSON data structure with the contents of all of our documents.
+ This JSON structure is an array of objects, where each object
+ is an object with a 'fileName' member that has the file name
+ of that document, and a 'content' entry with the content of that
+ document. Example:
+
+ [
+ {fileName: "message1", content: "hello world"},
+ {fileName: "message2", content: "goodbye world"}
+ ]
+
+ @author Brad Neuberg, bkn3@columbia.edu
+*/
+public class MoxieServlet extends HttpServlet{
+ private String jdbcURL, userName, password, driver;
+
+ public MoxieServlet(String jdbcURL, String userName,
+ String password, String driver){
+ this.jdbcURL = jdbcURL;
+ this.userName = userName;
+ this.password = password;
+ this.driver = driver;
+ }
+
+ public void init() throws ServletException{
+ // initialize our database and the class that allows us to
+ // gain access to our documents
+ try{
+ Documents.initialize(jdbcURL, userName, password, driver);
+ }catch(MoxieException e){
+ throw new ServletException(e);
+ }
+ }
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException{
+ try{
+ String path = req.getPathInfo();
+ if(path == null){
+ path = "/*";
+ }
+
+ // dispatch our action
+ if(path.equals("/*")){
+ list(req, res);
+ }else if(path.equals("/download") || path.equals("/download")){
+ download(req, res);
+ }else{
+ viewItem(req, res);
+ }
+ }catch(MoxieException e){
+ e.printStackTrace();
+ throw new ServletException(e);
+ }
+ }
+
+ public void doPost(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException{
+ try{
+ String methodOverride = req.getHeader("X-Method-Override");
+
+ // dispatch our action
+ if(methodOverride == null){
+ updateItem(req, res);
+ }else if(methodOverride.equals("DELETE")){
+ deleteItem(req, res);
+ }
+ }catch(MoxieException e){
+ e.printStackTrace();
+ throw new ServletException(e);
+ }
+ }
+
+ public void doDelete(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException{
+ try{
+ deleteItem(req, res);
+ }catch(MoxieException e){
+ throw new ServletException(e);
+ }
+ }
+
+ private void viewItem(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ // get the file name
+ String fileName = getFileName(req, res);
+
+ // white list the file name
+ if(Document.validFileName(fileName) == false){ // invalid file name
+ // HTTP Status Code 403
+ res.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ // see if the file exists
+ if(Documents.exists(fileName) == false){
+ // HTTP Status Code 404
+ res.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ // try to get it
+ Document doc = Documents.findByFileName(fileName);
+ res.setContentType("text/html");
+ PrintWriter out = res.getWriter();
+ out.write(doc.content);
+ }
+
+ private void newItem(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ // get the file name
+ String fileName = getFileName(req, res);
+
+ // white list the file name
+ if(Document.validFileName(fileName) == false){ // invalid file name
+ // HTTP Status Code 403
+ res.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ // populate it's Document values
+ String content = getRequestAsString(req);
+ if(content == null){
+ res.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ Document doc = new Document(null, fileName, new Date().getTime(), new Date().getTime(),
+ content);
+
+ // create it
+ Documents.newItem(doc);
+
+ // send back a 201 Created response with the correct
+ // return values
+ res.setStatus(HttpServletResponse.SC_CREATED);
+ res.setHeader("Location", fileName);
+ res.setContentType("text/html");
+ }
+
+ private void deleteItem(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ // get the file name
+ String fileName = getFileName(req, res);
+
+ // white list the file name
+ if(Document.validFileName(fileName) == false){ // invalid file name
+ // HTTP Status Code 403
+ res.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ // see if the file exists
+ if(Documents.exists(fileName) == false){
+ // HTTP Status Code 404
+ res.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ // get the original document
+ Document doc = Documents.findByFileName(fileName);
+
+ // delete it
+ Documents.deleteItem(doc.getId());
+
+ // send back a 410 Gone response
+ res.setStatus(HttpServletResponse.SC_GONE);
+ }
+
+ private void updateItem(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ // get the file name
+ String fileName = getFileName(req, res);
+
+ // white list the file name
+ if(Document.validFileName(fileName) == false){ // invalid file name
+ // HTTP Status Code 403
+ res.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ // see if the file exists; if it doesn't, we
+ // will create a new document
+ if(Documents.exists(fileName) == false){
+ newItem(req, res);
+ return;
+ }
+
+ // get the original document
+ Document doc = Documents.findByFileName(fileName);
+
+ // get our new content
+ String content = getRequestAsString(req);
+ if(content == null){
+ res.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ // update our values
+ doc.setLastUpdated(new Date().getTime());
+ doc.setContent(content);
+
+ // save them
+ Documents.updateItem(doc);
+
+ // send back a 200 OK response with the correct
+ // return values
+ res.setStatus(HttpServletResponse.SC_OK);
+ }
+
+ private void list(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ // get our file names
+ List<Document> allDocs = Documents.list();
+
+ // determine what kind of representation to return
+ String accepts = req.getHeader("Accept");
+ if(accepts == null
+ || accepts.indexOf("text/html") != -1){ // return HTML
+ listReturnHTML(allDocs, req, res);
+ }else{
+ listReturnJSON(allDocs, req, res);
+ }
+ }
+
+ private void download(HttpServletRequest req, HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ // get our file names
+ List<Document> allDocs = Documents.list();
+
+ // send our JSON response back
+ res.setContentType("text/javascript");
+ PrintWriter out = res.getWriter();
+
+ out.write("[\n");
+
+ // loop through each document
+ Iterator<Document> iter = allDocs.iterator();
+ while(iter.hasNext()){
+ Document d = iter.next();
+ out.write("{");
+
+ // FIXME: Use a real JSON serialization library
+ // write out the file name
+ out.write("fileName: \"" + d.fileName + "\", ");
+
+ // escape our double quotes
+ Pattern quotePattern = Pattern.compile("[\"]", Pattern.MULTILINE);
+ Matcher m = quotePattern.matcher(d.content);
+ String content = m.replaceAll("\\\\\"");
+
+ // escape multi line strings
+ Pattern linePattern = Pattern.compile("\n|\r", Pattern.MULTILINE);
+ m = linePattern.matcher(content);
+ content = m.replaceAll("\\\\\n");
+
+ // write out our contents
+ out.write("content: \"" + content + "\"");
+
+ out.write("}");
+
+ // add a comma if we are not the last one
+ if(iter.hasNext() == true){
+ out.write(", \n");
+ }else{
+ out.write("\n");
+ }
+ }
+
+ out.write("]\n");
+ }
+
+ private String getFileName(HttpServletRequest req, HttpServletResponse res)
+ throws MoxieException{
+ // get the file to view
+ String fileName = req.getPathInfo();
+
+ // strip off the leading slash
+ fileName = fileName.substring(1);
+
+ return fileName;
+ }
+
+ private String getRequestAsString(HttpServletRequest req)
+ throws IOException{
+ // correctly decode this value
+ String contentType = req.getHeader("Content-Type");
+ if(contentType != null && contentType.equals("text/html")){
+ // basic HTML in POST payload
+
+ // FIXME: WARNING: The combination of a wrapped InputStream being
+ // treated as a reader, with the deprecated readLine() method below
+ // might mangle i18n text
+ BufferedReader requestData = new BufferedReader(
+ new InputStreamReader(req.getInputStream()));
+ StringBuffer stringBuffer = new StringBuffer();
+ String line;
+ while ((line = requestData.readLine()) != null){
+ stringBuffer.append(line);
+ }
+
+ String content = stringBuffer.toString();
+ return content;
+ }else{ // encoded form values -- application/x-www-form-urlencoded
+ String content = req.getParameter("content");
+
+ return content;
+ }
+ }
+
+ private void listReturnHTML(List<Document> allDocs,
+ HttpServletRequest req,
+ HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ res.setContentType("text/html");
+ PrintWriter out = res.getWriter();
+ out.write("<html><body><ul>");
+
+ // loop through each file name and write it out as an A tag
+ Iterator<Document> iter = allDocs.iterator();
+ while(iter.hasNext()){
+ Document d = iter.next();
+ out.write("<li><a href=\"" + d.fileName + "\">"
+ + d.fileName + "</a></li>");
+ }
+ out.write("</ul></body></html>");
+ }
+
+ private void listReturnJSON(List<Document> allDocs,
+ HttpServletRequest req,
+ HttpServletResponse res)
+ throws IOException, ServletException, MoxieException{
+ res.setContentType("text/javascript");
+ PrintWriter out = res.getWriter();
+
+ out.write("[");
+
+ // loop through each file name and write it out as an A tag
+ Iterator<Document> iter = allDocs.iterator();
+ while(iter.hasNext()){
+ Document d = iter.next();
+ // FIXME: Use a real JSON serialization library
+ out.write("\"" + d.fileName + "\"");
+ if(iter.hasNext() == true){
+ out.write(", \n");
+ }
+ }
+
+ out.write("]\n");
+ }
+
+} \ No newline at end of file