/*
 * Copyright 1999,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package javax.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;



/**
 * Defines an object to provide client request information to a servlet.  The
 * servlet container creates a <code>ServletRequest</code> object and passes
 * it as an argument to the servlet's <code>service</code> method.
 *
 * <p>A <code>ServletRequest</code> object provides data including
 * parameter name and values, attributes, and an input stream.
 * Interfaces that extend <code>ServletRequest</code> can provide
 * additional protocol-specific data (for example, HTTP data is
 * provided by {@link javax.servlet.http.HttpServletRequest}.
 *
 * @author 	Various
 * @version 	$Version$
 *
 * @see 	javax.servlet.http.HttpServletRequest
 *
 */

public interface ServletRequest {




    /**
     *
     * Returns the value of the named attribute as an <code>Object</code>,
     * or <code>null</code> if no attribute of the given name exists.
     *
     * <p> Attributes can be set two ways.  The servlet container may set
     * attributes to make available custom information about a request.
     * For example, for requests made using HTTPS, the attribute
     * <code>javax.servlet.request.X509Certificate</code> can be used to
     * retrieve information on the certificate of the client.  Attributes
     * can also be set programatically using
     * {@link ServletRequest#setAttribute}.  This allows information to be
     * embedded into a request before a {@link RequestDispatcher} call.
     *
     * <p>Attribute names should follow the same conventions as package
     * names. This specification reserves names matching <code>java.*</code>,
     * <code>javax.*</code>, and <code>sun.*</code>.
     *
     * @param name	a <code>String</code> specifying the name of
     *			the attribute
     *
     * @return		an <code>Object</code> containing the value
     *			of the attribute, or <code>null</code> if
     *			the attribute does not exist
     *
     */

    public Object getAttribute(String name);



    /**
     * Returns an <code>Enumeration</code> containing the
     * names of the attributes available to this request.
     * This method returns an empty <code>Enumeration</code>
     * if the request has no attributes available to it.
     *
     *
     * @return		an <code>Enumeration</code> of strings
     *			containing the names
     * 			of the request's attributes
     *
     */

    public Enumeration getAttributeNames();




    /**
	 * Returns the name of the character encoding used in the body of this
	 * request. This method returns <code>null</code> if the request
	 * does not specify a character encoding
	 *
	 *
	 * @return		a <code>String</code> containing the name of
	 *			the chararacter encoding, or <code>null</code>
	 *			if the request does not specify a character encoding
	 *
	 */
	
	public String getCharacterEncoding();



	/**
     * Returns the length, in bytes, of the request body
     * and made available by the input stream, or -1 if the
     * length is not known. For HTTP servlets, same as the value
     * of the CGI variable CONTENT_LENGTH.
     *
     * @return		an integer containing the length of the
     * 			request body or -1 if the length is not known
     *
     */

    public int getContentLength();




    /**
     * Returns the MIME type of the body of the request, or
     * <code>null</code> if the type is not known. For HTTP servlets,
     * same as the value of the CGI variable CONTENT_TYPE.
     *
     * @return		a <code>String</code> containing the name
     *			of the MIME type of
     * 			the request, or null if the type is not known
     *
     */

    public String getContentType();




    /**
     * Retrieves the body of the request as binary data using
     * a {@link ServletInputStream}.  Either this method or
     * {@link #getReader} may be called to read the body, not both.
     *
     * @return			a {@link ServletInputStream} object containing
     * 				the body of the request
     *
     * @exception IllegalStateException  if the {@link #getReader} method
     * 					 has already been called for this request
     *
     * @exception IOException    	if an input or output exception occurred
     *
     */

    public ServletInputStream getInputStream() throws IOException;




    /**
     * Returns the value of a request parameter as a <code>String</code>,
     * or <code>null</code> if the parameter does not exist. Request parameters
     * are extra information sent with the request.  For HTTP servlets,
     * parameters are contained in the query string or posted form data.
     *
     * <p>You should only use this method when you are sure the
     * parameter has only one value. If the parameter might have
     * more than one value, use {@link #getParameterValues}.
     *
     * <p>If you use this method with a multivalued
     * parameter, the value returned is equal to the first value
     * in the array returned by <code>getParameterValues</code>.
     *
     * <p>If the parameter data was sent in the request body, such as occurs
     * with an HTTP POST request, then reading the body directly via {@link
     * #getInputStream} or {@link #getReader} can interfere
     * with the execution of this method.
     *
     * @param name 	a <code>String</code> specifying the
     *			name of the parameter
     *
     * @return		a <code>String</code> representing the
     *			single value of the parameter
     *
     * @see 		#getParameterValues
     *
     */

    public String getParameter(String name);




    /**
     *
     * Returns an <code>Enumeration</code> of <code>String</code>
     * objects containing the names of the parameters contained
     * in this request. If the request has
     * no parameters, the method returns an
     * empty <code>Enumeration</code>.
     *
     * @return		an <code>Enumeration</code> of <code>String</code>
     *			objects, each <code>String</code> containing
     * 			the name of a request parameter; or an
     *			empty <code>Enumeration</code> if the
     *			request has no parameters
     *
     */

    public Enumeration getParameterNames();




    /**
     * Returns an array of <code>String</code> objects containing
     * all of the values the given request parameter has, or
     * <code>null</code> if the parameter does not exist.
     *
     * <p>If the parameter has a single value, the array has a length
     * of 1.
     *
     * @param name	a <code>String</code> containing the name of
     *			the parameter whose value is requested
     *
     * @return		an array of <code>String</code> objects
     *			containing the parameter's values
     *
     * @see		#getParameter
     *
     */

    public String[] getParameterValues(String name);

    /**
     * Returns the name and version of the protocol the request uses
     * in the form <i>protocol/majorVersion.minorVersion</i>, for
     * example, HTTP/1.1. For HTTP servlets, the value
     * returned is the same as the value of the CGI variable
     * <code>SERVER_PROTOCOL</code>.
     *
     * @return		a <code>String</code> containing the protocol
     *			name and version number
     *
     */

    public String getProtocol();




    /**
     * Returns the name of the scheme used to make this request,
     * for example,
     * <code>http</code>, <code>https</code>, or <code>ftp</code>.
     * Different schemes have different rules for constructing URLs,
     * as noted in RFC 1738.
     *
     * @return		a <code>String</code> containing the name
     *			of the scheme used to make this request
     *
     */

    public String getScheme();




    /**
     * Returns the host name of the server that received the request.
     * For HTTP servlets, same as the value of the CGI variable
     * <code>SERVER_NAME</code>.
     *
     * @return		a <code>String</code> containing the name
     *			of the server to which the request was sent
     */

    public String getServerName();




    /**
     * Returns the port number on which this request was received.
     * For HTTP servlets, same as the value of the CGI variable
     * <code>SERVER_PORT</code>.
     *
     * @return		an integer specifying the port number
     *
     */

    public int getServerPort();



    /**
     * Retrieves the body of the request as character data using
     * a <code>BufferedReader</code>.  The reader translates the character
     * data according to the character encoding used on the body.
     * Either this method or {@link #getInputStream} may be called to read the
     * body, not both.
     *
     *
     * @return					a <code>BufferedReader</code>
     *						containing the body of the request	
     *
     * @exception IllegalStateException   	if {@link #getInputStream} method
     * 						has been called on this request
     *
     * @exception IOException  			if an input or output exception occurred
     *
     * @see 					#getInputStream
     *
     */

    public BufferedReader getReader() throws IOException;




    /**
     * Returns the Internet Protocol (IP) address of the client
     * that sent the request.  For HTTP servlets, same as the value of the
     * CGI variable <code>REMOTE_ADDR</code>.
     *
     * @return		a <code>String</code> containing the
     *			IP address of the client that sent the request
     *
     */

    public String getRemoteAddr();




    /**
     * Returns the fully qualified name of the client that sent the
     * request. If the engine cannot or chooses not to resolve the hostname
     * (to improve performance), this method returns the dotted-string form of
     * the IP address. For HTTP servlets, same as the value of the CGI variable
     * <code>REMOTE_HOST</code>.
     *
     * @return		a <code>String</code> containing the fully
     * qualified name of the client
     *
     */

    public String getRemoteHost();




    /**
     *
     * Stores an attribute in this request.
     * Attributes are reset between requests.  This method is most
     * often used in conjunction with {@link RequestDispatcher}.
     *
     * <p>Attribute names should follow the same conventions as
     * package names. Names beginning with <code>java.*</code>,
     * <code>javax.*</code>, and <code>com.sun.*</code>, are
     * reserved for use by Sun Microsystems.
     *
     *
     * @param name			a <code>String</code> specifying
     *					the name of the attribute
     *
     * @param o				the <code>Object</code> to be stored
     *
     */

    public void setAttribute(String name, Object o);




    /**
     *
     * @deprecated 	As of Version 2.1 of the Java Servlet API,
     * 			use {@link ServletContext#getRealPath} instead.
     *
     */

    public String getRealPath(String path);


}

