org.n52.wps.server.request.Request.java Source code

Java tutorial

Introduction

Here is the source code for org.n52.wps.server.request.Request.java

Source

/**
 * Copyright (C) 2007 - 2014 52North Initiative for Geospatial Open Source
 * Software GmbH
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * If the program is linked with libraries which are licensed under one of
 * the following licenses, the combination of the program with the linked
 * library is not considered a "derivative work" of the program:
 *
 *        Apache License, version 2.0
 *        Apache Software License, version 1.0
 *        GNU Lesser General Public License, version 3
 *        Mozilla Public License, versions 1.0, 1.1 and 2.0
 *        Common Development and Distribution License (CDDL), version 1.0
 *
 * Therefore the distribution of the program linked with libraries licensed
 * under the aforementioned licenses, is permitted by the copyright holders
 * if the distribution is compliant with both the GNU General Public
 * License version 2 and the aforementioned licenses.
 *
 * 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.
 */
package org.n52.wps.server.request;

import java.util.UUID;
import java.util.concurrent.Callable;

import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.response.Response;
import org.w3c.dom.Document;

/**
 * The client requests some operation from the server.
 * The request generates a unique reference based on the client, time and a count.
 * Not secure! Upcoming references are easily guessed or altered.
 * @see java.rmi.server.UID
 */
abstract public class Request implements Callable<Response> {

    protected CaseInsensitiveMap map = null;
    protected Document doc = null;
    protected static Logger LOGGER = LoggerFactory.getLogger(Request.class);
    protected UUID id = null;
    public static final String SUPPORTED_VERSION = "1.0.0";
    public static final String[] SUPPORTED_LANGUAGES = new String[] { "en-US" };

    /**
     * Create a Request based on a CaseInsensitiveMap as input (HTTP GET)
     * @param map The Map which holds the client input.
     */
    public Request(CaseInsensitiveMap map) throws ExceptionReport {
        super();
        this.map = map;
    }

    /**
     * Create a Request based on a Document as input (HTTP POST)
     * @param doc The Document which holds the client input.
     */
    public Request(Document doc) throws ExceptionReport {
        super();
        this.doc = doc;
    }

    /**
     * Returns the user input in Document form
     * @return Document || null if Request(Map, outputstream) was used
     */
    public Document getDocument() {
        return doc;
    }

    /**
     * Returns the user input in Map form
     * @return Map || null if Request(Document, OutputStream) was used
     */
    public CaseInsensitiveMap getMap() {
        return map;
    }

    /**
     * Retrieve a value from an input-map with a lookup-key
     * @param key The lookup-key
     * @param map The input-map to look in
     * @param required If the key-value pair must be in the map.
     * @return The value of the key-value pair
     */
    public static String getMapValue(String key, CaseInsensitiveMap map, boolean required) throws ExceptionReport {
        if (map.containsKey(key)) {
            return ((String[]) map.get(key))[0];
        } else if (!required) {
            LOGGER.warn("Parameter <" + key + "> not found.");
            return null;
        } else {
            //Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
            throw new ExceptionReport("Parameter <" + key + "> not specified.",
                    ExceptionReport.MISSING_PARAMETER_VALUE, key);
        }
    }

    /**
     * Retrieve a value from an input-map with a lookup-key
     * @param key The lookup-key
     * @param map The input-map to look in
     * @param required If the key-value pair must be in the map.
     * @return The value of the key-value pair
     */
    public static String getMapValue(String key, CaseInsensitiveMap map, boolean required, String[] supportedValues)
            throws ExceptionReport {
        if (map.containsKey(key)) {

            String value = ((String[]) map.get(key))[0];

            for (String string : supportedValues) {
                if (string.equalsIgnoreCase(value)) {
                    return value;
                }
            }
            throw new ExceptionReport("Invalid value for parameter <" + key + ">.",
                    ExceptionReport.INVALID_PARAMETER_VALUE, key);
        } else if (!required) {
            LOGGER.warn("Parameter <" + key + "> not found.");
            return null;
        } else {
            //Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
            throw new ExceptionReport("Parameter <" + key + "> not specified.",
                    ExceptionReport.MISSING_PARAMETER_VALUE, key);
        }
    }

    /**
     * Retrieve an array of values from an input-map with a lookup-key
     * @param key The lookup-key
     * @param map The input-map to look in
     * @param required If the key-value pair must be in the map.
     * @return The array of values of the key-value pair
     */
    public static String[] getMapArray(String key, CaseInsensitiveMap map, boolean required)
            throws ExceptionReport {
        if (map.containsKey(key)) {
            return (String[]) map.get(key);
        } else if (!required) {
            LOGGER.warn("Parameter <" + key + "> not found.");
            return null;
        } else {
            //Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
            throw new ExceptionReport("Parameter <" + key + "> not specified.",
                    ExceptionReport.MISSING_PARAMETER_VALUE, key);
        }
    }

    /**
     * Retrieve a value from the client-input-map with a lookup-key
     * @param The lookup-key
     * @return The value of the key-value pair
     */
    protected String getMapValue(String key, boolean required) throws ExceptionReport {
        return Request.getMapValue(key, this.map, required);
    }

    /**
     * Retrieve a value from the client-input-map with a lookup-key
     * @param The lookup-key
     * @return The value of the key-value pair
     */
    protected String getMapValue(String key, boolean required, String[] supportedValues) throws ExceptionReport {
        return Request.getMapValue(key, this.map, required, supportedValues);
    }

    /**
     * Retrieve an array of values from the client-input-map with a lookup-key
     * @param The lookup-key
     * @return The array of values of the key-value pair
     */
    protected String[] getMapArray(String key, boolean required) throws ExceptionReport {
        return Request.getMapArray(key, this.map, required);
    }

    /**
     * Returns the version that the client requested.
     * @return An array of versions that are compatible with the client 
     */
    protected String[] getRequestedVersions(boolean mandatory) throws ExceptionReport {
        return getMapArray("version", mandatory);

    }

    /**
     * The process (request) on the server could require a specific version on the client
     * @param version The version that is required on the client
     * @return True if the required version matches, False otherwise.
     */
    public boolean requireVersion(String version, boolean mandatory) throws ExceptionReport {
        String[] versions = getRequestedVersions(mandatory);
        if (mandatory && versions == null) {
            //Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
            throw new ExceptionReport("Parameter <version> not specified.", ExceptionReport.MISSING_PARAMETER_VALUE,
                    "version");
        } else if (versions == null && !mandatory) {
            return true;
        }
        for (String v : versions) {
            //remove possible blanks
            if (v.trim().equals(version)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Accumulates the Strings in an array, separated by ", " (without quotes).
     * @param strings The array to accumulate
     * @return The accumulated String
     */
    public static String accumulateString(String[] strings) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < strings.length; i++) {
            String s = strings[i];
            if (!(i == strings.length - 1)) {
                sb.append(s + ", ");
            } else {
                sb.append(s);
            }
        }
        return sb.toString();
    }

    public UUID getUniqueId() {
        if (id == null) {
            this.id = UUID.randomUUID();
        }
        return id;
    }

    /**
     * Checks, if the language is supported by the WPS.
     * The language parameter is optional, however, if a wrong language is requested, 
     * an ExceptionReport has to be returned to the client.
     * 
     * See https://bugzilla.52north.org/show_bug.cgi?id=905.
     * 
     * @param language The language to be checked.
     * @throws ExceptionReport If a wrong language is requested, this ExceptionReport will be returned to the client.
     */
    public static void checkLanguageSupported(String language) throws ExceptionReport {

        for (String supportedLanguage : SUPPORTED_LANGUAGES) {
            if (supportedLanguage.equals(language)) {
                return;
            }
        }
        throw new ExceptionReport("The requested language " + language + " is not supported",
                ExceptionReport.INVALID_PARAMETER_VALUE, "language");
    }

    abstract public Object getAttachedResult();

    /**
     * After creation a Request is handled. This is done by calling this method.
     * This handling could contain a lot of computations. These computations should
     * be called from within this method.
     * @return A Response to the client Request
     * @see java.util.concurrent.Callable#call()
     */
    abstract public Response call() throws ExceptionReport;

    /**
     * There should be some validation required on the (input of the) clients Request.
     * @return True if the clients Request can be handled without problems, False otherwise
     */
    abstract public boolean validate() throws ExceptionReport;

}