package com.cidat.proclets;

import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ProcletServiceData {
	public HttpServletRequest req;
	public HttpServletResponse res;
	public ServletConfig servletConfig;
	public String dataSourceName;
	public static final int JRUN = 1;
	public static final int NAS = 2;
	public static final int WEBLOGIC = 3;
	public static final int TOMCAT = 4;
	public static final int ORACLE9IAS = 5;
	public static final int OTHER = 6;
	public int servletSrv;
	public int servletSrvVersion = 0;
	public boolean debugVersion;
	String iniError = null;
	boolean canForwardJsp;
	boolean hardException = false;
	String logFilePath = null;
	String appPropertiesFilePath = null;
	String templatePageExpr = null;
	String absRedirect = null;
	String relRedirectServletPath = null;
	String relRedirectAddParams = null;
	String relRedirectAnchor = null;
	Hashtable multiPartEncParams = null;
	Exception forwardException;
	int nCallLevel = 0;
	Hashtable defParams = null;
	String errorPage = null;
	RequestEndListener requestEndListener = null;

	static Cache cache = new Cache();
	public static final String ERROR = "com.cidat.proclets.error";
	public static final String STACK = "com.cidat.proclets.stack";

	public String getLogFilePath() {
		return this.logFilePath;
	}

	public void setRequestEndListener(RequestEndListener requestEndListener) {
		if ((this.requestEndListener != null) && (requestEndListener != null)
				&& (this.requestEndListener != requestEndListener))
			throw new ValException(
					"ProcletServiceData.setRequestEndListener sÃ³lo soporta de momento un Listener");
		this.requestEndListener = requestEndListener;
	}

	void clearRedirect() {
		this.absRedirect = null;
		this.relRedirectServletPath = null;
		this.relRedirectAddParams = null;
		this.relRedirectAnchor = null;
	}

	protected ProcletServiceData(HttpServletRequest req,
			HttpServletResponse res, ServletConfig servletConfig,
			boolean isInner, ProcletProperties procProps, int servletSrv) {
		this.req = req;
		this.res = res;
		this.servletConfig = servletConfig;
		this.servletSrv = servletSrv;
		this.canForwardJsp = true;

		if (isInner) {
			this.iniError = ("Acceso directo denegado " + req.getRequestURI());
			return;
		}

		assign(procProps);
	}

	protected void assign(ProcletProperties procProps) {
		procProps.testNewVersion();

		if (procProps == null) {
			this.iniError = "ProcletProperties null";
			return;
		}

		if (procProps.iniError != null) {
			this.iniError = procProps.iniError;
		}
		this.dataSourceName = procProps.dataSourceName;
		this.debugVersion = procProps.debugVersion;

		this.errorPage = procProps.errorTemplatePage;
		this.logFilePath = procProps.logFilePath;
		if (procProps.appPropertiesFile != null)
			this.appPropertiesFilePath = procProps.appPropertiesFile
					.getAbsolutePath();
	}

	public static ProcletServiceData getTemplateServiceData(
			HttpServletRequest req) {
		ProcletServiceData sd = (ProcletServiceData) req
				.getAttribute("com.cidat.proclets.sd");
		return sd;
	}

	public static void processPageProclet(Proclet pageProclet,
			HttpServletRequest req, HttpServletResponse res,
			ServletConfig servletConfig, boolean isInner,
			ProcletProperties procProps) {
		ProcletServiceData sd = getPageProcletServiceData(req, res,
				servletConfig, isInner, procProps);
		try {
			sd.pageProcletIni();
			pageProclet.process(sd);
		} catch (Exception e) {
			sd.setException(e);
		} finally {
			sd.pageProcletEnd();
		}
	}

	public static ProcletServiceData getPageProcletServiceData(
			HttpServletRequest req, HttpServletResponse res,
			ServletConfig servletConfig, boolean isInner,
			ProcletProperties procProps) {
		ProcletServiceData sd = (ProcletServiceData) req
				.getAttribute("com.cidat.proclets.sd");
		if (sd != null) {
			sd.assign(procProps);
			return sd;
		}

		ServletContext ctx = servletConfig.getServletContext();

		String serverInfo = ctx.getServerInfo();
		System.out.println("---SERVER-INFO--- ###"+serverInfo+"###");
		int servletSrv = serverInfo.startsWith("Oracle9iAS") ? 5 : serverInfo
				.startsWith("Tomcat") ? 4
				: serverInfo.startsWith("WebLogic") ? 3 : serverInfo
						.startsWith("JRun") ? 1 : 6;

		ProcletServiceData newSd = new ProcletServiceData(req, res,
				servletConfig, isInner, procProps, servletSrv);

		if (servletSrv == 3) {
			String versionStr = "0";
			if ((serverInfo.startsWith("WebLogic XMLX Module 8"))
					|| (serverInfo.startsWith("WebLogic Server 8.1"))) {
				versionStr = "8";
			} else if ((serverInfo.startsWith("WebLogic Server 10.3."))) {
				versionStr = "11";
			} else {
				int versionOffset = 9;
				int nVersionEnd = serverInfo.indexOf('.', 9);
				if (nVersionEnd < 0)
					nVersionEnd = 10;
				versionStr = serverInfo.substring(9, nVersionEnd);
			}
			try {
			//FORZAMOS QUE SIEMPRE SEA WL11
				//newSd.servletSrvVersion = Integer.parseInt(versionStr);
				newSd.servletSrvVersion = Integer.parseInt("11");
			} catch (Exception e) {
			}
		}

		if (servletSrv == 1) {
			int versionOffset = 5;
			int nVersionEnd = serverInfo.indexOf('.', 5);
			if (nVersionEnd < 0)
				nVersionEnd = 6;
			String versionStr = serverInfo.substring(5, nVersionEnd);
			try {
			//FORZAMOS QUE SIEMPRE SEA WL11
				//newSd.servletSrvVersion = Integer.parseInt(versionStr);
				newSd.servletSrvVersion = Integer.parseInt("11");
			} catch (Exception e) {
			}
		}
		req.setAttribute("com.cidat.proclets.sd", newSd);
		return newSd;
	}

	public void pageProcletIni() throws ProcletException {
		if (this.debugVersion)
			System.out.println("ProcletServiceData.pageProcletIni : en pagina "
					+ this.req.getServletPath());
		if (this.iniError != null) {
			System.out.println(this.iniError);
			throw new ProcletException(this, this.iniError);
		}

		if ((this.req.getContentType() != null)
				&& (this.req.getContentType().toLowerCase()
						.startsWith("multipart/form-data"))
				&& (this.req.getContentLength() > 0)) {
			this.multiPartEncParams = FileUploadProclet.getFileParameters(this,
					-1);

			this.canForwardJsp = (this.servletSrv != 2);
		}
	}

	public void setException(Exception e) {
		this.forwardException = e;
	}

	public void pageProcletEnd() {
		if (this.nCallLevel > 0) {
			return;
		}

		try {
			if ((this.forwardException != null)
					&& ((this.forwardException instanceof ProcletException))) {
				ProcletException pe = (ProcletException) this.forwardException;

				if (pe.hardException) {
					ProcletException.saveStackVal(this, this.forwardException);
					this.hardException = true;
				}

			} else if (this.forwardException != null) {
				ProcletException.saveStackVal(this, this.forwardException);
				new ProcletException(this, this.forwardException.toString());
				this.hardException = true;
			}

			if (this.hardException) {
				System.out
						.println("ProcletServiceData.procletEnd: excepcion dura\""
								+ gOS("com.cidat.proclets.error") + "\"");
			}
			try {
				if (((this.absRedirect != null) || (this.relRedirectAddParams != null))
						&& (!this.hardException)) {
					String redir = this.absRedirect != null ? this.absRedirect
							: getAbsoluteUrlPath(gURL(
									this.relRedirectServletPath, null,
									this.relRedirectAnchor,
									this.relRedirectAddParams, null));

					redirect(redir);
					//System.out.println("TODO: LINEA DE CODIGO DECOMPILADA SIN SENTIDO ??? -- jsr 336; ");
				}
			} catch (ValException e) {
				ProcletException.saveStackVal(this, e);
				System.out
						.println("ProcletServiceData: Excepcion al obtener url de redirecciÃ³n: "
								+ e.toString());
				new ProcletException(this, e.toString());
			}

			if (!this.canForwardJsp) {
				String msg = "ERROR: " + gOS("com.cidat.proclets.error")
						+ " STACK: " + gOS("com.cidat.proclets.stack");
				try {
					new LogProclet("fileupload.txt", msg).process(this);
				} catch (ProcletException e) {
					System.out
							.println("ProcletServiceData.procletEnd: Excepcion de redirecciÃ³n con Fileupload: "
									+ e.getMessage());
				}

			}

			if ((this.templatePageExpr == null)
					|| (this.templatePageExpr.length() == 0)) {
				//System.out.println("TODO: LINEA DE CODIGO DECOMPILADA SIN SENTIDO ??? -- jsr 163; ");
			}
			try {
				String templatePage = getAbsoluteUrlPath(evalExpr(this.templatePageExpr));

				if ((this.servletSrv == 3) && (this.servletSrvVersion < 5)) {
					this.res.setContentType("text/html");
				}
				RequestDispatcher rd = this.servletConfig.getServletContext()
						.getRequestDispatcher(templatePage);

				if (rd == null)
					System.out
							.println("ProcletServiceData.procletEnd: No se ha podido redirigir a \""
									+ templatePage
									+ "\". PÃ¡gina no encontrada.");
				else
					rd.include(this.req, this.res);
			} catch (Exception e) {
				System.out
						.println("ProcletServiceData.procletEnd: Excepcion en redireccion \""
								+ e.toString() + "\"");

				//System.out.println("TODO: LINEA DE CODIGO DECOMPILADA SIN SENTIDO ??? -- jsr 12; ");
			}
		} finally {
			if (this.requestEndListener != null)
				this.requestEndListener.requestEnd(this);
		}
	}

	protected void redirect(String redir) {
		if (this.debugVersion)
			System.out.println("Redirigiendo a " + redir);
		String ua;
		if ((redir.indexOf('#') >= 0)
				&& ((ua = this.req.getHeader("User-Agent")) != null)
				&& (ua.indexOf("MSIE") >= 0)) {
			explorerRedirectWithAnchor(redir);
			return;
		}
		try {
			this.res.sendRedirect(redir);
		} catch (Exception e) {
			System.out
					.println("ProcletServiceData.redirect: Error redireccion: "
							+ e.toString());
		}
	}

	protected void explorerRedirectWithAnchor(String url) {
		try {
			this.res.setContentType("text/html");
			PrintWriter o = this.res.getWriter();
			o.println("<script>");
			o.println("location.replace(\"" + url + "\");");
			o.println("</script>");
		} catch (Exception e) {
			System.out
					.println("ProcletServiceData.explorerRedirectWithAnchor: Error: "
							+ e.toString());
		}
	}

	public Object gO(String name) throws ValException {
		Object ret = this.req.getAttribute(name);
		if (ret == null) {
			throw new ValException("Falta el parÃ¡metro " + name);
		}
		return ret;
	}

	public Object gOO(String name) {
		return this.req.getAttribute(name);
	}

	public String gS(String name) throws ValException {
		return gO(name).toString();
	}

	public String gSDbEscape(String name) throws ValException {
		return dbEscape(gS(name));
	}

	public String gOS(String name) {
		Object o = this.req.getAttribute(name);
		return o == null ? "" : o.toString();
	}

	public double gD(String name) throws ValException {
		return Double.valueOf(gS(name)).doubleValue();
	}

	public int gI(String name) throws ValException {
		return Integer.valueOf(gS(name)).intValue();
	}

	public boolean exists(String name) {
		return this.req.getAttribute(name) != null;
	}

	public String gURL(String servletPath, String extraPathInfo,
			String anchorExpr, String addParamsExpr, String removeParams)
			throws ValException {
		if (this.defParams == null) {
			this.defParams = new Hashtable();
		}
		if (servletPath == null) {
			servletPath = "";
		}
		if (extraPathInfo != null) {
			extraPathInfo = extraPathInfo.replace(' ', '_');
		}
		String urlServlet = servletPath + "/" + extraPathInfo;
		StringBuffer ret = new StringBuffer(urlServlet);

		Hashtable defParamsHash = (Hashtable) this.defParams.clone();
		String[] removeParamsArr = valListToArr(removeParams != null ? removeParams
				: "");
		for (int n = 0; n < removeParamsArr.length; n++) {
			defParamsHash.remove(removeParamsArr[n]);
		}

		StringBuffer addParamsUrl = new StringBuffer();
		String[] addParamsArr = valListToArr(addParamsExpr != null ? addParamsExpr
				: "");
		for (int n = 0; n < addParamsArr.length; n++) {
			int i;
			if ((i = addParamsArr[n].indexOf("=")) > 0) {
				String paramName = addParamsArr[n].substring(0, i);
				addParamsUrl.append("&"
						+ paramName
						+ "="
						+ URLEncoder.encode(evalExpr(addParamsArr[n]
								.substring(i + 1))));
				defParamsHash.remove(paramName);
			} else {
				boolean optional = addParamsArr[n].endsWith("?");
				String paramName = optional ? addParamsArr[n].substring(0,
						addParamsArr[n].length() - 1) : addParamsArr[n];
				if ((!optional) || (exists(paramName))) {
					addParamsUrl.append("&" + paramName + "="
							+ URLEncoder.encode(gS(paramName)));
					defParamsHash.remove(paramName);
				}
			}

		}

		for (Enumeration e = defParamsHash.keys(); e.hasMoreElements();) {
			String key = e.nextElement().toString();
			ret.append("&" + key + "=" + URLEncoder.encode(gS(key)));
		}

		ret.append(addParamsUrl.toString());

		if (ret.length() > urlServlet.length()) {
			ret.setCharAt(urlServlet.length(), '?');
		}

		return this.res.encodeURL(ret.toString())
				+ (anchorExpr != null ? "#" + evalExpr(anchorExpr) : "");
	}

	public String gURLHidden(String addParamsExpr, String removeParams)
			throws ValException {
		if (this.defParams == null) {
			this.defParams = new Hashtable();
		}
		Hashtable defParamsHash = (Hashtable) this.defParams.clone();
		String[] removeParamsArr = valListToArr(removeParams != null ? removeParams
				: "");
		for (int n = 0; n < removeParamsArr.length; n++) {
			defParamsHash.remove(removeParamsArr[n]);
		}
		StringBuffer ret = new StringBuffer();

		StringBuffer addParamsHidden = new StringBuffer();
		String[] addParamsArr = valListToArr(addParamsExpr != null ? addParamsExpr
				: "");
		for (int n = 0; n < addParamsArr.length; n++) {
			int i;
			if ((i = addParamsArr[n].indexOf("=")) > 0) {
				String paramName = addParamsArr[n].substring(0, i);
				addParamsHidden
						.append("<input type=\"hidden\" name=\""
								+ paramName
								+ "\" value=\""
								+ asciiToHtml(evalExpr(addParamsArr[n]
										.substring(i + 1))) + "\">");

				defParamsHash.remove(paramName);
			} else {
				boolean optional = addParamsArr[n].endsWith("?");
				String paramName = optional ? addParamsArr[n].substring(0,
						addParamsArr[n].length() - 1) : addParamsArr[n];
				if ((!optional) || (exists(paramName))) {
					addParamsHidden.append("<input type=\"hidden\" name=\""
							+ paramName + "\" value=\""
							+ asciiToHtml(gS(paramName)) + "\">");

					defParamsHash.remove(paramName);
				}
			}

		}

		for (Enumeration e = defParamsHash.keys(); e.hasMoreElements();) {
			String key = e.nextElement().toString();
			ret.append("<input type=\"hidden\" name=\"" + key + "\" value=\""
					+ asciiToHtml(gS(key)) + "\">");
		}

		ret.append(addParamsHidden.toString());

		return ret.toString();
	}

	public String gURL(String servletPath, String addParamsExpr)
			throws ValException {
		return gURL(servletPath, null, null, addParamsExpr, null);
	}

	public void sS(String name, String value) {
		this.req.setAttribute(name, value);
	}

	public void setVal(String name, Object value) {
		this.req.setAttribute(name, value);
	}

	public String[] getValNames(String valNameIni) {
		Vector vRet = new Vector();
		for (Enumeration aNE = this.req.getAttributeNames(); aNE
				.hasMoreElements();) {
			String name = (String) aNE.nextElement();
			if ((name.startsWith("javax."))
					|| (name.startsWith("com.cidat.proclets."))
					|| (name.startsWith("java."))
					|| ((valNameIni != null) && (valNameIni.length() != 0) && (!name
							.startsWith(valNameIni))))
				continue;
			vRet.addElement(name);
		}
		String[] ret = new String[vRet.size()];
		for (int n = 0; n < ret.length; n++)
			ret[n] = ((String) vRet.elementAt(n));
		vRet = null;
		return ret;
	}

	public Object getVal(String name) {
		return this.req.getAttribute(name);
	}

	public String evalExpr(String expression) throws ValException {
		StringBuffer ret = new StringBuffer();
		int i = 0;

		String opVal = "${";
		String opValDbEscape = "$[dbEscape]{";

		while (i < expression.length()) {
			boolean dbEscape = false;
			int ini = -1;

			int nSearchDollar = i;
			while (true) {
				int nDollar = expression.indexOf('$', nSearchDollar);
				if (nDollar == -1)
					break;
				ini = nDollar;
				if (expression.indexOf(opVal, nDollar) == nDollar)
					break;
				if (expression.indexOf(opValDbEscape, nDollar) == nDollar) {
					dbEscape = true;
					break;
				}
				ini = -1;
				nSearchDollar = nDollar + 1;
			}

			if (ini < 0) {
				ret.append(expression.substring(i));
				return ret.toString();
			}

			int nOpen = 1;
			int iniAfterBracket = ini
					+ (dbEscape ? opValDbEscape.length() : opVal.length());
			int end = iniAfterBracket;
			char prevChar = '\000';
			while (end < expression.length()) {
				char ch = expression.charAt(end);
				if ((prevChar == '$') && (ch == '{'))
					nOpen++;
				else if (ch == '}')
					nOpen--;
				if (nOpen == 0)
					break;
				prevChar = ch;
				end++;
			}
			if (end >= expression.length()) {
				ret.append(expression.substring(i));
				return ret.toString();
			}

			ret.append(expression.substring(i, ini));
			String valName = expression.substring(iniAfterBracket, end);
			if (valName.indexOf("${") < 0) {
				if (dbEscape)
					ret.append(gSDbEscape(valName));
				else
					ret.append(gS(valName));
			} else
				ret.append(gS(evalExpr(valName)));

			i = end + 1;
		}

		return ret.toString();
	}

	public String evalVals(String expression) throws ValException {
		return evalExpr(expression);
	}

	public static String[] valListToArr(String commaSepVals) {
		return valListToArr(commaSepVals, ",");
	}

	public static String[] valListToArr(String commaSepVals, String separators) {
		StringTokenizer sT = new StringTokenizer(commaSepVals, separators,
				false);
		String[] ret = new String[sT.countTokens()];
		for (int n = 0; n < ret.length; n++) {
			ret[n] = sT.nextToken();
		}
		return ret;
	}

	public static String arrToValList(String[] arr, char separator) {
		StringBuffer ret = new StringBuffer();
		for (int n = 0; n < arr.length; n++) {
			if (n > 0)
				ret.append(separator);
			ret.append(arr[n]);
		}
		return ret.toString();
	}

	public static String asciiToHtml(String src) {
		String escChar = "\"<>&\r\nÃ¡Ã©Ã­Ã³ÃºÃ�Ã‰Ã�Ã“ÃšÃ¼ÃœÃ±Ã‘";
		String[] repStr = { "&quot;", "&lt;", "&gt;", "&amp;", "", "<BR>\r\n",
				"&aacute;", "&eacute;", "&iacute;", "&oacute;", "&uacute;",
				"&Aacute;", "&Eacute;", "&Iacute;", "&Oacute;", "&Uacute;",
				"&uuml;", "&Uuml;", "&ntilde;", "&Ntilde;" };

		StringBuffer des = new StringBuffer(src.length() * 2);
		for (int n = 0; n < src.length(); n++) {
			int nEscChar = escChar.indexOf(src.charAt(n));
			if (nEscChar >= 0)
				des.append(repStr[nEscChar]);
			else {
				des.append(src.charAt(n));
			}
		}
		return des.toString();
	}

	public static String jsEscape(String src) {
		String escChar = "\"'\r\n";
		String[] repStr = { "\\\"", "\\'", "\\\r", "\\\n" };

		StringBuffer des = new StringBuffer(src.length() * 2);
		for (int n = 0; n < src.length(); n++) {
			int nEscChar = escChar.indexOf(src.charAt(n));
			if (nEscChar >= 0)
				des.append(repStr[nEscChar]);
			else {
				des.append(src.charAt(n));
			}
		}
		return des.toString();
	}

	String getAbsoluteUrlPath(String urlPath) {
		if (urlPath.startsWith("/")) {
			return urlPath;
		}

		String servletPath = (String) this.req
				.getAttribute("javax.servlet.include.servlet_path");
		if (servletPath == null)
			servletPath = this.req.getServletPath();
		int i = servletPath.lastIndexOf('/');
		servletPath = i < 0 ? "/" : servletPath.substring(0, i + 1);

		return servletPath + urlPath;
	}

	Cache getCache() {
		return cache;
	}

	public static String dbEscape(String text) throws ValException {
		StringBuffer ret = new StringBuffer();

		int i = 0;

		while (i < text.length()) {
			int nQuote = text.indexOf('\'', i);
			if (nQuote < 0) {
				ret.append(text.substring(i));
				return ret.toString();
			}
			ret.append(text.substring(i, nQuote));
			ret.append("''");
			i = nQuote + 1;
		}
		return ret.toString();
	}
}

/*
 * Location:
 * D:\svn\ejie\q53.trunk\codigo\q53\q53ItourbaskWar\WebContent\WEB-INF\
 * lib\proclets_wl81.jar Qualified Name: com.cidat.proclets.ProcletServiceData
 * JD-Core Version: 0.6.0
 */