Package org.jbpm.db

Source Code of org.jbpm.db.GraphSession

/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jbpm.db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.jbpm.JbpmException;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;

/**
* are the graph related database operations.
*/
public class GraphSession {

  JbpmSession jbpmSession = null;
  Session session = null;
 
  public GraphSession(JbpmSession jbpmSession) {
    this.jbpmSession = jbpmSession;
    this.session = jbpmSession.getSession();
  }

  public GraphSession(Session session) {
    this.session = session;
    this.jbpmSession = new JbpmSession(session);
  }

  // process definitions //////////////////////////////////////////////////////
 
 
  public void deployProcessDefinition(ProcessDefinition processDefinition) {
    String processDefinitionName = processDefinition.getName();
    // if the process definition has a name (process versioning only applies to named process definitions)
    if (processDefinitionName!=null) {
      // find the current latest process definition
      ProcessDefinition previousLatestVersion = findLatestProcessDefinition(processDefinitionName);
      // if there is a current latest process definition
      if (previousLatestVersion!=null) {
        // take the next version number
        processDefinition.setVersion( previousLatestVersion.getVersion()+1 );
      } else {
        // start from 1
        processDefinition.setVersion(1);
      }
     
      session.save(processDefinition);
     
    } else {
      throw new JbpmException("process definition does not have a name");
    }
  }
 
  /**
   * saves the process definitions.  this method does not assign a version
   * number.  that is the responsibility of the {@link org.jbpm.jpdl.par.ProcessArchiveDeployer}.
   */
  public void saveProcessDefinition( ProcessDefinition processDefinition ) {
    try {
      session.save(processDefinition);
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't save process definition '" + processDefinition + "'", e);
    }
  }
 
  /**
   * loads a process definition from the database by the identifier.
   */
  public ProcessDefinition loadProcessDefinition(long processDefinitionId) {
    try {
      return (ProcessDefinition) session.load( ProcessDefinition.class, new Long(processDefinitionId) );
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't load process definition '" + processDefinitionId + "'", e);
    }
  }
 
  /**
   * queries the database for a process definition with the given name and version.
   */
  public ProcessDefinition findProcessDefinition(String name, int version) {
    ProcessDefinition processDefinition = null;
    try {
      Query query = session.getNamedQuery("GraphSession.findProcessDefinitionByNameAndVersion");
      query.setString("name", name);
      query.setInteger("version", version);
      processDefinition = (ProcessDefinition) query.uniqueResult();
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't get process definition with name '"+name+"' and version '"+version+"'", e);
    }
    return processDefinition;
  }
 
  /**
   * queries the database for the latest version of a process definition with the given name.
   */
  public ProcessDefinition findLatestProcessDefinition(String name) {
    ProcessDefinition processDefinition = null;
    try {
      Query query = session.getNamedQuery("GraphSession.findLatestProcessDefinitionQuery");
      query.setString("name", name);
      query.setMaxResults(1);
      processDefinition = (ProcessDefinition) query.uniqueResult();
    } catch (Exception e) {
     
      System.out.flush();
      System.err.flush();
      try {
        Thread.sleep(200);
      } catch (InterruptedException e1) {
        e1.printStackTrace();
      }
     
      e.printStackTrace(); log.error(e);
     
      System.out.flush();
      System.err.flush();

      jbpmSession.handleException();
      throw new JbpmException("couldn't find process definition '" + name + "'", e);
    }
    return processDefinition;
  }

  /**
   * queries the database for the latest version of each process definition.
   * Process definitions are distinct by name.
   */
  public List findLatestProcessDefinitions() {
    List processDefinitions = new ArrayList();
    Map processDefinitionsByName = new HashMap();
    try {
      Query query = session.getNamedQuery("GraphSession.findAllProcessDefinitions");
      Iterator iter = query.list().iterator();
      while (iter.hasNext()) {
        ProcessDefinition processDefinition = (ProcessDefinition) iter.next();
        String processDefinitionName = processDefinition.getName();
        ProcessDefinition previous = (ProcessDefinition) processDefinitionsByName.get(processDefinitionName);
        if ( (previous==null)
             || (previous.getVersion()<processDefinition.getVersion())
           ){
          processDefinitionsByName.put(processDefinitionName, processDefinition);
        }
      }
      processDefinitions = new ArrayList(processDefinitionsByName.values());
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't find latest versions of process definitions", e);
    }
    return processDefinitions;
  }

  /**
   * queries the database for all process definitions, ordered by name (ascending), then by version (descending).
   */
  public List findAllProcessDefinitions() {
    try {
      Query query = session.getNamedQuery("GraphSession.findAllProcessDefinitions");
      return query.list();
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't find all process definitions", e);
    }
  }

  /**
   * queries the database for all versions of process definitions with the given name, ordered by version (descending).
   */
  public List findAllProcessDefinitionVersions(String name) {
    try {
      Query query = session.getNamedQuery("GraphSession.findAllProcessDefinitionVersions");
      query.setString("name", name);
      return query.list();
    } catch (HibernateException e) {
      e.printStackTrace(); log.error(e);
      throw new JbpmException("couldn't find all versions of process definition '"+name+"'", e);
    }
  }

  public void deleteProcessDefinition(long processDefinitionId) {
    deleteProcessDefinition(loadProcessDefinition(processDefinitionId));
  }

  public void deleteProcessDefinition(ProcessDefinition processDefinition) {
    if (processDefinition==null) throw new NullPointerException("processDefinition is null in JbpmSession.deleteProcessDefinition()");
    try {
      // delete all the process instances of this definition
      List processInstances = findProcessInstances(processDefinition.getId());
      if (processInstances!=null) {
        Iterator iter = processInstances.iterator();
        while (iter.hasNext()) {
          deleteProcessInstance((ProcessInstance) iter.next());
        }
      }
     
      // then delete the process definition
      session.delete(processDefinition);

    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't delete process definition '" + processDefinition.getId() + "'", e);
    }
  }

  // process instances ////////////////////////////////////////////////////////
 
  /**
   * @deprecated use {@link org.jbpm.JbpmContext#save(ProcessInstance)} instead.
   * @throws UnsupportedOperationException
   */
  public void saveProcessInstance(ProcessInstance processInstance) {
    throw new UnsupportedOperationException("use JbpmContext.save(ProcessInstance) instead");
  }

  /**
   * loads a process instance from the database by the identifier.
   */
  public ProcessInstance loadProcessInstance(long processInstanceId) {
    try {
      ProcessInstance processInstance = (ProcessInstance) session.load( ProcessInstance.class, new Long(processInstanceId) );
      return processInstance;
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't load process instance '" + processInstanceId + "'", e);
    }
  }

  /**
   * loads a token from the database by the identifier.
   */
  public Token loadToken(long tokenId) {
    try {
      Token token = (Token) session.load(Token.class, new Long(tokenId));
      return token;
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't load token '" + tokenId + "'", e);
    }
  }

  /**
   * locks a process instance in the database.
   */
  public void lockProcessInstance(long processInstanceId) {
    lockProcessInstance(loadProcessInstance(processInstanceId));
  }

  /**
   * locks a process instance in the database.
   */
  public void lockProcessInstance(ProcessInstance processInstance) {
    try {
      session.lock( processInstance, LockMode.UPGRADE );
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't lock process instance '" + processInstance.getId() + "'", e);
    }
  }

  /**
   * fetches all processInstances for the given process definition from the database.
   * The returned list of process instances is sorted start date, youngest first.
   */
  public List findProcessInstances(long processDefinitionId) {
    List processInstances = null;
    try {
      Query query = session.getNamedQuery("GraphSession.findAllProcessInstancesForADefinition");
      query.setLong("processDefinitionId", processDefinitionId);
      processInstances = query.list();

    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't load process instances for process definition '" + processDefinitionId + "'", e);
    }
    return processInstances;
  }

  public void deleteProcessInstance(long processInstanceId) {
    deleteProcessInstance(loadProcessInstance(processInstanceId));
  }

  public void deleteProcessInstance(ProcessInstance processInstance) {
    deleteProcessInstance(processInstance, true, true, true);
  }

  public void deleteProcessInstance(ProcessInstance processInstance, boolean includeTasks, boolean includeTimers, boolean includeMessages) {
    if (processInstance==null) throw new NullPointerException("processInstance is null in JbpmSession.deleteProcessInstance()");
    try {
      // find the tokens
      Query query = session.getNamedQuery("GraphSession.findTokensForProcessInstance");
      query.setEntity("processInstance", processInstance);
      List tokens = query.list();
     
      // deleteSubProcesses
      Iterator iter = tokens.iterator();
      while (iter.hasNext()) {
        Token token = (Token) iter.next();
        deleteSubProcesses(token);

        // messages
        if (includeMessages) {
          query = session.getNamedQuery("GraphSession.deleteMessagesForToken");
          query.setEntity("token", token);
          query.executeUpdate();
        }
      }
     
      // tasks
      if (includeTasks) {
        query = session.getNamedQuery("GraphSession.findTaskInstanceIdsForProcessInstance");
        query.setEntity("processInstance", processInstance);
        List taskInstanceIds = query.list();
       
        query = session.getNamedQuery("GraphSession.deleteTaskInstancesById");
        query.setParameterList("taskInstanceIds", taskInstanceIds);
      }
      
      // timers
      if (includeTimers) {
        query = session.getNamedQuery("SchedulerSession.deleteTimersForProcessInstance");
        query.setEntity("processInstance", processInstance);
        query.executeUpdate();
      }
      
      // delete the logs for all the process instance's tokens
      query = session.getNamedQuery("GraphSession.selectLogsForTokens");
      query.setParameterList("tokens", tokens);
      List logs = query.list();
      iter = logs.iterator();
      while (iter.hasNext()) {
        session.delete(iter.next());
      }

      // then delete the process instance
      session.delete(processInstance);
     
    } catch (Exception e) {
      e.printStackTrace(); log.error(e);
      jbpmSession.handleException();
      throw new JbpmException("couldn't delete process instance '" + processInstance.getId() + "'", e);
    }
  }

  void deleteSubProcesses(Token token) {
    ProcessInstance subProcessInstance = token.getSubProcessInstance();
    if (subProcessInstance!=null){
      subProcessInstance.setSuperProcessToken(null);
      token.setSubProcessInstance(null);
      deleteProcessInstance(subProcessInstance);
    }
    if (token.getChildren()!=null) {
      Iterator iter = token.getChildren().values().iterator();
      while (iter.hasNext()) {
        Token child = (Token) iter.next();
        deleteSubProcesses(child);
      }
    }
  }

  private static final Log log = LogFactory.getLog(GraphSession.class);
}
TOP

Related Classes of org.jbpm.db.GraphSession

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.