All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.clickntap.smart.SmartSwitcher Maven / Gradle / Ivy

There is a newer version: 1.189
Show newest version
package com.clickntap.smart;

import java.beans.PropertyDescriptor;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.clickntap.smart.SmartAction.BindingElement;
import com.clickntap.tool.bean.Bean;
import com.clickntap.tool.bean.BeanManager;
import com.clickntap.tool.bean.BeanUtils;
import com.clickntap.tool.jdbc.JdbcManager;
import com.clickntap.utils.ConstUtils;

public class SmartSwitcher implements Controller {
  private static final String CHANNEL_SCRIPT_KEY = "channelScript";
  private static final String FORM_SCRIPT_KEY = "formScript";
  private static final String ACTION_SCRIPT_KEY = "actionScript";
  private static final String RESET_SCRIPT_KEY = "resetScript";
  private static Log log = LogFactory.getLog(SmartSwitcher.class);
  private JdbcManager jdbcManager;

  private static boolean isReset(SmartContext context) {
    try {
      if (Integer.parseInt(context.eval(context.conf(RESET_SCRIPT_KEY))) == 1)
        return true;
    } catch (Exception e) {
    }
    return false;
  }

  public static boolean executeAction(SmartContext context, SmartAction action, boolean reset) throws Exception {
    if (log.isDebugEnabled()) {
      log.debug("[ action");
    }
    if (context.isBreak()) {
      if (log.isDebugEnabled()) {
        log.debug("break");
        log.debug("action ]");
      }
      return false;
    }
    boolean canContinue = true;
    executeLoads(context, action);
    if (canContinue)
      executeScripts(context, action.getInits());
    if (canContinue)
      canContinue = executeRules(context, action, canContinue);
    if (canContinue || (action.getElses().size() > 0))
      canContinue = executeBinds(context, action, canContinue, true, reset);
    if (canContinue)
      executeScripts(context, action.getExecs());
    else
      executeScripts(context, action.getElses());
    if (log.isDebugEnabled()) {
      log.debug("action ]");
    }
    return canContinue;
  }

  public static boolean executeRules(SmartContext context, SmartAction action, boolean canContinue) throws Exception {
    if (context.isBreak())
      return false;
    for (String rule : action.getRules()) {
      if (log.isDebugEnabled()) {
        log.debug("eval rule '" + rule + "'");
      }
      if (!context.evalRule(rule)) {
        if (log.isDebugEnabled()) {
          log.debug("break with rule '" + rule + "'");
        }
        canContinue = false;
        break;
      }
    }
    return canContinue;
  }

  public static void executeScripts(SmartContext context, List scripts) throws Exception {
    if (context.isBreak())
      return;
    for (String script : scripts) {
      if (log.isDebugEnabled()) {
        log.debug("eval script '" + script + "'");
      }
      try {
        context.eval(script);
      } catch (Exception e) {
        throw e;
      }
    }
  }

  public static boolean executeBinds(SmartContext context, SmartAction action, boolean canContinue, boolean storable, boolean reset) throws Exception {
    if (context.isBreak())
      return false;
    for (BindingElement be : action.getBinds()) {
      SmartBindingResult bindingResult = context.bind(be.getObjectName(), be.getObjectClass(), be.getChannel(getSmartChannelContext(context)), be.getAllowedFields(), be.getDisallowedFields(), be.getScope());
      Object target = bindingResult.getBindingResult().getTarget();
      if (reset || bindingResult.isNew()) {
        context.eval(be.getScript());
        Object tempObject = Class.forName(be.getObjectClass()).getDeclaredConstructor().newInstance();
        context.bind(tempObject);
        PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(tempObject.getClass());
        for (PropertyDescriptor descriptor : descriptors) {
          try {
            Object value = BeanUtils.getValue(tempObject, descriptor.getName());
            if (value != null && !(value instanceof Bean)) {
              BeanUtils.setValue(target, descriptor.getName(), value);
            }
          } catch (Exception e) {
          }
        }
      }
      if (storable) {
        if (target instanceof Bean && be.getValidationGroup() != null)
          ValidationUtils.invokeValidator(((BeanManager) context.getBean(be.getChannel(getSmartChannelContext(context)))).getValidator((Bean) target, be.getValidationGroup()), target, bindingResult.getBindingResult());
      }
      if (bindingResult.getBindingResult().hasErrors()) {
        canContinue = false;
      }
    }
    return canContinue;
  }

  public static void executeLoads(SmartContext context, SmartAction action) throws Exception {
    if (context.isBreak())
      return;
    for (BindingElement be : action.getLoads()) {
      context.load(be.getObjectName(), be.getObjectClass(), be.getChannel(getSmartChannelContext(context)), be.getScope());
      context.eval(be.getScript());
    }
  }

  private static String getSmartChannelContext(SmartContext context) throws Exception {
    try {
      String channelContext = context.eval(context.conf(CHANNEL_SCRIPT_KEY));
      return channelContext;
    } catch (Throwable e) {
      return ConstUtils.EMPTY;
    }
  }

  public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    if (request.getCharacterEncoding() == null)
      request.setCharacterEncoding(ConstUtils.UTF_8);
    SmartContext ctx = new SmartContext(request, response);
    ctx.checkFailedAttempts();
    return restHandleRequest(ctx);
  }

  public ModelAndView restHandleRequest(SmartContext ctx) throws Exception {
    try {
      if (handleRequest(ctx) && !ctx.isRedirected()) {
        return new ModelAndView(ctx.getController().getViewName(), ctx);
      } else
        return null;
    } catch (Exception e) {
      ctx.setException(e);
      try {
        return new ModelAndView(ctx.getController().getViewName(), ctx);
      } catch (SmartControllerNotFoundException notfound) {
        return null;
      }
    }
  }

  private boolean handleRequest(SmartContext ctx) throws Exception {
    try {
      if (jdbcManager == null)
        return execute(ctx);
      else {
        return (Boolean) jdbcManager.execute(new TransactionalService(this, ctx));
      }
    } catch (SmartControllerNotFoundException e) {
    } catch (SmartControllerAccessDeniedException e) {
      ctx.getResponse().sendError(HttpServletResponse.SC_FORBIDDEN);
    }
    return false;
  }

  public boolean execute(SmartContext context) throws Exception {
    boolean executed = false;

    SmartController controller = context.getController();
    if (!context.canTryAutoLogin())
      context.tryAutoLogin();

    if (controller.isAjax() && controller.isAuthenticated() && !context.isAuthenticated())
      throw new SmartControllerAccessDeniedException();
    if (context.tryLogin(false) && context.isStoredRequest())
      context.redirect(context.getStoredRequest().getRef());
    else if (controller.isAuthenticated() && !context.isAuthenticated()) {
      if (!context.isLogoutRequest())
        context.storeRequest();
      context.redirect(controller.getLoginRef());
    } else {
      if (context.isAuthenticated() && context.isStoredRequest())
        context.loadRequest();
      executeController(context, controller);
      executed = true;
    }
    context.tryLogout();
    return executed && !context.isRedirected();
  }

  private void executeController(SmartContext context, SmartController controller) throws Exception {
    try {
      if (log.isDebugEnabled()) {
        log.debug("[ service");
      }
      long lo = System.currentTimeMillis();
      SmartAction cacheAction = controller.getCacheAction();
      if (cacheAction != null) {
        executeAction(context, cacheAction, false);
        if (SmartCache.isCached(context))
          return;
      }
      for (SmartAction action : controller.getActions()) {
        executeAction(context, action, false);
      }
      for (SmartMethod method : controller.getMethods()) {
        if (log.isDebugEnabled()) {
          log.debug("[ method " + method.getName());
        }
        executeScripts(context, method.getInits());
        if (method.getName().equals(context.eval(context.conf(ACTION_SCRIPT_KEY)))) {
          executeAction(context, method, isReset(context));
        } else if (method.getName().equals(context.eval(context.conf(FORM_SCRIPT_KEY)))) {
          executeLoads(context, method);
          boolean canContinue = true;
          if (canContinue)
            canContinue = executeRules(context, method, canContinue);
          if (canContinue || (method.getElses().size() > 0))
            executeBinds(context, method, true, false, isReset(context));
        }
        if (log.isDebugEnabled()) {
          log.debug("method ]");
        }
      }
      lo = (System.currentTimeMillis() - lo);
      if (log.isDebugEnabled()) {
        log.debug("exec in " + lo + " millis");
        log.debug("service ]");
      }
    } catch (Exception e) {
      throw e;
    } finally {
    }
  }

  public void setJdbcManager(JdbcManager jdbcManager) {
    this.jdbcManager = jdbcManager;
  }

  public class TransactionalService implements TransactionCallback {

    private SmartSwitcher smartSwicher;
    private SmartContext smartContext;

    public TransactionalService(SmartSwitcher smartSwitcher, SmartContext smartContext) {
      this.smartSwicher = smartSwitcher;
      this.smartContext = smartContext;
    }

    public Object doInTransaction(TransactionStatus status) {
      try {
        return smartSwicher.execute(smartContext);
      } catch (SmartControllerAccessDeniedException e) {
        throw e;
      } catch (Exception e) {
        if (log.isErrorEnabled()) {
          log.error(e);
        }
        throw new RuntimeException(e);
      }
    }

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy