Package com.dotmarketing.portlets.chains

Source Code of com.dotmarketing.portlets.chains.ChainsProcessor

package com.dotmarketing.portlets.chains;

import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.DotCacheException;
import com.dotmarketing.db.HibernateUtil;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotRuntimeException;
import com.dotmarketing.portlets.chains.business.ChainAPI;
import com.dotmarketing.portlets.chains.business.ChainLinkCodeCompilationException;
import com.dotmarketing.portlets.chains.model.Chain;
import com.dotmarketing.portlets.chains.model.ChainState;
import com.dotmarketing.portlets.chains.model.ChainStateParameter;
import com.dotmarketing.util.Logger;

public class ChainsProcessor {

  private static Pattern variablesPattern = Pattern.compile("\\{([A-Za-z0-9_-]+)\\}");
 
  public static ChainControl executeChain(String chainKey) throws DotDataException, DotCacheException, DotRuntimeException, ChainLinkCodeCompilationException {
    ChainAPI api = APILocator.getChainAPI();
    Chain chain = api.loadChainByKey(chainKey);

    if (chain == null) {
      throw new DotRuntimeException("Couldn't find a suitable chain to execute with the key name = " + chainKey);
    }

    ChainControl control = new ChainControl(chain, chain.getSuccessValue(), chain.getFailureValue());
    return executeChain(chain, control);
  }
 
  public static ChainControl executeChain (String chainKey, HttpServletRequest request) throws DotDataException, DotCacheException, DotRuntimeException, ChainLinkCodeCompilationException {
    ChainAPI api = APILocator.getChainAPI();
    Chain chain = api.loadChainByKey(chainKey);

    if (chain == null) {
      throw new DotRuntimeException("Couldn't find a suitable chain to execute with the key name = " + chainKey);
    }

    ChainControl control = new ChainControl(request, request.getSession(), chain, chain.getSuccessValue(), chain.getFailureValue());
    return executeChain(chain, control);   
  }
 
  @SuppressWarnings("unchecked")
  public static ChainControl executeChain (Chain chain, ChainControl control) throws DotDataException, DotRuntimeException, DotCacheException, ChainLinkCodeCompilationException {
   
    try {
     
           ChainAPI api = APILocator.getChainAPI();
     
      if(chain == null || control == null) {
        throw new DotRuntimeException("Unable to execute a null chain/control");
      }
               
            List<ChainState> states = chain.getStates();
            HibernateUtil.startTransaction();

            boolean exceptionOcurred = false;
          boolean lastLinkResult = true;

          if(control.getRequest() != null) {
            HttpServletRequest req = control.getRequest();
            Enumeration<String> parameterNames = req.getParameterNames();
            while(parameterNames.hasMoreElements()) {
                String e = parameterNames.nextElement();
              control.putChainProperty(e, req.getParameter(e));
            }
          }
         
          for (ChainState state : states) {
           
            //Resetting default control properties
            control.putChainProperty(ChainControl.ROLLBACK_ON_ERROR, true);
            control.putChainProperty(ChainControl.ROLLBACK_ONLY, false);
            control.putChainProperty(ChainControl.CONTINUE_ON_EXCEPTION, false);
            control.putChainProperty(ChainControl.CONTINUE_ON_FAILURE, false);
            control.putChainProperty(ChainControl.RESTART_TRANS, false);
           
              ChainLink link = api.instanciateChainLink(state.getLinkCodeId());
                List<ChainStateParameter> params = state.getParameters();
                for(ChainStateParameter p : params) {
                 
                  //Pattern substitution of variables block
                  //If a chain state parameter contains a variable value like myEmail={emailAddress}
                  //This code will try to replace the variable {emailAddress} with a preset emailAddress variable that could have
                  //been set by another link that happened before or a request parameter
                  //this code could also do string replacement like if you have a state parameter like phoneNumber={areaCode}-{phoneNumber}-{ext},
                  //this is useful if the request is submitting a parameter broken in pieces and the link expects it differently                 
                  Object value = "";
                 
                  Matcher variablesMatcher = variablesPattern.matcher(p.getValue());
              if(variablesMatcher.matches()) {
                    String variable = variablesMatcher.group(1);
                    Object preValue = control.getChainProperty(variable);
                    if(preValue != null) {
                      value = preValue;
                    }               
              } else {
                StringBuffer buff = new StringBuffer();
                    while(variablesMatcher.find()) {
                      String variable = variablesMatcher.group(1);
                      Object preValue = control.getChainProperty(variable);
                      if(preValue != null) {
                        variablesMatcher.appendReplacement(buff, preValue.toString());
                      }
                    }
                    variablesMatcher.appendTail(buff);
                    value = buff.toString();
              }
             
                  control.putChainProperty(p.getName(), value);
                }

              try {
                  lastLinkResult = link.execute(control);
                  exceptionOcurred = false;
                } catch (Exception linkException) {
                  Logger.error(link.getClass(), "Error ocurred executing the link id = " + link.getCode().getId());
                  exceptionOcurred = true;
                  control.addErrorMessage("link_exception", "Link: " + link.getTitle() + " throwed an exception: " + linkException.getMessage());
                }

                //False by default, if an exception occurred within a link code then the whole chain execution will be stopped
                boolean continueOnException = control.isSetToContinueOnException();
                //False by default, if an exception occurred within a link code then the whole chain execution will be stopped
                boolean continueOnFailure = control.isSetToContinueOnFailure();
                //False by default, if an exception occurred within a link code then the whole chain execution will be stopped
                boolean rollbackOnly = control.isSetToRollbackOnly();
                //False by default, if an exception occurred within a link code then the whole chain execution will be stopped
                boolean rollbackOnError = control.isSetToRollbackOnError();

                if(rollbackOnly || (rollbackOnError && (exceptionOcurred || !lastLinkResult))) {
                  HibernateUtil.rollbackTransaction();
                  HibernateUtil.startTransaction();
                } else if (control.isSetToRestartTransaction())
                {
                  HibernateUtil.commitTransaction();
                  HibernateUtil.startTransaction();                 
                }
               
                if((exceptionOcurred && !continueOnException) || (!lastLinkResult && !continueOnFailure)) {
                  //An error occurred that will stop the execution
                  break;
                }
               
                //This is set for the last iteration in case the last link throws an exception
                //but we will ignore the exception so we go to the success url
                if(continueOnException)
                  exceptionOcurred = false;
               
                //This is set for the last iteration in case the last link returned failure
                //but we will ignore the last link result so we go to the success url
                if(continueOnFailure)
                  lastLinkResult = true;
               
            }

            HibernateUtil.commitTransaction();
           
            if (exceptionOcurred || !lastLinkResult) {
                String failure = control.getFailureValue();
                control.setExecutionResult(failure);
                return control;
            } else {
                String success = control.getSuccessValue();
                control.setExecutionResult(success);
                return control;
            }           
        } finally {
          HibernateUtil.closeSession();
        }

  }
}
TOP

Related Classes of com.dotmarketing.portlets.chains.ChainsProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.