org.elissa.server.SimpleStorageServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.elissa.server.SimpleStorageServlet.java

Source

package org.elissa.server;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;

/**
 * Copyright (c) 2007 Martin Czuchra.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
public class SimpleStorageServlet extends HttpServlet {

    // serialization id.
    private static final long serialVersionUID = -5801302483240001557L;
    private static final boolean DEBUG = false;

    private static Configuration config = null;
    private Connection database = null;
    private String currentResource = null;

    private void prepare(HttpServletRequest req, HttpServletResponse res) throws InstantiationException,
            IllegalAccessException, ClassNotFoundException, SQLException, ConfigurationException {

        if (SimpleStorageServlet.config == null)
            SimpleStorageServlet.config = new PropertiesConfiguration("database.properties");

        String connector = SimpleStorageServlet.config.getString("db.connector");
        String url = SimpleStorageServlet.config.getString("db.url");
        String username = SimpleStorageServlet.config.getString("db.username");
        String password = SimpleStorageServlet.config.getString("db.password");

        Class.forName(connector).newInstance();
        this.database = DriverManager.getConnection(url, username, password);

        this.currentResource = req.getParameter("resource");
    }

    private void process(boolean isPost, HttpServletRequest req, HttpServletResponse res) {

        try {

            prepare(req, res);

            if (isPost) {

                this.storeResource(req, res);

            } else if (this.currentResource == null)

                this.showProcessList(req, res);

            else {

                String stencilsetURL = req.getParameter("stencilset");
                this.showResource(req, res, stencilsetURL);

            }

        } catch (Exception e) {

            this.showError(e, res);

        } finally {

            if (database != null) {
                try {
                    database.close();
                } catch (Exception e) { /* ignore close errors */
                }
            }
        }
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

        this.process(false, req, res);
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

        this.process(true, req, res);
    }

    protected void storeResource(HttpServletRequest req, HttpServletResponse res) throws SQLException {

        String data = req.getParameter("data");

        PreparedStatement stmt = database.prepareStatement("SELECT ID FROM sites WHERE Name = ?");
        stmt.setString(1, this.currentResource);

        if (stmt.executeQuery().next()) {

            PreparedStatement store = database.prepareStatement("UPDATE sites SET Site = ? WHERE Name = ?");
            store.setString(1, data);
            store.setString(2, this.currentResource);
            store.execute();

        } else {

            PreparedStatement store = database.prepareStatement("INSERT INTO sites (Name, Site) VALUES (?, ?)");
            store.setString(2, data);
            store.setString(1, this.currentResource);
            store.execute();
        }
    }

    public void showResource(HttpServletRequest req, HttpServletResponse res, String stencilsetURL)
            throws SQLException {

        res.setContentType("application/xhtml+xml");

        PreparedStatement stmt = database.prepareStatement("SELECT ID, Site FROM sites WHERE Name = ?");
        stmt.setString(1, this.currentResource);

        stmt.execute();

        ResultSet rs = stmt.getResultSet();
        String result;

        if (rs.next())

            result = rs.getString(2);

        else {

            result = "<div class=\"-oryx-canvas\" id=\"oryx-canvas123\" style=\"width:1200px; height:600px;\">";
            result += "<a href=\"" + stencilsetURL + "\" rel=\"oryx-stencilset\"></a>";
            result += "<span class=\"oryx-mode\">writeable</span>";
            result += "<span class=\"oryx-mode\">fullscreen</span>";
            result += "</div>";
        }

        this.template(req, res, result);

    }

    public void template(HttpServletRequest req, HttpServletResponse res, String resource) throws SQLException {

        PrintWriter out;
        try {
            out = res.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        out.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\"");
        out.println("xmlns:b3mn=\"http://b3mn.org/2007/b3mn\"");
        out.println("xmlns:ext=\"http://b3mn.org/2007/ext\"");
        out.println("xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"");
        out.println("xmlns:atom=\"http://b3mn.org/2007/atom+xhtml\">");

        out.println("<head profile=\"http://purl.org/NET/erdf/profile\">");

        out.println("<title>" + this.currentResource + " - Oryx</title>");

        out.println("<!-- libraries -->");
        out.println("<script src=\"lib/prototype-1.5.1.js\" type=\"text/javascript\" />");
        out.println("<script src=\"lib/path_parser.js\" type=\"text/javascript\" />");
        out.println("<script src=\"lib/ext-2.0.2/adapter/yui/yui-utilities.js\" type=\"text/javascript\" />");
        out.println("<script src=\"lib/ext-2.0.2/adapter/yui/ext-yui-adapter.js\" type=\"text/javascript\" />");
        out.println("<script src=\"lib/ext-2.0.2/ext-all.js\" type=\"text/javascript\" />");
        out.println("<script src=\"lib/ext-2.0.2/color-field.js\" type=\"text/javascript\" />");
        out.println("<style media=\"screen\" type=\"text/css\">");
        out.println("@import url(\"lib/ext-2.0.2/resources/css/ext-all.css\");");
        out.println("@import url(\"lib/ext-2.0.2/resources/css/xtheme-gray.css\");");
        out.println("</style>");

        out.println("<script src=\"shared/kickstart.js\" type=\"text/javascript\" />");
        out.println("<script src=\"shared/erdfparser.js\" type=\"text/javascript\" />");
        out.println("<script src=\"shared/datamanager.js\" type=\"text/javascript\" />");

        out.println("<!-- oryx editor -->");
        out.println("<script src=\"" + (SimpleStorageServlet.DEBUG ? "oryx.debug.js" : "oryx.js")
                + "\" type=\"text/javascript\" />");
        out.println("<link rel=\"Stylesheet\" media=\"screen\" href=\"css/theme_norm.css\" type=\"text/css\" />");

        out.println("<!-- erdf schemas -->");
        out.println("<link rel=\"schema.dc\" href=\"http://purl.org/dc/elements/1.1/\" />");
        out.println("<link rel=\"schema.dcTerms\" href=\"http://purl.org/dc/terms/\" />");
        out.println("<link rel=\"schema.b3mn\" href=\"http://b3mn.org\" />");
        out.println("<link rel=\"schema.oryx\" href=\"http://oryx-editor.org/\" />");
        out.println("<link rel=\"schema.raziel\" href=\"http://raziel.org/\" />");

        // providing a base is essential for the layouter plugin, as the
        // underlying rdf parser does not allow relative urls, and the
        // extract-rdf xsl script by Ian Davis doesn't respect xml:base but the
        // html base element. However, ehen providing a base, fragments refering
        // to fetched svg files break, since they now all refer to the base
        // element's href attribute. Latter makes the arrowheads disappear. To
        // fix this, the layouter plugin currently adds a base element before
        // sending the current data back to the server.
        // out.println("<base href=\"" + req.getRequestURL() + "\" />");

        out.println("</head>");

        out.println("<body style=\"overflow:hidden;\"><div class='processdata' style='display:none'>");

        out.println(resource);

        out.println("</div>");
        out.println("<div class='processdata'></div>");
        out.println("</body>");
        out.println("</html>");
    }

    /**
     * Returns a map of all available stencil sets, which means, all currently
     * installed stencil sets. It therefore traverses all subfolders of the
     * stencil sets folder and regards each JSON file within them as a valid
     * stencil set. All files ending with ".json" are considered JSON files.
     * 
     * @return a map of all available stencilsets (name => url).
     */
    private Map<String, URL> getAvailableStencilsets(URL base) {

        // TODO make stencilsets folder configurable.
        // TODO make webapp name be found dynamically.
        String webappName = "/oryx";
        String stencilsetPath = this.getServletContext().getRealPath("/") + File.separator + "stencilsets"
                + File.separator;
        Map<String, URL> stencilsets = new HashMap<String, URL>();
        File dir = new File(stencilsetPath);

        // if dir is not a directory
        if (!(dir.isDirectory()))
            return stencilsets;

        // for each folder within...
        for (File contained : dir.listFiles()) {
            if (!(contained.isDirectory()))
                continue;

            // find the included json files.
            for (File jsonFile : contained.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.endsWith(".json");
                }
            })) {

                try {

                    // construct url for the stencilset
                    URL location = new URL(base.getProtocol(), base.getHost(), base.getPort(),
                            webappName + "/stencilsets/" + contained.getName() + "/" + jsonFile.getName());

                    String name = this.lookupStencilsetName(jsonFile.getName(), location);

                    // put it in the map
                    stencilsets.put(name, location);

                } catch (MalformedURLException e) {

                    // if there is a problem, ignore this stencil set.
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        return stencilsets;
    }

    private String lookupStencilsetName(String name, URL location) {
        return name.substring(0, name.length() - 5);
    }

    public void showProcessList(HttpServletRequest req, HttpServletResponse res)
            throws SQLException, MalformedURLException {

        PreparedStatement stmt = database.prepareStatement("SELECT ID, Name FROM sites");

        PrintWriter out;
        try {
            out = res.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        res.setContentType("text/html");

        out.println(
                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");

        out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">");
        out.println("<head>");

        out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>");
        out.println("<title>Oryx - Process Overview</title>");
        out.println("</head>");

        out.println("<body>");
        out.println("<div style=\"text-align: center;\">");

        out.println("<p>");
        out.println("<form action='" + req.getRequestURL() + "' method='get'>");
        out.println("Create a new process:<br/>");
        out.println("<img src='./images/crystal/empty.png' style='float: clear;' width='128' height='128'/><br/>");
        out.println("<input type='text' name='resource' value='' />");

        // get available stencil sets.
        URL base = new URL(req.getRequestURL().toString());
        Map<String, URL> stencilsets = getAvailableStencilsets(base);

        out.println("<select name=\"stencilset\" size=\"1\">");

        for (String name : stencilsets.keySet()) {
            URL url = stencilsets.get(name);
            out.println("<option value=\"" + url.toString() + "\">");
            out.println(name);
            out.println("</option>");
        }
        out.println("</select>");
        out.println("<input type='submit' value='Add' />");

        out.println("</form>");
        out.println("</p>");

        if (stmt.execute()) {

            ResultSet rs = stmt.getResultSet();
            out.println("<div style='text-align:left; float: clear;'>Or review an existing one:<br/></div>");

            while (rs.next()) {

                out.println("<div style='padding: 16px; display: inline; float: left;'>");
                out.println("<div>");
                out.println("<a href='" + req.getRequestURL() + "?resource=" + rs.getString(2)
                        + "' style='text-decoration: none'>");
                out.println("<img src='./images/crystal/misc.png' border='0' width='128' height='128'/><br/>");
                out.println(rs.getString(2));
                out.println("</a>");
                out.println("</div>");
                out.println("</div>");
            }

        } else {
            out.println("There currently are no saved processes.<br/>");
        }

        out.println("</div>");
        out.println("</body>");
        out.println("</html>");
    }

    public void showError(Exception exception, HttpServletResponse res) {

        PrintWriter out;
        try {
            out = res.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        System.out.println(exception);
        exception.printStackTrace();

        res.setContentType("text/html");

        out.println(
                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");

        out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">");
        out.println("<head>");

        out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>");
        out.println("<title>Oryx - Error</title>");
        out.println("</head>");

        out.println("<body>");
        out.println("<div style=\"text-align: center;\">");
        out.println("<img src='./images/crystal/error.png' style='padding-top: 200px;' width='128' height='128'/>");
        out.println("<p>" + exception.toString() + "</p>");
        out.println("<!-- ACTUAL ERROR: ");
        exception.printStackTrace(out);
        out.println(" -->");
        out.println("</div>");
        out.println("</body>");
        out.println("</html>");

        out.close();

    }
}