Package pl.net.bluesoft.rnd.pt.ext.jbpm

Source Code of pl.net.bluesoft.rnd.pt.ext.jbpm.ProcessToolContextFactoryImpl

package pl.net.bluesoft.rnd.pt.ext.jbpm;

import com.thoughtworks.xstream.XStream;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.jbpm.api.Configuration;
import org.jbpm.api.ProcessEngine;
import pl.net.bluesoft.rnd.processtool.ProcessToolContext;
import pl.net.bluesoft.rnd.processtool.ProcessToolContextCallback;
import pl.net.bluesoft.rnd.processtool.ProcessToolContextFactory;
import pl.net.bluesoft.rnd.processtool.ReturningProcessToolContextCallback;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmConstants;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmSession;
import pl.net.bluesoft.rnd.processtool.dao.ProcessDefinitionDAO;
import pl.net.bluesoft.rnd.processtool.model.UserData;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessDefinitionConfig;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessDefinitionPermission;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessQueueConfig;
import pl.net.bluesoft.rnd.processtool.plugins.ProcessToolRegistry;
import pl.net.bluesoft.util.lang.Strings;

import javax.naming.InitialContext;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* @author tlipski@bluesoft.net.pl
*/
public class ProcessToolContextFactoryImpl implements ProcessToolContextFactory, ProcessToolBpmConstants {

    private static Logger logger = Logger.getLogger(ProcessToolContextFactoryImpl.class.getName());
    private Configuration configuration;
    private ProcessToolRegistry registry;

    public ProcessToolContextFactoryImpl(ProcessToolRegistry registry) {
        this.registry = registry;
        initJbpmConfiguration();
    }

    @Override
    public <T> T withExistingOrNewContext(ReturningProcessToolContextCallback<T> callback) {
        ProcessToolContext ctx = ProcessToolContext.Util.getThreadProcessToolContext();
        return ctx != null && ctx.isActive() ? callback.processWithContext(ctx) : withProcessToolContext(callback);
    }

    @Override
  public <T> T withProcessToolContext(ReturningProcessToolContextCallback<T> callback) {
        if (registry.isJta()) {
            return withProcessToolContextJta(callback);
        } else {
            return withProcessToolContextNonJta(callback);
        }
    }

  public <T> T withProcessToolContextNonJta(ReturningProcessToolContextCallback<T> callback) {
        T result = null;

    Session session = registry.getSessionFactory().openSession();
    try {
      ProcessEngine pi = getProcessEngine();
      try {
        Transaction tx = session.beginTransaction();
        try {
          ProcessToolContextImpl ctx = new ProcessToolContextImpl(session, this, pi);
          result = callback.processWithContext(ctx);
        } catch (RuntimeException e) {
          logger.log(Level.SEVERE, e.getMessage(), e);
          try {
            tx.rollback();
          } catch (Exception e1) {
            logger.log(Level.WARNING, e1.getMessage(), e1);
          }
          throw e;
        }
        tx.commit();
      }
      finally {
        pi.close();
      }
    } finally {
      session.close();
    }
        return result;
    }

    public <T> T withProcessToolContextJta(ReturningProcessToolContextCallback<T> callback) {
        T result = null;

        try {
            UserTransaction ut=null;
            try {
                ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
            } catch (Exception e) {
                //it should work on jboss regardless. But it does not..
                logger.warning("java:comp/UserTransaction not found, looking for UserTransaction");
                ut = (UserTransaction) new InitialContext().lookup("UserTransaction");
            }

            logger.fine("ut.getStatus() = " + ut.getStatus());
            if (ut.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
                ut.rollback();
            }
            if (ut.getStatus() != Status.STATUS_ACTIVE)
                ut.begin();
            Session session = registry.getSessionFactory().getCurrentSession();
            try {
                ProcessEngine pi = getProcessEngine();
                try {
                    try {
                        ProcessToolContextImpl ctx = new ProcessToolContextImpl(session, this, pi);
                        result = callback.processWithContext(ctx);
                    } catch (Exception e) {
                        logger.log(Level.SEVERE, e.getMessage(), e);
                        try {
                            ut.rollback();
                        } catch (Exception e1) {
                            logger.log(Level.WARNING, e1.getMessage(), e1);
                        }
                        throw e;
                    }
                } finally {
                    pi.close();
                }
            } finally {
                session.flush();
            }
            ut.commit();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;


    }

    private ProcessEngine getProcessEngine() {
        Thread t = Thread.currentThread();
        ClassLoader previousLoader = t.getContextClassLoader();
        try {
            ClassLoader newClassLoader = getClass().getClassLoader();
            t.setContextClassLoader(newClassLoader);
            return configuration.buildProcessEngine();
        } finally {
            t.setContextClassLoader(previousLoader);
        }
    }

    @Override
    public ProcessToolRegistry getRegistry() {
        return registry;
    }


    @Override
    public void deployOrUpdateProcessDefinition(final InputStream bpmStream,
                                                final ProcessDefinitionConfig cfg,
                                                final ProcessQueueConfig[] queues,
                                                final InputStream imageStream,
                                                final InputStream logoStream) {
        withProcessToolContext(new ProcessToolContextCallback() {
            @Override
            public void withContext(ProcessToolContext processToolContext) {

                ProcessToolContext.Util.setThreadProcessToolContext(processToolContext);
                try {
                    boolean skipJbpm = false;
                    InputStream is = bpmStream;
                    ProcessToolBpmSession session = processToolContext.getProcessToolSessionFactory().createSession(
                            new UserData("admin", "admin@aperteworkflow.org", "Admin"), Arrays.asList("ADMIN"));
                    if (cfg.getPermissions() != null) {
                        for (ProcessDefinitionPermission p : cfg.getPermissions()) {
                            if (!Strings.hasText(p.getPrivilegeName())) {
                                p.setPrivilegeName(PRIVILEGE_INCLUDE);
                            }
                            if (!Strings.hasText(p.getRoleName())) {
                                p.setRoleName(PATTERN_MATCH_ALL);
                            }
                        }
                    }
                    byte[] oldDefinition = session.getProcessLatestDefinition(cfg.getBpmDefinitionKey(), cfg.getProcessName());
                    if (oldDefinition != null) {
                        byte[] newDefinition = loadBytesFromStream(is);
                        is = new ByteArrayInputStream(newDefinition);
                        if (Arrays.equals(newDefinition, oldDefinition)) {
                            logger.log(Level.WARNING, "bpm definition for " + cfg.getProcessName() +
                                    " is the same as in BPM, therefore not updating BPM process definition");
                            skipJbpm = true;
                        }
                    }

                    if (!skipJbpm) {
                        String deploymentId = session.deployProcessDefinition(cfg.getProcessName(), is, imageStream);
                        logger.log(Level.INFO, "deployed new BPM Engine definition with id: " + deploymentId);
                    }

                    ProcessDefinitionDAO processDefinitionDAO = processToolContext.getProcessDefinitionDAO();
                    processDefinitionDAO.updateOrCreateProcessDefinitionConfig(cfg);
                    logger.log(Level.INFO, "created  definition with id: " + cfg.getId());
                    if (queues != null && queues.length > 0) {
                        processDefinitionDAO.updateOrCreateQueueConfigs(Arrays.asList(queues));
                        logger.log(Level.INFO, "created/updated " + queues.length + " queues");
                    }
                } finally {
                    ProcessToolContext.Util.removeThreadProcessToolContext();
                }
            }
        });
    }

    @Override
    public void deployOrUpdateProcessDefinition(InputStream jpdlStream,
                                                InputStream processToolConfigStream,
                                                InputStream queueConfigStream,
                                                final InputStream imageStream,
                                                final InputStream logoStream) {
        if (jpdlStream == null || processToolConfigStream == null || queueConfigStream == null) {
            throw new IllegalArgumentException("at least one of the streams is null");
        }
        XStream xstream = new XStream();
        xstream.aliasPackage("config", ProcessDefinitionConfig.class.getPackage().getName());
        xstream.useAttributeFor(String.class);
        xstream.useAttributeFor(Boolean.class);
        xstream.useAttributeFor(Integer.class);

        ProcessDefinitionConfig config = (ProcessDefinitionConfig) xstream.fromXML(processToolConfigStream);

        if (logoStream != null) {
            byte[] logoBytes = loadBytesFromStream(logoStream);
            if (logoBytes.length > 0) {
                config.setProcessLogo(logoBytes);
            }
        }
        Collection<ProcessQueueConfig> qConfigs = (Collection<ProcessQueueConfig>) xstream.fromXML(queueConfigStream);
        deployOrUpdateProcessDefinition(jpdlStream,
                config,
                qConfigs.toArray(new ProcessQueueConfig[qConfigs.size()]),
                imageStream,
                logoStream);
    }

//    }

    private byte[] loadBytesFromStream(InputStream stream) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int c;
        try {
            while ((c = stream.read()) >= 0) {
                bos.write(c);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return bos.toByteArray();
    }

    public void updateSessionFactory(SessionFactory sf) {
        if (configuration != null) {
            configuration.setHibernateSessionFactory(sf);
        }
    }

    public void initJbpmConfiguration() {
        Thread t = Thread.currentThread();
        ClassLoader previousLoader = t.getContextClassLoader();
        try {
            ClassLoader newClassLoader = getClass().getClassLoader();
            t.setContextClassLoader(newClassLoader);
            configuration = new Configuration();
            configuration.setHibernateSessionFactory(registry.getSessionFactory());
        } finally {
            t.setContextClassLoader(previousLoader);
        }
    }

}
TOP

Related Classes of pl.net.bluesoft.rnd.pt.ext.jbpm.ProcessToolContextFactoryImpl

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.