package org.apache.struts.action;

import java.io.IOException;
import java.util.Locale;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.TokenProcessor;

public class Action {
  public static final String ACTION_SERVLET_KEY = "org.apache.struts.action.ACTION_SERVLET";
  
  public static final String APPLICATION_KEY = "org.apache.struts.action.MODULE";
  
  public static final String DATA_SOURCE_KEY = "org.apache.struts.action.DATA_SOURCE";
  
  public static final String ERROR_KEY = "org.apache.struts.action.ERROR";
  
  public static final String EXCEPTION_KEY = "org.apache.struts.action.EXCEPTION";
  
  public static final String FORM_BEANS_KEY = "org.apache.struts.action.FORM_BEANS";
  
  public static final String FORWARDS_KEY = "org.apache.struts.action.FORWARDS";
  
  public static final String LOCALE_KEY = "org.apache.struts.action.LOCALE";
  
  public static final String MAPPING_KEY = "org.apache.struts.action.mapping.instance";
  
  public static final String MAPPINGS_KEY = "org.apache.struts.action.MAPPINGS";
  
  public static final String MESSAGE_KEY = "org.apache.struts.action.ACTION_MESSAGE";
  
  public static final String MESSAGES_KEY = "org.apache.struts.action.MESSAGE";
  
  public static final String MULTIPART_KEY = "org.apache.struts.action.mapping.multipartclass";
  
  public static final String PLUG_INS_KEY = "org.apache.struts.action.PLUG_INS";
  
  public static final String REQUEST_PROCESSOR_KEY = "org.apache.struts.action.REQUEST_PROCESSOR";
  
  public static final String SERVLET_KEY = "org.apache.struts.action.SERVLET_MAPPING";
  
  public static final String TRANSACTION_TOKEN_KEY = "org.apache.struts.action.TOKEN";
  
  private static TokenProcessor token = TokenProcessor.getInstance();
  
  protected static Locale defaultLocale = Locale.getDefault();
  
  protected ActionServlet servlet = null;
  
  public ActionServlet getServlet() {
    return this.servlet;
  }
  
  public void setServlet(ActionServlet servlet) {
    this.servlet = servlet;
  }
  
  public ActionForward execute(ActionMapping mapping, ActionForm form, ServletRequest request, ServletResponse response) throws Exception {
    return perform(mapping, form, request, response);
  }
  
  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
    return perform(mapping, form, request, response);
  }
  
  public ActionForward perform(ActionMapping mapping, ActionForm form, ServletRequest request, ServletResponse response) throws IOException, ServletException {
    try {
      return perform(mapping, form, (HttpServletRequest)request, (HttpServletResponse)response);
    } catch (ClassCastException e) {
      return null;
    } 
  }
  
  public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    return null;
  }
  
  protected String generateToken(HttpServletRequest request) {
    return token.generateToken(request);
  }
  
  protected DataSource getDataSource(HttpServletRequest request) {
    return getDataSource(request, "org.apache.struts.action.DATA_SOURCE");
  }
  
  protected DataSource getDataSource(HttpServletRequest request, String key) {
    ServletContext context = getServlet().getServletContext();
    ModuleConfig moduleConfig = RequestUtils.getModuleConfig(request, context);
    return (DataSource)context.getAttribute(key + moduleConfig.getPrefix());
  }
  
  protected Locale getLocale(HttpServletRequest request) {
    HttpSession session = request.getSession();
    Locale locale = (Locale)session.getAttribute("org.apache.struts.action.LOCALE");
    if (locale == null)
      locale = defaultLocale; 
    return locale;
  }
  
  protected MessageResources getResources() {
    return (MessageResources)this.servlet.getServletContext().getAttribute("org.apache.struts.action.MESSAGE");
  }
  
  protected MessageResources getResources(HttpServletRequest request) {
    return (MessageResources)request.getAttribute("org.apache.struts.action.MESSAGE");
  }
  
  protected MessageResources getResources(HttpServletRequest request, String key) {
    ServletContext context = getServlet().getServletContext();
    ModuleConfig moduleConfig = RequestUtils.getModuleConfig(request, context);
    return (MessageResources)context.getAttribute(key + moduleConfig.getPrefix());
  }
  
  protected boolean isCancelled(HttpServletRequest request) {
    return (request.getAttribute("org.apache.struts.action.CANCEL") != null);
  }
  
  protected boolean isTokenValid(HttpServletRequest request) {
    return token.isTokenValid(request, false);
  }
  
  protected boolean isTokenValid(HttpServletRequest request, boolean reset) {
    return token.isTokenValid(request, reset);
  }
  
  protected void resetToken(HttpServletRequest request) {
    token.resetToken(request);
  }
  
  protected void saveErrors(HttpServletRequest request, ActionErrors errors) {
    if (errors == null || errors.isEmpty()) {
      request.removeAttribute("org.apache.struts.action.ERROR");
      return;
    } 
    request.setAttribute("org.apache.struts.action.ERROR", errors);
  }
  
  protected void saveMessages(HttpServletRequest request, ActionMessages messages) {
    if (messages == null || messages.isEmpty()) {
      request.removeAttribute("org.apache.struts.action.ACTION_MESSAGE");
      return;
    } 
    request.setAttribute("org.apache.struts.action.ACTION_MESSAGE", messages);
  }
  
  protected void saveToken(HttpServletRequest request) {
    token.saveToken(request);
  }
  
  protected void setLocale(HttpServletRequest request, Locale locale) {
    HttpSession session = request.getSession();
    if (locale == null)
      locale = defaultLocale; 
    session.setAttribute("org.apache.struts.action.LOCALE", locale);
  }
  
  protected String toHex(byte[] buffer) {
    return token.toHex(buffer);
  }
}
