package com.cidat.proclets;

import gnu.regexp.RE;
import gnu.regexp.REException;
import gnu.regexp.REMatch;

import java.util.Hashtable;

public class ParamProclet implements Proclet {
	String[] params;
	String[] array;
	boolean[] uniqueNamedArr;
	RE[] regex;
	String[] ini;
	boolean[] toErrorPage;
	boolean[] isDefaultParam;
	Proclet[] iniProclet;

	public ParamProclet(String paramDefsList) {
		this(ProcletServiceData.valListToArr(paramDefsList));
	}

	public ParamProclet(String paramDef, Proclet procletBeforeIni) {
		this(new String[] { paramDef });
		this.iniProclet[0] = procletBeforeIni;
	}

	public ParamProclet(String[] paramDefs) {
		int nParams = paramDefs.length;

		this.params = new String[nParams];
		this.regex = new RE[nParams];
		this.ini = new String[nParams];
		this.array = new String[nParams];
		this.uniqueNamedArr = new boolean[nParams];
		this.toErrorPage = new boolean[nParams];
		this.isDefaultParam = new boolean[nParams];
		this.iniProclet = new Proclet[nParams];

		RE paramDefFormat = null;
		try {
			paramDefFormat = new RE(
					"\\s*(!?)\\s*(D:)?\\s*([a-z\\.A-Z0-9_]+)(\\[u?\\][a-z\\.A-Z0-9_]*)?\\s*(\\((.*?)\\))?\\s*(=.+)?");
		} catch (REException e) {
		}
		for (int n = 0; n < nParams; n++) {
			if (!paramDefFormat.isMatch(paramDefs[n])) {
				throw new ValException(
						"Formato de la definición del parámetro errónea: \""
								+ paramDefs[n] + "\"");
			}
			REMatch reM = paramDefFormat.getMatch(paramDefs[n]);

			this.toErrorPage[n] = reM.toString(1).equals("!");
			this.isDefaultParam[n] = ((reM.toString(2).length()) > 0 ? true
					: false);
			this.params[n] = reM.toString(3);
			this.array[n] = (reM.toString(4).length() > 0 ? reM.toString(4)
					.substring(reM.toString(4).indexOf(']') + 1) : null);
			this.uniqueNamedArr[n] = ((reM.toString(4).length() > 0)
					&& (reM.toString(4).startsWith("[u")) ? true : false);
			this.ini[n] = (reM.toString(5).length() > 0 ? reM.toString(6)
					: null);

			if (reM.toString(7).length() > 0) {
				try {
					this.regex[n] = new RE(reM.toString(7).substring(1));
				} catch (REException e) {
					throw new ValException(
							"Expresión regexp de la definición del parámetro errónea: \""
									+ paramDefs[n] + "\"");
				}
			}

			this.iniProclet[n] = null;
		}
	}

	public void process(ProcletServiceData sd) throws ProcletException {
		Hashtable defParamsHash = sd.defParams;
		if (sd.defParams == null) {
			sd.defParams = new Hashtable();
		}
		for (int nD = 0; nD < this.params.length; nD++) {
			if (this.isDefaultParam[nD] != false) {
				sd.defParams.put(this.params[nD], "true");
			}
		}
		ProcletException error = null;

		for (int n = 0; n < this.params.length; n++) {
			if (this.array[n] == null) {
				ProcletException newError = importVal(sd, n, this.params[n]);
				if (newError != null) {
					error = newError;
				}

			} else if (this.uniqueNamedArr[n] != false) {
				String[] vals = getParameterValues(sd, this.params[n]
						+ this.array[n]);
				if (vals == null)
					vals = new String[0];
				for (int i = 0; i < vals.length; i++) {
					String newArrayVal = this.params[n] + "[" + i + "]"
							+ this.array[n];
					if (sd.getVal(newArrayVal) == null)
						sd.setVal(newArrayVal, vals[i]);
				}
				sd.setVal(this.params[n] + ".length",
						String.valueOf(vals.length));
			} else {
				int i = 0;
				while (true) {
					String newArrayVal = this.params[n] + "[" + i + "]"
							+ this.array[n];
					if ((getParameter(sd, newArrayVal) == null)
							&& (sd.getVal(newArrayVal) == null))
						break;
					ProcletException newError = importVal(sd, n, newArrayVal);
					if (newError != null)
						error = newError;
					i++;
				}
				sd.setVal(this.params[n] + ".length", String.valueOf(i));
			}
		}
		if (error != null)
			throw error;
	}

	ProcletException importVal(ProcletServiceData sd, int n, String param)
			throws ProcletException {
		ProcletException error = null;
		boolean newParamImported = false;

		String p = (String) sd.getVal(param);
		if (p == null) {
			newParamImported = true;
			p = getParameter(sd, param);
		}
		if ((p == null) && (this.ini[n] != null)) {
			if (this.iniProclet[n] != null)
				this.iniProclet[n].process(sd);
			p = sd.evalExpr(this.ini[n]);
		}

		if (p == null) {
			throw new ProcletException(sd, "No he recibido el parámetro : "
					+ param);
		}
		if ((this.regex[n] != null) && (!this.regex[n].isMatch(p))) {
			if (this.toErrorPage[n] != false) {
				throw new ProcletException(sd,
						"Error en el formato del parámetro " + param);
			}

			error = new ProcletException(sd, "error_" + param, "true");
		}
		if (newParamImported) {
			sd.setVal(param, new String(p));
		}
		return error;
	}

	String getParameter(ProcletServiceData sd, String name)
			throws ProcletException {
		String reqParam = sd.req.getParameter(name);
		if (reqParam != null) {
			return reqParam;
		}
		if (sd.multiPartEncParams == null) {
			return null;
		}

		String[] vals = (String[]) sd.multiPartEncParams.get(name);
		return vals == null ? null : vals[0];
	}

	String[] getParameterValues(ProcletServiceData sd, String name)
			throws ProcletException {
		String[] reqParam = sd.req.getParameterValues(name);
		if (reqParam != null) {
			return reqParam;
		}
		if (sd.multiPartEncParams == null) {
			return null;
		}

		String[] vals = (String[]) sd.multiPartEncParams.get(name);
		return vals == null ? null : vals;
	}
}

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