package org.xins.common.servlet.container;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.xins.common.text.FormatException;
import org.xins.common.text.URLEncoding;
public class XINSServletRequest implements HttpServletRequest {
private static String LOCALHOST_NAME;
private static String LOCALHOST_ADDRESS;
private static Map SESSIONS = new HashMap();
private final String _method;
private final String _url;
private HashMap _parameters = new HashMap();
private long _date = System.currentTimeMillis();
private Hashtable _attributes = new Hashtable();
private Hashtable _headers = new Hashtable();
private String _pathInfo;
private String _queryString;
private String _contentType;
private String _postData;
private Cookie[] _cookies;
private boolean _inputStreamUsed = false;
private boolean _readerUsed = false;
private String _characterEncoding;
static {
try {
LOCALHOST_ADDRESS = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException exception) {
LOCALHOST_ADDRESS = "127.0.0.1";
}
try {
LOCALHOST_NAME = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException exception) {
LOCALHOST_NAME = "localhost";
}
}
public XINSServletRequest(String url) {
this("GET", url, null, null);
}
public XINSServletRequest(String method, String url, String data, Map headers) {
_method = method;
_url = url;
_postData = data;
if (headers == null) {
_contentType = "application/x-www-form-urlencoded";
} else {
_headers.putAll(headers);
_contentType = (String) headers.get("CONTENT-TYPE");
}
parseURL(url);
}
private void parseURL(String url) {
int doubleSlashPos = url.lastIndexOf("://");
int startPathPos = url.indexOf("/", doubleSlashPos + 1) + 1;
int questionMarkPos = url.lastIndexOf('?');
if (questionMarkPos == url.length() - 1) {
_queryString = "";
if (startPathPos < questionMarkPos) {
_pathInfo = url.substring(startPathPos, questionMarkPos);
}
} else if (questionMarkPos != -1) {
_queryString = url.substring(questionMarkPos + 1);
if (startPathPos < questionMarkPos) {
_pathInfo = url.substring(startPathPos, questionMarkPos);
}
} else {
_queryString = null;
if (startPathPos < url.length()) {
_pathInfo = url.substring(startPathPos);
}
return;
}
StringTokenizer paramsParser = new StringTokenizer(_queryString, "&");
while (paramsParser.hasMoreTokens()) {
String parameter = paramsParser.nextToken();
int equalPos = parameter.indexOf('=');
if (equalPos != -1) {
try {
String paramName = URLEncoding.decode(parameter.substring(0, equalPos));
String paramValue = "";
if (equalPos != parameter.length()-1) {
paramValue = URLEncoding.decode(parameter.substring(equalPos + 1));
}
Object currValue = _parameters.get(paramName);
if (currValue == null) {
_parameters.put(paramName, paramValue);
} else if (currValue instanceof String) {
ArrayList values = new ArrayList();
values.add(currValue);
values.add(paramValue);
_parameters.put(paramName, values);
} else {
ArrayList values = (ArrayList) currValue;
values.add(paramValue);
}
} catch (FormatException fe) {
} catch (IllegalArgumentException iae) {
}
}
}
}
public void setCharacterEncoding(String str) {
_characterEncoding = str;
}
public String[] getParameterValues(String str) {
Object values = _parameters.get(str);
if (values == null) {
return null;
} else if (values instanceof String) {
return new String[] { (String) values };
} else {
ArrayList list = (ArrayList) values;
return (String[]) list.toArray(new String[list.size()]);
}
}
public String getParameter(String str) {
String[] values = getParameterValues(str);
return (values == null) ? null : values[0];
}
public int getIntHeader(String str) {
String value = getHeader(str);
if (value != null) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException exception) {
return -1;
}
} else {
return -1;
}
}
public Object getAttribute(String str) {
return _attributes.get(str);
}
public long getDateHeader(String str) {
return _date;
}
public String getHeader(String str) {
return (String) _headers.get(str.toUpperCase());
}
public Enumeration getHeaders(String str) {
throw new UnsupportedOperationException();
}
public String getRealPath(String str) {
throw new UnsupportedOperationException();
}
public RequestDispatcher getRequestDispatcher(String str) {
throw new UnsupportedOperationException();
}
public boolean isUserInRole(String str) {
return false;
}
public void removeAttribute(String str) {
_attributes.remove(str);
}
public void setAttribute(String str, Object obj) {
_attributes.put(str, obj);
}
public String getQueryString() {
return _queryString;
}
public String getProtocol() {
return "file://";
}
public String getPathTranslated() {
if (_pathInfo == null) {
return null;
}
int firstSlashPos = _pathInfo.indexOf("/");
if (firstSlashPos == -1 || firstSlashPos == _pathInfo.length() - 1) {
return null;
}
return _pathInfo.substring(firstSlashPos + 1);
}
public String getPathInfo() {
return _pathInfo;
}
public Enumeration getParameterNames() {
return Collections.enumeration(_parameters.keySet());
}
public Map getParameterMap() {
return _parameters;
}
public String getMethod() {
return _method;
}
public Enumeration getLocales() {
throw new UnsupportedOperationException();
}
public Locale getLocale() {
throw new UnsupportedOperationException();
}
public Enumeration getAttributeNames() {
return _attributes.keys();
}
public String getAuthType() {
return "";
}
public String getCharacterEncoding() {
if (_characterEncoding != null) {
return _characterEncoding;
} else if (_contentType == null) {
return null;
} else {
int charsetPos = _contentType.indexOf("charset=");
if (charsetPos == -1) {
return "UTF-8";
} else {
return _contentType.substring(charsetPos + 8);
}
}
}
public int getContentLength() {
return getIntHeader("Content-Length");
}
public String getContentType() {
return _contentType;
}
public String getContextPath() {
throw new UnsupportedOperationException();
}
public Cookie[] getCookies() {
if (_cookies == null && _headers.get("COOKIE") != null) {
String cookies = (String) _headers.get("COOKIE");
StringTokenizer stCookies = new StringTokenizer(cookies, ";");
_cookies = new Cookie[stCookies.countTokens()];
int counter = 0;
while (stCookies.hasMoreTokens()) {
String nextCookie = stCookies.nextToken().trim();
int equalsPos = nextCookie.indexOf('=');
String cookieName = nextCookie.substring(0, equalsPos);
String cookieValue = nextCookie.substring(equalsPos + 1);
_cookies[counter++] = new Cookie(cookieName, cookieValue);
}
} else if (_cookies == null) {
_cookies = new Cookie[0];
}
return _cookies;
}
public Enumeration getHeaderNames() {
return _headers.keys();
}
public ServletInputStream getInputStream() {
if (_readerUsed) {
throw new IllegalStateException("The method getReader() has already been called on this request.");
}
_inputStreamUsed = true;
return new InputStream(_postData);
}
public BufferedReader getReader() {
if (_inputStreamUsed) {
throw new IllegalStateException("The method getInputStream() has already been called on this request.");
}
_readerUsed = true;
return new BufferedReader(new StringReader(_postData));
}
public String getRemoteAddr() {
return LOCALHOST_ADDRESS;
}
public String getRemoteHost() {
return LOCALHOST_NAME;
}
public String getRemoteUser() {
return "";
}
public String getRequestURI() {
if (_url.indexOf('?') == -1) {
return _url;
} else {
return _url.substring(0, _url.indexOf('?'));
}
}
public StringBuffer getRequestURL() {
return new StringBuffer(_url);
}
public String getRequestedSessionId() {
throw new UnsupportedOperationException();
}
public String getScheme() {
int separator = _url.indexOf("://");
if (separator != -1) {
return _url.substring(0, separator + 3);
}
return "file://";
}
public String getServerName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (Exception ioe) {
return "localhost";
}
}
public int getServerPort() {
return 8080;
}
public String getServletPath() {
return "";
}
public HttpSession getSession() {
return (HttpSession) SESSIONS.get(getRemoteAddr() + getRemoteUser());
}
public HttpSession getSession(boolean create) {
String sessionKey = getRemoteAddr() + getRemoteUser();
HttpSession session = (HttpSession) SESSIONS.get(sessionKey);
if (session == null) {
session = new XINSHttpSession();
SESSIONS.put(sessionKey, session);
}
return session;
}
public Principal getUserPrincipal() {
throw new UnsupportedOperationException();
}
public boolean isRequestedSessionIdFromCookie() {
return false;
}
public boolean isRequestedSessionIdFromURL() {
return false;
}
public boolean isRequestedSessionIdFromUrl() {
return false;
}
public boolean isRequestedSessionIdValid() {
return false;
}
public boolean isSecure() {
return false;
}
private static class InputStream extends ServletInputStream {
private InputStream(String data) {
String encoding = "ISO-8859-1";
try {
byte[] dataAsByte = data.getBytes(encoding);
_stream = new ByteArrayInputStream(dataAsByte);
} catch (UnsupportedEncodingException exception) {
throw new RuntimeException("Failed to convert characters to bytes using encoding \"" + encoding + "\".");
}
}
private final ByteArrayInputStream _stream;
public int read() throws IOException {
return _stream.read();
}
public int read(byte[] b) throws IOException {
return _stream.read(b);
}
public int read(byte[] b, int off, int len) throws IOException {
return _stream.read(b, off, len);
}
public boolean markSupported() {
return _stream.markSupported();
}
public void mark(int readlimit) {
_stream.mark(readlimit);
}
public long skip(long n) throws IOException {
return _stream.skip(n);
}
public void reset() throws IOException {
_stream.reset();
}
public void close() throws IOException {
_stream.close();
}
}
}