com.webbfontaine.valuewebb.irms.core.RuleCallable.java Source code

Java tutorial

Introduction

Here is the source code for com.webbfontaine.valuewebb.irms.core.RuleCallable.java

Source

/*
 * Copyrights 2002-2011 Webb Fontaine
 * Developer: Sargis Harutyunyan
 * Date: 05 dc. 2011
 * This software is the proprietary information of Webb Fontaine.
 * Its use is subject to License terms.
 */
package com.webbfontaine.valuewebb.irms.core;

import com.google.common.base.Stopwatch;
import com.google.common.base.Throwables;
import com.webbfontaine.twm.urmcore.server.lang.GroovyScript;
import com.webbfontaine.valuewebb.irms.impl.bean.TTSourceBean;
import com.webbfontaine.valuewebb.irms.repo.RuleRepository;
import com.webbfontaine.valuewebb.model.irms.Criteria;
import org.jboss.seam.security.digest.DigestUtils;
import org.jboss.seam.util.Naming;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

import static com.webbfontaine.valuewebb.irms.core.RuleContext.RULE_CONTEXT_PARAM_NAME;

public class RuleCallable<T> implements Callable<T> {

    private static final Logger LOGGER = LoggerFactory.getLogger(RuleCallable.class);

    private final SourceBeanBuilder sourceBeanBuilder;
    private final RuleContextBuilder ruleContextBuilder;

    private RuleRepository<T> ruleRepository;

    private final Criteria criterion;

    public RuleCallable(Criteria criterion, RuleContextBuilder ruleContextBuilder,
            SourceBeanBuilder sourceBeanBuilder) {
        this.sourceBeanBuilder = sourceBeanBuilder;
        this.ruleContextBuilder = ruleContextBuilder;
        this.criterion = criterion;
    }

    @Override
    public T call() throws Exception {
        Stopwatch stopwatch = Stopwatch.createStarted();

        RuleContext ruleContext = ruleContextBuilder.createRuleContext();
        TTSourceBean ttSourceBean = sourceBeanBuilder.createSourceBean();

        T result = applyRule(criterion, ruleContext, ttSourceBean);

        stopwatch.stop();

        LOGGER.debug("Rule: {} execution time for TT with id: {}, pds size: {} is: {}", new Object[] {
                criterion.getCode(), ttSourceBean.getTtId(), ttSourceBean.getTtNumberOfItems(), stopwatch });

        return result;
    }

    private void runWithTransaction(Runnable runnable) {
        UserTransaction utx = getUserTransaction();
        try {
            utx.begin();
            runnable.run();
            utx.commit();
        } catch (Exception e) {
            LOGGER.error("", e);
            try {
                utx.rollback();
            } catch (SystemException sex) {
                LOGGER.error("", sex);
            }
        }
    }

    private T applyRule(Criteria criterion, RuleContext ruleContext, TTSourceBean ttSourceBean) {
        GroovyScript groovyScript = createGroovyScript(criterion.getCriteria());
        try {
            IrmsRule<TTSourceBean, T> executableRule = ruleRepository.createRule(criterion.getCode(), groovyScript);

            executableRule.setSource(ttSourceBean);
            executableRule.setParameters(createRuleParams(ruleContext));

            return executableRule.applyRule();
        } catch (Exception e) {
            LOGGER.error("Error for Rule: <{}:{}>", criterion.getId(), criterion.getCode());
            LOGGER.error("", e);
            throw Throwables.propagate(e);
        }
    }

    private GroovyScript createGroovyScript(String ruleScript) {
        GroovyScript groovyScript = new GroovyScript(getName(ruleScript), ruleScript);

        LOGGER.debug("Groovy script to execute: {}", groovyScript);
        return groovyScript;
    }

    private static String getName(String rule) {
        return String.format("Rule%s", DigestUtils.md5Hex(rule));
    }

    private static Map<String, Object> createRuleParams(RuleContext ruleContext) {
        Map<String, Object> params = new HashMap<>(1);
        params.put(RULE_CONTEXT_PARAM_NAME, ruleContext);

        return params;
    }

    private UserTransaction getUserTransaction() {
        InitialContext context = getInitialContext();
        try {
            return (UserTransaction) context.lookup("java:comp/UserTransaction");
        } catch (NameNotFoundException nnfe) {
            try {
                //Embedded JBoss has no java:comp/UserTransaction
                UserTransaction ut = (UserTransaction) context.lookup("UserTransaction");
                ut.getStatus(); //for glassfish, which can return an unusable UT
                return ut;
            } catch (Exception e) {
                throw Throwables.propagate(e);
            }
        } catch (NamingException e) {
            throw Throwables.propagate(e);
        }
    }

    private static InitialContext getInitialContext() {
        try {
            return Naming.getInitialContext();
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
    }

    public void setRuleRepository(RuleRepository<T> ruleRepository) {
        this.ruleRepository = ruleRepository;
    }

}