Package org.apache.tools.moo.servlet

Source Code of org.apache.tools.moo.servlet.ClientTest

/*
* $Header: /home/cvspublic/jakarta-tools/moo/src/share/org/apache/tools/moo/servlet/ClientTest.java,v 1.3 1999/10/21 18:42:01 arun Exp $
* $Date: 1999/10/21 18:42:01 $
* $Revision: 1.3 $
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement: 
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* @author Mandar Raje [mandar@eng.sun.com]
* @author Arun Jamwal [arunj@eng.sun.com]
*/
package org.apache.tools.moo.servlet;

import org.apache.tools.moo.*;
import org.apache.tools.moo.servlet.*;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLEncoder;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.io.File;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.lang.NullPointerException;
import java.io.OutputStream;
import java.io.PrintWriter;


/**
* ClientTest is the base class for all compatibility client tests
* They need to override runTest() as well as the description field
*/
public abstract class ClientTest
implements Testable {

    private MapManager mapManager = null;
    URL url = null;
    boolean useCookie = false;


    /**
     * returns a description of the client test.
     * This method needs to be overridden by the specific test
     */
    public abstract String
    getDescription();

    /**
     * returns the results of running the compatibility test in the form of a
     * TestResult object. 
     * This method needs to be overridden by the client
     */
    public abstract TestResult
    runTest();

    /**
     * establishes and returns an HTTP Connection (HTTP GET).
     * This method does not set any headers nor a query string
     */
    public HttpURLConnection
    getConnection()
    throws Exception {
        return getConnection(null, null, null, null);
    }

    /**
     * establishes and returns an HTTP Connection (HTTP GET).
     * This method does not set any headers nor a query string
     */
    public HttpURLConnection
    getConnection(boolean useCookie)
    throws Exception {
        this.useCookie = useCookie;
        return getConnection(null, null, null, null);
    }

    /**
     * establishes and returns an HTTP Connection with the HTTP method
     * set to method.  There are no user-defined headers, nor a query string
     */
    public HttpURLConnection
    getConnection(String method)
    throws Exception {
        return getConnection(null, null, null, method);
    }

    /**
     * establishes and returns an HTTP Connection with the HTTP method
     * set to method.  There are no user-defined headers, nor a query string
     */
    public HttpURLConnection
    getConnection(String method, boolean useCookie)
    throws Exception {
        this.useCookie = useCookie;
        return getConnection(null, null, null, method);
    }

    /**
     * establishes and returns an HTTP Connection (HTTP GET).
     * The headers arg should be set up with the keys as HTTP headers fields and
     * the values as string values.
     * This method does not set the query string
     */
    public HttpURLConnection
    getConnection (Hashtable headers)
    throws Exception {
        return getConnection(headers, null, null, null);
    }

    /**
     * establishes and returns an HTTP Connection (HTTP GET).
     * The headers arg should be set up with the keys as HTTP headers fields and
     * the values as string values.
     * This method does not set the query string
     */
    public HttpURLConnection
    getConnection (Hashtable headers, boolean useCookie)
    throws Exception {
        this.useCookie = useCookie;
        return getConnection(headers, null, null, null);
    }


    public HttpURLConnection
    getConnection(Hashtable headers, String query, String pathInfo, String method, boolean useCookie)
    throws Exception {
        this.useCookie = useCookie;
        return getConnection(headers, query, pathInfo, method);
    }
    /**
     * establishes and returns an HTTP Connection.
     * This connects to the value in the MapManager
     * This method sets the headers where the keys from the hashtable
     * are HTTP headers and the values the HTTP header values
     * The query string should be done the same way, where the values are a
     * java.util.Vector
     * The method argument is the request method to be used.  If it is null
     * this returns a connection with an HTTP GET
     * it must be one of the following strings: GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE
     */


    /**
     * This is the less-prefered method, but allows you to input query
     * string arguments as a string (allowing a key without a corresponding
     * value (ie http://localhost/servlet/mine?Hello)
     * thus it is called a different name to avoid ambiguity with the
     * parameters being passed in as nulls
     *
     * establishes and returns an HTTP Connection.
     * This connects to the value in the MapManager
     * This method sets the headers where the keys from the hashtable
     * are HTTP headers and the values the HTTP header values
     * The query string should be done the same way, where the values are a
     * java.util.Vector
     * The method argument is the request method to be used.  If it is null
     * this returns a connection with an HTTP GET
     * it must be one of the following strings: GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE
     */

    /**
     * Grandaddy of all calls
     * query is passed in as a query String (without the prepended ?)
     */
    public HttpURLConnection
    getConnection(Hashtable headers, String query, String pathInfo, String method)
    throws Exception {

        HttpURLConnection connection = null;
        String mapResource = this.getClass().getName();

        mapManager = MapManagerImpl.getMapManager();

        String testResource = mapManager.get(mapResource);
        //associated server-side class for the client

        if (testResource == null) {
            throw new NullPointerException("bad resource: " + mapResource
                                           + ".  Can't map client test to server test");
        }

        //opens an http connection to the server specified by the property
        //Main.hostName at the port specified by Main.portName to the file
        //located at testResource with the query-string query
        String queryAndPath = (pathInfo!=null ? "/"+pathInfo : "") +
                              (query!=null ? "?" + query : "");

        String toConnect = testResource + queryAndPath;

        url = URLHelper.getURL(toConnect);
        String host = url.getHost();
        String port = String.valueOf(url.getPort());
        String protocol = url.getProtocol();
        String file = url.getFile();

        try {
            connection = (HttpURLConnection)url.openConnection();
        } catch (IOException e) {
            out.println("Could not retrieve file " + file + " on " + host
                        + " on port number " + port + " via " + protocol + " protocol");
            throw e;
        }

        //set the request method
        if (method != null) {
            try {
                connection.setRequestMethod(method);
            }catch (ProtocolException e) {
                out.println("Method: " + method + " not valid for " + protocol);
                throw e;
            }//end catch
        } //end if

        //set cookie header
        if (this.useCookie == true)
            setCookieHeader(connection);

        //establish the headers
        doHeaders(headers, connection);

        //set general properties
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);
        connection.setFollowRedirects(false);

        //establish connection
        try {
            connection.connect();
        }catch (IOException e) {
            out.println("Could not establish a connection to file " + file
                        + " on " + host + " on port number " + port + " via "
                        + protocol + " protocol");
            throw e;
        } //end catch

        out.println("Connected to "+ url.toString());

        return connection;
    }


    /**
     * Takes in a hashtable, where the keys are the names of HTTP form fields
     * (must be in a java.lang.String object)
     * and the hashtable values are the HTTP form values (in a vector or a string),
     * and converts them into a string, which is returned
     *
     * If the value of the hashtable is not a vector (or a string), the key is ignored.
     * Likewise if the key is not a string
     *
     * if queryString is null, this returns the empty string, ""
     */
    public String doQueryString(Hashtable queryString) {
        if (queryString == null) return "";

        // assert: queryString not null
        // hold the querystring to be generated in sb
        StringBuffer sb = new StringBuffer();
        Enumeration keys = queryString.keys();

        while (keys.hasMoreElements()) {
            String key = (String)keys.nextElement();
            Object val = queryString.get(key);
            boolean isString = val instanceof String;
            boolean isVector = val instanceof Vector;
            String value;

            if (isString) {
                value = (String)val;
                sb.append( URLEncoder.encode(key) );
                sb.append( "=" );
                sb.append( URLEncoder.encode(value) );
            }

            else if (isVector) {
                Enumeration vals = ((Vector)val).elements();
                while (vals.hasMoreElements()) {
                    value = (String)vals.nextElement();
                    sb.append(URLEncoder.encode(key));
                    sb.append("=");
                    sb.append(URLEncoder.encode(value));
                }
            } //end else
            else continue;
            //next iteration -- don't really need this as this is the end of the while loop
        } //end while (keys ...

        return sb.toString();

    }


    private void setCookieHeader(HttpURLConnection connection) {
        String savedCookies =
          mapManager.getCookieJar().applyRelevantCookies(this.url);
        if (savedCookies != null) {
            connection.setRequestProperty("Cookie", savedCookies);
        }
    }

    private void saveCookies(HttpURLConnection connection) {
        String recvCookies = connection.getHeaderField("Set-Cookie");
        if (recvCookies != null) {
            Vector receivedCookies = new Vector();
            receivedCookies.addElement(recvCookies);
            mapManager.getCookieJar().recordAnyCookies(receivedCookies, this.url);
        }
    }

    /**
     * adds the headers from the headers Hashtable
     * (key=HTTP header, value=HTTP value)
     * to the connection
     *
     * if headers is null, this method leaves connection unchanged
     *
     * modifies: connection
     */
    private void doHeaders(Hashtable headers, HttpURLConnection connection) {
        if (headers != null) {
            Enumeration enum = headers.keys();

            while (enum.hasMoreElements()) {
                String key = (String)enum.nextElement();
                String value = (String)headers.get(key);

                if (key != null &
                        value != null) {
                    connection.setRequestProperty(key, value);
                } //end if
            } //end while
        } //end if
    } //end doHeaders



    /**
     * runs another test (ie a precursor to the current test)
     * this is used for example to set state on the server, then test
     * additional functionality with a later test
     *
     * if class does not exist, throw ClassNotFoundException
     * if the class is not an instance of moo.Testable, throw ClassCastException
     * if test passes, return a TestResult with status true
     * if test fails or throws an exception, return a TestResult with a false status
     *
     * @param testName  the fully-qualified class name of the test to run
     *                  must be an instance of org.apache.tools.moo.Testable
     *
     *
     * At some point, this may need to be edited, as the second test may need
     * access to the initial connection.  The reason for this is in setting a
     * session for example, when the second test needs to know which session id
     * was established by the first test.
     *
     */

    protected TestResult runAnotherTest(String testName)
    throws ClassNotFoundException, ClassCastException
    {
        Class c = Class.forName(testName);
        try {
            Testable test = (Testable)c.newInstance();
            return test.runTest();
        }
        catch (java.lang.IllegalAccessException e) {
            e.printStackTrace(new PrintStream(Logger.getLogger().getOutputStream()));
            return new TestResult(false, e.toString());
        }
        catch (java.lang.InstantiationException e) {
            e.printStackTrace(new PrintStream(Logger.getLogger().getOutputStream()));
            return new TestResult(false, e.toString());
        }
    }


    /**
     * requires: that the corresponding server returns a response in the
     * form of a properties file.  Additionally, there must be a key in the
     * properties file named Constants.Response.Status, which has a string
     * value of either "true" or "false".  If not, then false is returned. 
     * This mechanism may need to be extended.
     *
     * reads the response from the server as a properties file
     * it then checks the Constants.Response.Status property
     * to see if the test succeeded. 
     *
     * this should be called by the subclass client test's runTest() method.
     */
    public TestResult
    getTestResult (HttpURLConnection connection)
    throws Exception {
        TestResult testResult = new TestResult();
        Properties props = new Properties();

        //handle HTTP codes here
        int code = connection.getResponseCode();
        String message = connection.getResponseMessage();

        if (this.useCookie == true)
            saveCookies(connection);

        //http response in 400s signifies Client Request Incomplete/Doc Not found ...
        //http response in 500s signifies servlet error

        if (code >= 400) {
            testResult.setStatus(false);
            testResult.setMessage(message);
        }
        else { //assume request was OK

            props.load(connection.getInputStream());
            connection.disconnect();

            String statusStr =
              props.getProperty(Constants.Response.Status, "false");

            out.println("Response Status = " + statusStr);
            if(statusStr.equals("false"))
                out.println("Message: " + props.getProperty(Constants.Response.Message,""));

            testResult.setStatus(Boolean.valueOf(statusStr).booleanValue());
            testResult.setMessage(
              props.getProperty(Constants.Response.Message, ""));
        } //end else

        return testResult;
    }

    /**
     * this is called if the test results in an exception.
     * this should be called by the subclass client test' runTest() method.
     *
     * modifies: the status and message properties of testResult
     */
    public TestResult
    getTestResult (TestResult testResult, Exception e) {
        if (testResult == null) {
            testResult = new TestResult();
        }

        testResult.setStatus(false);
        testResult.setMessage(this.getClass().getName() +
                              " exception: " + e);

        e.printStackTrace(new PrintWriter(out.getOutputStream()));

        return testResult;
    }

    public void setStream (OutputStream err) {
        out.setOutputStream(err);
    }

    protected Logger out = Logger.getLogger();

}
TOP

Related Classes of org.apache.tools.moo.servlet.ClientTest

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.