com.aliasi.demo.framework.DemoServlet.java Source code

Java tutorial

Introduction

Here is the source code for com.aliasi.demo.framework.DemoServlet.java

Source

/*
 * LingPipe v. 4.1.0
 * Copyright (C) 2003-2011 Alias-i
 *
 * This program is licensed under the Alias-i Royalty Free License
 * Version 1 WITHOUT ANY WARRANTY, without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the Alias-i
 * Royalty Free License Version 1 for more details.
 *
 * You should have received a copy of the Alias-i Royalty Free License
 * Version 1 along with this program; if not, visit
 * http://alias-i.com/lingpipe/licenses/lingpipe-license-1.txt or contact
 * Alias-i, Inc. at 181 North 11th Street, Suite 401, Brooklyn, NY 11211,
 * +1 (718) 290-9170.
 */

package com.aliasi.demo.framework;

import com.aliasi.util.Streams;

import com.aliasi.xml.SAXWriter;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;

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

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * The <code>DemoServlet</code> class provides a servlet interface
 * to streaming demos.  The demo servlet presents demos in three
 * ways: web form, file upload and web service, each with its own
 * method of transmitting property information.
 *
 * <p>See the Web demo instructions for more information on using
 * this class.</p>
 *
 * @author  Bob Carpenter
 * @version 2.3.0
 * @since   LingPipe2.3
 */
public class DemoServlet extends HttpServlet {

    static final long serialVersionUID = 6980095913648079890L;

    private StreamDemo mDemo;

    /**
     * Construct a demo servlet.
     */
    public DemoServlet() {
    }

    /**
     * Initialize the demo servlet.  This is the initialization
     * called by the servlet container.  It constructs the
     * demo using reflection given the parameters.
     */
    public void init() throws ServletException {
        String demoClass = getInitParameter("demoConstructor");
        String demoConstructorArgs = getInitParameter("demoConstructorArgs");

        try {
            mDemo = Constants.constructDemo(demoClass, demoConstructorArgs);
        } catch (IllegalArgumentException e) {
            String msg = "Error constructing demo=" + e;
            throw new ServletException(e);
        } catch (ClassCastException e) {
            String msg = "Could not convert class=" + demoClass + " to instance of StreamDemo.";
            throw new ServletException(e);
        }
    }

    /**
     * Destroys this demo by null-ing out the resources used.
     */
    public void destroy() {
        mDemo = null;
    }

    /**
     * Handles <code>GET</code> requests by deferring them
     * to <code>POST</code> requests.
     *
     * @param request Servlet equest.
     * @param response Servlet response.
     * @throws IOException If there is an underlying I/O error.
     * @throws ServletException If there is an underlying servlet
     * error.
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        doPost(request, response);
    }

    /**
     * Handles <code>POST</code> requests.  First it determines what
     * type of demo is involved by looking at the path information.
     * If the extension is <code>/textInput.html</code>, it generates
     * the input form for the text input demo.  If the extension is
     * <code>/fileInput.html</code>, it generates the input form for
     * file upload.  If neither extension is present, it generates
     * the output for the demo, based on the properties determined
     * from the input.
     *
     * @param request Servlet equest.
     * @param response Servlet response.
     * @throws IOException If there is an underlying I/O error.
     * @throws ServletException If there is an underlying servlet
     * error.
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        String pathInfo = request.getPathInfo();
        if (pathInfo.equals("/response.xml")) {
            generateOutput(request, response);
        } else if (pathInfo.equals("/textInput.html")) {
            generateInputForm(request, response, true);
        } else if (pathInfo.equals("/fileInput.html")) {
            generateInputForm(request, response, false);
        }
    }

    void generateOutput(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        InputStream in = null;
        OutputStream out = null;

        try {
            response.setContentType(mDemo.responseType());
            out = response.getOutputStream();

            @SuppressWarnings("unchecked") // bad inherited API from commons
            Properties properties = mapToProperties((Map<String, String[]>) request.getParameterMap());

            String reqContentType = request.getContentType();

            if (reqContentType == null || reqContentType.startsWith("text/plain")) {

                properties.setProperty("inputType", "text/plain");
                String reqCharset = request.getCharacterEncoding();
                if (reqCharset != null)
                    properties.setProperty("inputCharset", reqCharset);
                in = request.getInputStream();

            } else if (reqContentType.startsWith("application/x-www-form-urlencoded")) {

                String codedText = request.getParameter("inputText");
                byte[] bytes = codedText.getBytes("ISO-8859-1");
                in = new ByteArrayInputStream(bytes);

            } else if (ServletFileUpload.isMultipartContent(new ServletRequestContext(request))) {

                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload uploader = new ServletFileUpload(factory);
                @SuppressWarnings("unchecked") // bad commons API
                List<FileItem> items = (List<FileItem>) uploader.parseRequest(request);
                Iterator<FileItem> it = items.iterator();
                while (it.hasNext()) {
                    log("found item");
                    FileItem item = it.next();
                    if (item.isFormField()) {
                        String key = item.getFieldName();
                        String val = item.getString();
                        properties.setProperty(key, val);
                    } else {
                        byte[] bytes = item.get();
                        in = new ByteArrayInputStream(bytes);
                    }
                }

            } else {
                System.out.println("unexpected content type");
                String msg = "Unexpected request content" + reqContentType;
                throw new ServletException(msg);
            }
            mDemo.process(in, out, properties);
        } catch (FileUploadException e) {
            throw new ServletException(e);
        } finally {
            Streams.closeQuietly(in);
            Streams.closeQuietly(out);
        }
    }

    private void generateInputForm(HttpServletRequest request, HttpServletResponse response, boolean isTextField)
            throws IOException, ServletException {

        OutputStream out = null;
        try {
            response.setContentType("text/html");
            out = response.getOutputStream();
            String charset = mDemo.defaultProperties().getProperty("Input Character Encoding");
            if (charset == null) {
                charset = "UTF-8";
            }
            SAXWriter saxWriter = new SAXWriter(out, charset, XHTML_MODE);
            saxWriter.setDTDString(XHTML_DTD_STRING);
            saxWriter.startDocument();
            Attributes htmlAtts = SAXWriter.createAttributes("xmlns", "http://www.w3.org/1999/xhtml", "xml:lang",
                    "en");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("html", htmlAtts);

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("head");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("title");
            saxWriter.characters(mDemo.title());
            saxWriter.endSimpleElement("title");

            saxWriter.characters("\n");
            Attributes httpAtts = SAXWriter.createAttributes("http-equiv", "Content-type", "content",
                    "application/xhtml+xml; charset=" + charset);
            saxWriter.startEndSimpleElement("meta", httpAtts);

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("style", "type", "text/css");
            saxWriter.characters("\n");
            saxWriter.characters(CSS_STYLE);
            saxWriter.characters("\n");
            saxWriter.endSimpleElement("style");
            saxWriter.characters("\n");
            saxWriter.endSimpleElement("head");

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("body");

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("div", "id", "header");

            Attributes logoAtts = SAXWriter.createAttributes("href", "http://alias-i.com", "id", "logo");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("a", logoAtts);
            Attributes imgAtts = SAXWriter.createAttributes("src",
                    "http://alias-i.com/lingpipe/web/img/logo-small.gif", "alt", "Alias-i Logo");
            saxWriter.startSimpleElement("img", imgAtts);
            saxWriter.endSimpleElement("img");
            saxWriter.endSimpleElement("a");

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("h1", "id", "pageTitle");
            saxWriter.characters(mDemo.title());
            saxWriter.endSimpleElement("h1");

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("div"); // id=header

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("h2", "id", "poweredBy");
            saxWriter.characters("Powered by ");
            saxWriter.startSimpleElement("a", "href", "http://alias-i.com/lingpipe");
            saxWriter.characters("LingPipe");
            saxWriter.endSimpleElement("a");
            saxWriter.endSimpleElement("h2");

            String[] lines = mDemo.description().split("\n");
            if (lines.length > 0) {
                saxWriter.characters("\n");
                saxWriter.startSimpleElement("div", "id", "description");
                for (int i = 0; i < lines.length; ++i) {
                    saxWriter.characters("\n");
                    saxWriter.startSimpleElement("p");
                    if (i == 0) {
                        saxWriter.startSimpleElement("b");
                        saxWriter.characters("This Demo:");
                        saxWriter.endSimpleElement("b");
                    }
                    saxWriter.characters(" ");
                    saxWriter.characters(lines[i]);
                    saxWriter.endSimpleElement("p");
                }
                saxWriter.characters("\n");
                saxWriter.endSimpleElement("div");
            }

            String actionPath = request.getContextPath() + request.getServletPath() + "/response.xml";

            Attributes formAtts = isTextField ? SAXWriter.createAttributes("method", "post", "action", actionPath)
                    : SAXWriter.createAttributes("method", "post", "action", actionPath, "enctype",
                            "multipart/form-data");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("form", formAtts);

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("div", "id", "license");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("p");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("b");
            saxWriter.characters("Terms of Use:");
            saxWriter.endSimpleElement("b");
            saxWriter.characters(" This demo is for evaluation purposes only.");
            saxWriter.characters(" Please do not overload our demo server. ");
            saxWriter.startSimpleElement("a", "href", "http://alias-i.com/lingpipe/web/contact.html");
            saxWriter.characters("Contact Alias-i");
            saxWriter.endSimpleElement("a");
            saxWriter.characters(" about other uses.");
            saxWriter.endSimpleElement("p");
            saxWriter.endSimpleElement("div"); // license

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("div", "id", "input");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("h4");
            saxWriter.characters((isTextField ? "Text" : "File") + " Input");
            saxWriter.endSimpleElement("h4");

            if (isTextField) {
                Attributes textAreaAtts = SAXWriter.createAttributes("name", "inputText", "rows", "12", "cols",
                        "60");
                saxWriter.characters("\n");
                saxWriter.startEndSimpleElement("textarea", textAreaAtts);

            } else {
                Attributes fileUploadAtts = SAXWriter.createAttributes("type", "file", "name", "inputFile", "size",
                        "50%", "id", "fileUpload");
                saxWriter.characters("\n");
                saxWriter.startEndSimpleElement("input", fileUploadAtts);
            }

            saxWriter.characters("\n");
            saxWriter.startEndSimpleElement("br");

            Attributes inputAtts = isTextField
                    ? SAXWriter.createAttributes("type", "submit", "value", "Submit Text", "id", "submitButton",
                            "title", "Click to analyze input text.")
                    : SAXWriter.createAttributes("type", "submit", "value", "Submit File", "id", "submitButton",
                            "title", "Click to upload and analyze selected file.");
            saxWriter.characters("\n");
            saxWriter.startEndSimpleElement("input", inputAtts);

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("span", "id", "switch");
            saxWriter.characters("(or switch to:");
            if (isTextField) {
                saxWriter.startSimpleElement("a", "href", "fileInput.html");
                saxWriter.characters("File Input Form");
            } else {
                saxWriter.startSimpleElement("a", "href", "textInput.html");
                saxWriter.characters("Text Input Form");
            }
            saxWriter.endSimpleElement("a");
            saxWriter.characters(")");
            saxWriter.endSimpleElement("span");

            if (!isTextField) {
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
                saxWriter.startEndSimpleElement("br");
            }

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("div");

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("div", "id", "params");

            Map<String, String[]> propertyDeclarations = mDemo.propertyDeclarations();
            Iterator<Map.Entry<String, String[]>> entryIt = propertyDeclarations.entrySet().iterator();
            while (entryIt.hasNext()) {
                Map.Entry<String, String[]> entry = entryIt.next();
                String key = entry.getKey();
                String[] vals = entry.getValue();
                String toolTip = mDemo.propertyToolTips().get(key);
                saxWriter.characters("\n");
                saxWriter.startSimpleElement("h4");
                saxWriter.characters(key);
                saxWriter.endSimpleElement("h4");
                if (vals.length > 1) {
                    Attributes selectAtts = (toolTip != null)
                            ? SAXWriter.createAttributes("name", key, "title", toolTip)
                            : SAXWriter.createAttributes("name", key);
                    saxWriter.characters("\n");
                    saxWriter.startSimpleElement("select", selectAtts);
                    for (int i = 0; i < vals.length; ++i) {
                        saxWriter.characters("\n");
                        saxWriter.startSimpleElement("option", "value", vals[i]);
                        saxWriter.characters(vals[i]);
                        saxWriter.endSimpleElement("option");
                    }
                    saxWriter.characters("\n");
                    saxWriter.endSimpleElement("select");
                } else {
                    Attributes paramInputAtts = (vals.length == 1)
                            ? SAXWriter.createAttributes("type", "text", "name", key, "value", vals[0])
                            : SAXWriter.createAttributes("type", "text", "name", key);
                    saxWriter.characters("\n");
                    saxWriter.startEndSimpleElement("input", paramInputAtts);
                }
            }

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("div");

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("form");

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("div", "id", "footInstructions");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("div", "id", "instructions");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("h3");
            saxWriter.characters("General Web Demo Instructions");
            saxWriter.endSimpleElement("h3");

            saxWriter.characters("\n");
            saxWriter.startSimpleElement("ul");
            writeItems(GENERAL_WEB_INSTRUCTIONS, saxWriter);
            if (isTextField)
                writeItems(TEXT_WEB_INSTRUCTIONS, saxWriter);
            else
                writeItems(FILE_WEB_INSTRUCTIONS, saxWriter);

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("ul");

            saxWriter.startSimpleElement("h3");
            saxWriter.characters("For more info: ");
            saxWriter.startSimpleElement("a", "href", "http://alias-i.com/web/lingpipe/demos.html");
            saxWriter.characters("Complete LingPipe Demo Instructions");
            saxWriter.endSimpleElement("a");
            saxWriter.endSimpleElement("h3");

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("div"); // instructions

            Map<String, String> modelToResource = mDemo.modelToResource();
            Map<String, String> tutorialToUrl = mDemo.tutorialToUrl();

            if ((modelToResource.size() > 0) || (tutorialToUrl.size() > 0)) {

                saxWriter.characters("\n");
                saxWriter.startSimpleElement("div", "id", "resources");

                saxWriter.characters("\n");
                saxWriter.startSimpleElement("h3");
                saxWriter.characters("Related LingPipe Resources");
                saxWriter.endSimpleElement("h3");

                if (tutorialToUrl.size() > 0) {
                    saxWriter.characters("\n");
                    saxWriter.startSimpleElement("h4");
                    saxWriter.characters("Tutorials");
                    saxWriter.endSimpleElement("h4");

                    saxWriter.characters("\n");
                    saxWriter.startSimpleElement("ul");
                    Iterator<Map.Entry<String, String>> it = tutorialToUrl.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry<String, String> entry = it.next();
                        String tutorialName = entry.getKey();
                        String tutorialUrl = entry.getValue();
                        saxWriter.characters("\n");
                        saxWriter.startSimpleElement("li");
                        saxWriter.startSimpleElement("a", "href", tutorialUrl);
                        saxWriter.characters(tutorialName);
                        saxWriter.endSimpleElement("a");
                        saxWriter.endSimpleElement("li");
                    }
                    saxWriter.characters("\n");
                    saxWriter.endSimpleElement("ul");
                }

                if (modelToResource.size() > 0) {
                    saxWriter.characters("\n");
                    saxWriter.startSimpleElement("h4");
                    saxWriter.characters("Models");
                    saxWriter.endSimpleElement("h4");

                    saxWriter.characters("\n");
                    saxWriter.startSimpleElement("ul");
                    Iterator<Map.Entry<String, String>> it = modelToResource.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry<String, String> entry = it.next();
                        String modelName = entry.getKey();
                        String modelResourcePath = entry.getValue();
                        saxWriter.characters("\n");
                        saxWriter.startSimpleElement("li");
                        saxWriter.startSimpleElement("a", "href", "../resource" + modelResourcePath);
                        saxWriter.characters(modelName);
                        saxWriter.endSimpleElement("a");
                        saxWriter.endSimpleElement("li");
                    }
                    saxWriter.characters("\n");
                    saxWriter.endSimpleElement("ul");
                }

                saxWriter.characters("\n");
                saxWriter.endSimpleElement("div"); // resources
            }

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("div"); // footInstructions

            //Allows Google Analytics to track site usage
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("script", "type", "text/javascript");
            saxWriter.characters("\n");
            saxWriter.characters(
                    "var gaJsHost = ((\'https:\' == document.location.protocol) ? \'https://ssl.\' : \'http://www.\');\n"
                            + "document.write(unescape(\'%3Cscript src=\'\' + gaJsHost + \'google-analytics.com/ga.js\' type=\'text/javascript\'%3E%3C/script%3E\'));\n");
            saxWriter.endSimpleElement("script");
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("script", "type", "text/javascript");
            saxWriter.characters("\n");
            saxWriter.characters(
                    "try var pageTracker = _gat._getTracker(\'UA-15123726-1\'); pageTracker._trackPageview(); } catch(err) {}\n");

            saxWriter.endSimpleElement("script");
            saxWriter.characters("\n");

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("body");

            saxWriter.characters("\n");
            saxWriter.endSimpleElement("html");
            saxWriter.endDocument();
        } catch (SAXException e) {
            throw new ServletException(e);
        } finally {
            Streams.closeQuietly(out);
        }
    }

    static void writeItems(String text, SAXWriter saxWriter) throws SAXException {

        String[] paragraphs = text.split("\n");
        for (int i = 0; i < paragraphs.length; ++i) {
            saxWriter.characters("\n");
            saxWriter.startSimpleElement("li");
            saxWriter.characters("\n");
            saxWriter.characters(paragraphs[i]);
            saxWriter.characters("\n");
            saxWriter.endSimpleElement("li");
        }
    }

    private Properties mapToProperties(Map<String, String[]> map) {
        Properties reqProperties = new Properties(mDemo.defaultProperties());
        Iterator<Map.Entry<String, String[]>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String[]> entry = it.next();
            String key = entry.getKey();
            String[] vals = entry.getValue();
            if (vals == null || vals.length == 0)
                continue;
            reqProperties.setProperty(key, vals[0]);
        }
        return reqProperties;
    }

    static final boolean XHTML_MODE = true;

    private static final String XHTML_DTD_STRING = "<!DOCTYPE html" + " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
            + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";

    private static final String GENERAL_WEB_INSTRUCTIONS = "Set the web browser's character encoding based on the encoding of text to be submitted (Use browser menu=View, submenu=Encoding)."
            + "\n" + "Set the input character encoding to match the actual encoding of the input bytes." + "\n"
            + "Set the input type selection to match the type of the input, either plain text, HTML or XML." + "\n"
            + "Set the output character encoding to any value; it need not match the input character set or browser.";

    private static final String TEXT_WEB_INSTRUCTIONS = "Cut-and-paste or enter text in the specified character encoding."
            + "\n"
            + "To analyze a file, first switch to the file input form, the link for which is next to the submit button.";

    private static final String FILE_WEB_INSTRUCTIONS = "Files may be analyzed by entering an absolute path to them in the file input field."
            + " They may also be selected by clicking on the browse button and opening the desired file."
            + " This will write its absolute path into the input field."
            + " Use the submit button to upload the file for analysis." + "\n"
            + "To analyze direct text input, first switch to the text input form, the link for which is next to the submit button.";

    private static final String CSS_STYLE = "* { margin: 0; padding: 0; font-family: verdana, arial, sans-serif; background-color: #DDD; border: none; font-size: 1em; }"
            + "\n"
            + "#header {background-color: #272651; padding: 0; color: #272651; margin: 0 0 1px 0; border: 15px solid #DDD; border-top: 1em solid #DDD; border-left: 1.15em solid #DDD; border-bottom: 1px solid #DDD; }"
            + "\n"
            + "h1#pageTitle { font-size: 1.5em; color: #EEE; background-color: #272651; padding: 0.75em 0 .75em .333em; }"
            + "\n" + "a#logo { float: right; display: inline; padding: 1em 1em 0 0; background-color: #272651; }"
            + "\n" + "h2 { font-size: 1em; }" + "\n"
            + "h2#poweredBy { float: right; font-size: 0.8em; font-weight: normal; background-color: #272651; color: #EEE; margin: 0; padding: 1em 1.5em; border: 15px solid #DDD; border-top: none }"
            + "\n"
            + "h2#poweredBy a { font-size: 1.5em; font-weight: normal; background-color: #272651; color: #F7EB00; }"
            + "\n" + "h3 { font-size: 1em; margin: 1.0em; }" + "\n" + "h4 { font-size: 0.8em; margin: .25em 0; }"
            + "\n"
            + "#description p { width: 100%; margin-bottom: 0.25em; padding: 0.5em; background-color: #EEE; border: 1px solid #888; font-size: 0.75em;  overflow:hidden }"
            + "\n" + "#description p b { background-color: #EEE; }" + "\n"
            + "#description { width: 30em; padding: 1.15em 0.75em 1.15em 1.15em; line-height: 140%; }" + "\n"
            + "#license { clear: both; width: 30em; padding: 0em 0.75em 1.15em 1.15em; line-height: 140%; }" + "\n"
            + "#license p { width: 100%; margin-bottom: 0.25em; padding: 0.75em 0.5em; background-color: #EEE; border: 1px solid #888; font-size: 0.75em;  overflow:hidden }"
            + "\n" + "#license p b { background-color: #EEE; }" + "\n" + "#license p a { background-color: #EEE; }"
            + "\n" + "#input { float: left; width: 30em; padding: 1.15em .75em 1.15em 1.15em; }" + "\n"
            + "#input textarea { width: 100%; margin-bottom: 0.25em; padding: 0.5em; background-color: #FFF; border: 1px solid #888; font-size: 0.8em;  overflow:hidden }"
            + "\n"
            + "#input #fileUpload { margin-bottom: 0.25em; padding: 0.5em; background-color:#FFF; border: 1px solid black; font-size: 0.8em; }"
            + "\n"
            + "#input #submitButton { float: left; font-size: 0.8em; font-weight: bold; padding: 0.5em; margin-bottom: 1.5em; background-color: #FFF; border: 1px solid #888; }"
            + "\n" + "#switch { font-weight: normal; font-size: .8em; float: right; text-align: right; }" + "\n"
            + "#params { padding-top: 1.75em; padding-left: 3em; margin-left: 30em; }" + "\n"
            + "#params h4 { margin: 1em 0 .1em 0; padding: 0; }" + "\n"
            + "#params select { font-size: 0.9em;  background-color: #EEE; border: 1px solid #333; padding: 0;  }"
            + "\n" + "#params input { font-size: 0.9em;  background-color: #EEE; border: 1px solid #888; }" + "\n"
            + "#footInstructions { clear: both; float: left; width: 30em; padding: 1.15em 0.75em 1.15em 1.15em; }"
            + "\n"
            + "#instructions { width: 100%; margin-bottom: 0.25em; padding: 0.5em; background-color: #EEE; border: 1px solid #888; font-size: 0.8em;  overflow:hidden }"
            + "\n"
            + "#instructions h3 { font-weight: bold; margin: 0em 1em 0 0.5em; background: #EEE; padding-top: 0.75em; }"
            + "\n" + "#instructions ul { margin: 0 1.5em 0.5em 2.0em; background: #EEE; }" + "\n"
            + "#instructions ul li { margin: 0.75em 0 0 0; background: #EEE; }" + "\n"
            + "#resources { width: 100%; margin-bottom: 0.25em; margin-top: 1em; padding: 0.5em; background-color: #EEE; border: 1px solid #888; font-size: 0.8em;  overflow:hidden }"
            + "\n" + "#resources h3 { font-size: 1em; background: #EEE; margin: 0; padding: 0.5em 0.5em; }" + "\n"
            + "#instructions a { background: #EEE; }" + "\n"
            + "#resources h4 { font-size: 0.9em;  margin: 0; padding: 0.5em 0.5em 0 0.5em; background-color: #EEE; }"
            + "\n" + "#resources ul { margin: 0 1.5em 0.5em 2.0em; background: #EEE; }" + "\n"
            + "#resources ul li { margin: 0.5em 0 0 0; background: #EEE; }" + "\n"
            + "#resources ul li a { background: #EEE; font-size: 0.9em; }" + "\n";

}