Package pspdash

Source Code of pspdash.TinyCGIBase

// PSP Dashboard - Data Automation Tool for PSP-like processes
// Copyright (C) 2003 Software Process Dashboard Initiative
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// The author(s) may be contacted at:
// OO-ALC/TISHD
// Attn: PSP Dashboard Group
// 6137 Wardleigh Road
// Hill AFB, UT 84056-5843
//
// E-Mail POC:  processdash-devel@lists.sourceforge.net


package pspdash;

import pspdash.data.DataRepository;
import pspdash.data.SimpleData;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

public class TinyCGIBase implements TinyCGI {

    static String DEFAULT_CHARSET = "ISO-8859-1";

    protected InputStream inStream = null;
    protected OutputStream outStream = null;
    protected PrintWriter out = null;
    protected Map env = null;
    protected Map parameters = new HashMap();
    protected String charset = DEFAULT_CHARSET;

    public void service(InputStream in, OutputStream out, Map env)
        throws IOException
    {
        this.inStream = in;
        this.outStream = out;
        this.out = new PrintWriter(new OutputStreamWriter(outStream, charset));
        this.env = env;
        parameters.clear();
        parseInput((String) env.get("QUERY_STRING"));
        if ("POST".equalsIgnoreCase((String) env.get("REQUEST_METHOD")))
            doPost();
        else
            doGet();
        this.out.flush();
    }

    /** Parse CGI query parameters, and store them in the Map
     *  <code>parameters</code>.
     *
     * Single valued parameters can be fetched directly from the map.
     * Multivalued parameters are stored in the map as String arrays,
     * with "_ALL" appended to the name.  (So a query string
     * "name=foo&name=bar" would result in a 2-element string array
     * being placed in the map under the key "name_ALL".)
     */
    protected void parseInput(String query) throws IOException {
        if (query == null || query.length() == 0) return;

        String delim = (query.indexOf('\n') == -1) ? "&" : "\r\n";
        StringTokenizer params = new StringTokenizer(query, delim);
        String param, name, val;
        int equalsPos;
        while (params.hasMoreTokens()) {
            param = params.nextToken();
            equalsPos = param.indexOf('=');
            if (equalsPos == 0 || param.length() == 0)
                continue;
            else if (equalsPos == -1)
                parameters.put(URLDecoder.decode(param), Boolean.TRUE);
            else try {
                name = URLDecoder.decode(param.substring(0, equalsPos));
                val = param.substring(equalsPos+1);
                // skip URL decoding if the value begins with "=".  This
                // saves us from having to URL-encode complex expressions
                // in query files.
                if (val.startsWith("=")) val = val.substring(1);
                else val = URLDecoder.decode(val);
                if (supportQueryFiles() && QUERY_FILE_PARAM.equals(name))
                    parseInputFile(val);
                else
                    putParam(name, val);
            } catch (Exception e) {
                System.err.println("Malformed query parameter: " + param);
            }
        }
    }
    public static final String QUERY_FILE_PARAM = "qf";

    private void putParam(String name, String val) {
        parameters.put(name, val);
        name = name + "_ALL";
        parameters.put
            (name, append((String[]) parameters.get(name), val));
    }

    /* Read name=value pairs from POSTed form data. */
    protected void parseFormData() throws IOException {
        int length;
        try {
            length = Integer.parseInt((String) env.get("CONTENT_LENGTH"));
        } catch (Exception e) { return; }

        byte [] messageBody = new byte[length];
        int bytesRead = inStream.read(messageBody);
        parseInput(new String(messageBody, 0, bytesRead));
    }

    /* Read name=value pairs, and uploaded files, from multipart form data.
     *
     * For each uploaded file with parameter name "foo", the following
     * entries will appear in the parameter list:<ul>
     * <li>foo - the name of the uploaded file.
     * <li>foo_SIZE - the size of the uploaded file (a Long).
     * <li>foo_TYPE - the content type of the uploaded file
     * <li>foo_CONTENTS - the contents of the uploaded file (byte[]).
     * </ul>
     */
    protected void parseMultipartFormData() throws IOException {
        String contentType = (String) env.get("CONTENT_TYPE");
        int contentLength;
        try {
            contentLength =
                Integer.parseInt((String) env.get("CONTENT_LENGTH"));
        } catch (Exception e) { return; }

        try {
            // Parse the incoming multipart form data. This may throw
            // an IllegalArgumentException if the incoming data is not
            // multipart/form data.
            MultipartRequest req = new MultipartRequest
                (new PrintWriter(System.out), contentType, contentLength,
                 inStream, MultipartRequest.MAX_READ_BYTES);

            // copy the name/value pairs from the request into our
            // list of parameters.
            Enumeration parameterNames = req.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String name = (String) parameterNames.nextElement();
                Enumeration values = req.getURLParameters(name);
                while (values.hasMoreElements())
                    putParam(name, (String) values.nextElement());
            }

            // fetch all the files read, and store them into our
            // parameters map.
            parameterNames = req.getFileParameterNames();
            while (parameterNames.hasMoreElements()) {
                String name = (String) parameterNames.nextElement();
                parameters.put(name, req.getFileSystemName(name));
                parameters.put(name + "_SIZE",
                               req.getFileParameter(name, req.SIZE));
                parameters.put(name + "_TYPE",
                               req.getFileParameter(name, req.CONTENT_TYPE));
                parameters.put(name + "_CONTENTS",
                               req.getFileParameter(name, req.CONTENTS));
            }

        } catch (IllegalArgumentException iae) {
            parseFormData();
        }
    }


    /* Read name=value pairs from the given URI. If the URI is not
     * absolute (e.g. "/reports/foo"), it is interpreted relative
     * to the current request. */
    protected void parseInputFile(String filename) throws IOException {
        if (filename == null || filename.length() == 0) return;

        TinyWebServer t = getTinyWebServer();
        String origFilename = filename;
        String scriptPath = (String) env.get("SCRIPT_PATH");
        try {
            if (!filename.startsWith("/")) {
                URL context = new URL("http://unimportant" + scriptPath);
                URL file = new URL(context, filename);
                filename = file.getFile();
            }
            env.put("SCRIPT_PATH", filename);
            parseInput(new String(t.getRequest(filename, true), "UTF-8"));
        } catch (IOException ioe) {
            System.out.println("Couldn't read file: " + filename);
            System.out.println("(Specified as '" + origFilename + "' from '" +
                               scriptPath +"')");
        } finally {
            env.put("SCRIPT_PATH", scriptPath);
        }
    }

    public String resolveRelativeURI(String context, String uri) {
        if (uri == null || uri.startsWith("/") || uri.startsWith("http:"))
            return uri;

        try {
            if (!context.startsWith("http:"))
                context = "http://unimportant" + context;
            URL cntxt = new URL(context);
            URL file = new URL(cntxt, uri);
            return file.getFile();
        } catch (MalformedURLException mue) {
            return uri;
        }
    }
    public String resolveRelativeURI(String uri) {
        return resolveRelativeURI((String) env.get("REQUEST_URI"), uri);
    }

    private String[] append(String [] array, String element) {
        String [] result;
        result = new String[array == null ? 1 : array.length + 1];
        if (array != null)
            System.arraycopy(array, 0, result, 0, array.length);
        result[result.length-1] = element;
        return result;
    }

    protected String cssLinkHTML() {
        String style = (String) parameters.get("style");
        if (style == null)
            style = "/style.css";
        return "<LINK REL='stylesheet' TYPE='text/css' HREF='" + style + "'>";
    }


    /** Get the data repository servicing this request. */
    protected DataRepository getDataRepository() {
        return (DataRepository) env.get(DATA_REPOSITORY);
    }
    /** Get the tiny web server that is running this request. */
    protected TinyWebServer getTinyWebServer() {
        return (TinyWebServer) env.get(TINY_WEB_SERVER);
    }
    /** Get the PSPProperties object */
    protected PSPProperties getPSPProperties() {
        return (PSPProperties) env.get(PSP_PROPERTIES);
    }
    protected ObjectCache getObjectCache() {
        return (ObjectCache) env.get(OBJECT_CACHE);
    }
    /** Perform an internal http request. */
    protected byte[] getRequest(String uri, boolean skipHeaders)
        throws IOException {
        return getTinyWebServer().getRequest(uri, skipHeaders);
    }
    /** Fetch a named query parameter */
    protected String getParameter(String name) {
        return (String) parameters.get(name);
    }
    /** get the effective prefix, set via the URL */
    protected String getPrefix() {
        String result = (String) parameters.get("hierarchyPath");
        if (result == null)
            result = (String) env.get("PATH_TRANSLATED");
        else if (!result.startsWith("/")) {
            String prefix = (String) env.get("PATH_TRANSLATED");
            if (prefix == null)
                prefix = "";
            result = prefix + "/" + result;
        }
        return result;
    }
    /** get the name of the person who owns the data in the repository */
    protected String getOwner() {
        DataRepository data = getDataRepository();
        SimpleData val = data.getSimpleValue("/Owner");
        if (val == null) return null;
        String result = val.format();
        if ("Enter your name".equals(result))
            return null;
        else
            return result;
    }

    /** Does this CGI script want to support query parameter files?
     * child classes that DO NOT want query parameter support should
     * override this method to return false. */
    protected boolean supportQueryFiles() { return true; }


    /** Handle an HTTP POST request */
    protected void doPost() throws IOException {
        writeHeader();
        writeContents();
    }


    /** Handle an HTTP GET request */
    protected void doGet() throws IOException {
        writeHeader();
        writeContents();
    }


    /** Write a standard CGI header.
     *
     * This method can be overridden by children that might need to generate
     * a special header, or might need to vary the header on the fly.
     */
    protected void writeHeader() {
        out.print("Content-type: text/html; charset="+charset+"\r\n\r\n");
        // flush in case writeContents wants to use outStream instead of out.
        out.flush();
    }


    /** Generate CGI script output.
     *
     * This method should be overridden by child classes to generate
     * the contents of the script.
     */
    protected void writeContents() throws IOException {
        out.println("<HTML><BODY>");
        out.println("This space intentionally left blank.");
        out.println("</BODY></HTML>");
    }

    /** Set the default character set to be used for CGI output.
     *
     * If the parameter does not name a valid charset, this method
     * will do nothing.
     *
     * @param charsetName The name of a supported character encoding
     */
    static void setDefaultCharset(String charsetName) {
        if (charsetName != null && charsetName.length() > 0) try {
            "test".getBytes(charsetName);
            DEFAULT_CHARSET = charsetName;
        } catch (UnsupportedEncodingException uee) {}
    }

    /** Get the name of the default character set to be used for CGI output.
     */
    public static String getDefaultCharset() {
        return DEFAULT_CHARSET;
    }
}
TOP

Related Classes of pspdash.TinyCGIBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.