[jboss-cvs] jboss-seam/src/main/org/jboss/seam/bpm ...

Gavin King gavin.king at jboss.com
Tue Jun 19 15:12:44 EDT 2007


  User: gavin   
  Date: 07/06/19 15:12:44

  Added:       src/main/org/jboss/seam/bpm               Actor.java
                        BusinessProcess.java Jbpm.java
                        ManagedJbpmContext.java PooledTask.java
                        PooledTaskInstanceList.java ProcessInstance.java
                        ProcessInstanceFinder.java TaskInstance.java
                        TaskInstanceList.java TaskInstanceListForType.java
                        TaskInstancePriorityList.java Transition.java
                        package-info.java
  Log:
  repackaged built-in components
  sorry for breakage, but it had to happen eventually :-(
  
  Revision  Changes    Path
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/Actor.java
  
  Index: Actor.java
  ===================================================================
  package org.jboss.seam.bpm;
  import static org.jboss.seam.InterceptionType.NEVER;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  import java.io.Serializable;
  import java.util.HashSet;
  import java.util.Set;
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.AbstractMutable;
  /**
   * Allows the application to specify the jBPM actorId
   * during the login cycle.
   * 
   * @author Gavin King
   */
  @Name("org.jboss.seam.core.actor")
  @Scope(ScopeType.SESSION)
  @Intercept(NEVER)
  @Install(dependencies="org.jboss.seam.core.jbpm", precedence=BUILT_IN)
  public class Actor extends AbstractMutable implements Serializable
  {
     private static final long serialVersionUID = -6515302276074415520L;
     private String id;
     private Set<String> groupActorIds = new HashSet<String>();
     //TODO: dirtyness for groupActorIds
     public String getId() 
     {
        return id;
     }
     public void setId(String id) 
     {
        setDirty(this.id, id);
        this.id = id;
     }
   
     public Set<String> getGroupActorIds()
     {
        return groupActorIds;
     }
     public static Actor instance()
     {
        if ( !Contexts.isSessionContextActive() )
        {
           throw new IllegalStateException("No active session context");
        }
        return (Actor) Component.getInstance(Actor.class, true);
     }
     
     @Override
     public String toString()
     {
        return "Actor(" + id + ")";
     }  
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/BusinessProcess.java
  
  Index: BusinessProcess.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.io.Serializable;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.AbstractMutable;
  import org.jboss.seam.core.Events;
  import org.jbpm.graph.def.ProcessDefinition;
  import org.jbpm.graph.exe.ProcessInstance;
  import org.jbpm.taskmgmt.exe.TaskInstance;
  
  /**
   * Holds the task and process ids for the current conversation,
   * and provides programmatic control over the business process.
   * 
   * @author Gavin King
   *
   */
  @Scope(ScopeType.CONVERSATION)
  @Name("org.jboss.seam.core.businessProcess")
  @Intercept(NEVER)
  @Install(dependencies="org.jboss.seam.core.jbpm", precedence=BUILT_IN)
  public class BusinessProcess extends AbstractMutable implements Serializable 
  {
  
     private static final long serialVersionUID = 4722350870845851070L;
     private Long processId;
     private Long taskId;
     
     public static BusinessProcess instance()
     {
        if ( !Contexts.isConversationContextActive() )
        {
           throw new IllegalStateException("No active conversation context");
        }
        return (BusinessProcess) Component.getInstance(BusinessProcess.class, ScopeType.CONVERSATION);
     }
     
     /**
      * Is there a process instance associated with 
      * the current conversation?
      */
     public boolean hasCurrentProcess()
     {
        return processId!=null;
     }
     
     /**
      * Is there a process instance that has not ended 
      * associated with the current conversation?
      */
     public boolean hasActiveProcess()
     {
        return hasCurrentProcess() && 
              !org.jboss.seam.bpm.ProcessInstance.instance().hasEnded();
     }
     
     /**
      * Is there a task instance associated with 
      * the current conversation?
      */
     public boolean hasCurrentTask()
     {
        return taskId!=null;
     }
     
     /**
      * The jBPM process instance id associated with
      * the current conversation.
      */
     public Long getProcessId() 
     {
        return processId;
     }
     
     /**
      * Set the process instance id, without validating
      * that the process instance actually exists.
      */
     public void setProcessId(Long processId) 
     {
        setDirty(this.processId, processId);
        this.processId = processId;
     }
     
     /**
      * The jBPM task instance id associated with
      * the current conversation.
      */
     public Long getTaskId() 
     {
        return taskId;
     }
     
     /**
      * Set the task instance id, without validating
      * that the task instance actually exists.
      */
     public void setTaskId(Long taskId) 
     {
        setDirty(this.taskId, taskId);
        this.taskId = taskId;
     }
     
     /**
      * Create a process instance and associate it with the
      * current conversation.
      * 
      * @param processDefinitionName the jBPM process definition name
      */
     public void createProcess(String processDefinitionName)
     {
        ProcessInstance process = ManagedJbpmContext.instance().newProcessInstanceForUpdate(processDefinitionName);
        afterCreateProcess(processDefinitionName, process);
     }
  
     /**
      * Create a process instance and associate it with the
      * current conversation.
      * 
      * @param processDefinitionName the jBPM process definition name
      * @param businessKey the business key of the new process definition
      */
     public void createProcess(String processDefinitionName, String businessKey)
     {
        /*ProcessInstance process = ManagedJbpmContext.instance().getGraphSession()
                 .findLatestProcessDefinition(processDefinitionName)
                 .createProcessInstance(Collections.EMPTY_MAP, businessKey);*/
        ProcessInstance process = ManagedJbpmContext.instance().newProcessInstanceForUpdate(processDefinitionName);
        process.setKey(businessKey);
        afterCreateProcess(processDefinitionName, process);
     }
     
     private void afterCreateProcess(String processDefinitionName, ProcessInstance process)
     {
        setProcessId( process.getId() );
        // need to set process variables before the signal
        Contexts.getBusinessProcessContext().flush();
        process.signal();
        
        Events.instance().raiseEvent("org.jboss.seam.createProcess." + processDefinitionName);
     }
     
     /**
      * Start the current task, using the current actor id
      * 
      * @see Actor
      */
     public void startTask()
     {
        String actorId = Actor.instance().getId();
        TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
        if ( actorId != null )
        {
           task.start(actorId);
        }
        else
        {
           task.start();
        }
        
        Events.instance().raiseEvent("org.jboss.seam.startTask." + task.getTask().getName());
     }
     
     /**
      * End the current task, via the given transition. If no transition name 
      * is given, check the Transition component for a transition, or use the 
      * default transition.
      * 
      * @param transitionName the jBPM transition name, or null
      */
     public void endTask(String transitionName)
     {
        TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
        if (task==null)
        {
           throw new IllegalStateException( "no task instance associated with context" );
        }
        
        if ( transitionName==null || "".equals(transitionName) )
        {
           transitionName = Transition.instance().getName();
        }
        
        if (transitionName==null)
        {
           task.end();
        }
        else
        {
           task.end(transitionName);
        }
        
        setTaskId(null); //TODO: do I really need this???!
        
        Events.instance().raiseEvent("org.jboss.seam.endTask." + task.getTask().getName());
        ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
        if ( process.hasEnded() )
        {
           Events.instance().raiseEvent("org.jboss.seam.endProcess." + process.getProcessDefinition().getName());
        }
     }
     
     /**
      * Signal the given transition for the current process instance.
      * 
      * @param transitionName the jBPM transition name 
      */
     public void transition(String transitionName)
     {
        ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
        process.signal(transitionName);
        if ( process.hasEnded() )
        {
           Events.instance().raiseEvent("org.jboss.seam.endProcess." + process.getProcessDefinition().getName());
        }
     }
     
     /**
      * Associate the task instance with the given id with the current
      * conversation.
      * 
      * @param taskId the jBPM task instance id
      * @return true if the task was found and was not ended
      */
     public boolean resumeTask(Long taskId)
     {
        setTaskId(taskId);
        TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
        if (task==null)
        {
           taskNotFound(taskId);
           return false;
        }
        else if ( task.hasEnded() )
        {
           taskEnded(taskId);
           return false;
        }
        else
        {
           setProcessId( task.getTaskMgmtInstance().getProcessInstance().getId() );
           Events.instance().raiseEvent("org.jboss.seam.initTask." + task.getTask().getName());
           return true;
        }
     }
     
     /**
      * Associate the process instance with the given id with the 
      * current conversation.
      * 
      * @param processId the jBPM process instance id
      * @return true if the process was found and was not ended
      */
     public boolean resumeProcess(Long processId)
     {
        setProcessId(processId);
        ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
        return afterResumeProcess(processId, process);
     }
     
     /**
      * Associate the process instance with the given business key 
      * with the current conversation.
      * 
      * @param processDefinition the jBPM process definition name
      * @param key the jBPM process instance key
      * @return true if the process was found and was not ended
      */
     public boolean resumeProcess(String processDefinition, String key)
     {
        ProcessDefinition definition = ManagedJbpmContext.instance().getGraphSession().findLatestProcessDefinition(processDefinition);
        ProcessInstance process = definition==null ? 
                 null : ManagedJbpmContext.instance().getProcessInstanceForUpdate(definition, key);
        if (process!=null) setProcessId( process.getId() );
        return afterResumeProcess(key, process);
     }
  
     private boolean afterResumeProcess(long processId, ProcessInstance process)
     {
        if ( process==null )
        {
           processNotFound(processId);
           return false;
        }
        else if ( process.hasEnded() )
        {
           processEnded(processId);
           return false;
        }
        else
        {
           Events.instance().raiseEvent("org.jboss.seam.initProcess." + process.getProcessDefinition().getName());
           return true;
        }
     }
     
     private boolean afterResumeProcess(String processKey, ProcessInstance process)
     {
        if ( process==null )
        {
           processNotFound(processKey);
           return false;
        }
        else if ( process.hasEnded() )
        {
           processEnded(processKey);
           return false;
        }
        else
        {
           Events.instance().raiseEvent("org.jboss.seam.initProcess." + process.getProcessDefinition().getName());
           return true;
        }
     }
     
     /**
      * Check that the task currently associated with the conversation
      * exists and has not ended.
      * 
      * @return true if the task exists and was not ended
      */
     public boolean validateTask()
     {
        if ( !hasCurrentTask() )
        {
           taskNotFound(taskId);
           return false;
        }
        else if ( org.jboss.seam.bpm.TaskInstance.instance().hasEnded() )
        {
           taskEnded(taskId);
           return false;
        }
        else
        {
           return true;
        }
     }
     
     protected void taskNotFound(Long taskId)
     {
        
     }
     
     protected void taskEnded(Long taskId)
     {
        
     }
     
     protected void processEnded(Long processId)
     {
        
     }
     
     protected void processNotFound(Long processId)
     {
        
     }
     
     protected void processEnded(String key)
     {
        
     }
     
     protected void processNotFound(String key)
     {
        
     }
     
     @Override
     public String toString()
     {
        return "BusinessProcess(processId=" + processId + ",taskId=" + taskId + ")";
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/Jbpm.java
  
  Index: Jbpm.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.io.InputStream;
  import java.io.StringReader;
  import java.util.HashMap;
  import java.util.Hashtable;
  import java.util.Map;
  import java.util.Properties;
  
  import javax.naming.NamingException;
  
  import org.dom4j.Element;
  import org.hibernate.HibernateException;
  import org.hibernate.cfg.Environment;
  import org.hibernate.lob.ReaderInputStream;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Destroy;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Startup;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.Init;
  import org.jboss.seam.jbpm.SeamFunctionMapper;
  import org.jboss.seam.jbpm.SeamUserCodeInterceptor;
  import org.jboss.seam.jbpm.SeamVariableResolver;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.pageflow.PageflowHelper;
  import org.jboss.seam.util.Naming;
  import org.jboss.seam.util.Resources;
  import org.jbpm.JbpmConfiguration;
  import org.jbpm.JbpmContext;
  import org.jbpm.graph.def.ProcessDefinition;
  import org.jbpm.graph.node.DbSubProcessResolver;
  import org.jbpm.graph.node.ProcessState;
  import org.jbpm.graph.node.SubProcessResolver;
  import org.jbpm.instantiation.UserCodeInterceptorConfig;
  import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
  import org.jbpm.persistence.db.DbPersistenceServiceFactory;
  import org.xml.sax.InputSource;
  
  /**
   * A seam component that boostraps a JBPM SessionFactory
   * 
   * @author Gavin King
   * @author <a href="mailto:steve at hibernate.org">Steve Ebersole</a>
   * @author Norman Richards
   * @author <a href="mailto:theute at jboss.org">Thomas Heute</a>
   */
  @Scope(ScopeType.APPLICATION)
  @Intercept(NEVER)
  @Startup
  @Name("org.jboss.seam.core.jbpm")
  @Install(value=false, precedence=BUILT_IN)
  public class Jbpm 
  {
     private static final LogProvider log = Logging.getLogProvider(Jbpm.class);
     
     private JbpmConfiguration jbpmConfiguration;
     private String jbpmConfigurationJndiName;
     private String[] processDefinitions;
     private String[] pageflowDefinitions;
     private Map<String, ProcessDefinition> pageflowProcessDefinitions = new HashMap<String, ProcessDefinition>();
  
     @Create
     public void startup() throws Exception
     {
        log.trace( "Starting jBPM" );
        ProcessState.setDefaultSubProcessResolver( new SeamSubProcessResolver() );
        installProcessDefinitions();
        installPageflowDefinitions();
        JbpmExpressionEvaluator.setVariableResolver( new SeamVariableResolver() );
        JbpmExpressionEvaluator.setFunctionMapper( new SeamFunctionMapper() );
        UserCodeInterceptorConfig.setUserCodeInterceptor( new SeamUserCodeInterceptor() );
     }
  
     @Destroy
     public void shutdown()
     {
        if (jbpmConfiguration!=null) 
        {
           jbpmConfiguration.close();
        }
     }
     
     public JbpmConfiguration getJbpmConfiguration()
     {
        if (jbpmConfiguration==null)
        {
           initJbpmConfiguration();
        }
        return jbpmConfiguration;
     }
  
     private void initJbpmConfiguration()
     {
        if (jbpmConfigurationJndiName==null)
        {
           jbpmConfiguration = JbpmConfiguration.getInstance();
        }
        else
        {
           try
           {
              jbpmConfiguration = (JbpmConfiguration) Naming.getInitialContext().lookup(jbpmConfigurationJndiName);
           }
           catch (NamingException ne)
           {
              throw new IllegalArgumentException("JbpmConfiguration not found in JNDI", ne);
           }
        }
  
        DbPersistenceServiceFactory dbpsf = (DbPersistenceServiceFactory) jbpmConfiguration.getServiceFactory("persistence");
        if (Naming.getInitialContextProperties()!=null)
        {
           // Prefix regular JNDI properties for Hibernate
           Hashtable<String, String> hash = Naming.getInitialContextProperties();
           Properties prefixed = new Properties();
           for (Map.Entry<String, String> entry: hash.entrySet() )
           {
              prefixed.setProperty( Environment.JNDI_PREFIX + "." + entry.getKey(), entry.getValue() );
           }
           
           try
           {
              dbpsf.getConfiguration().getProperties().putAll(prefixed);
           }
           catch (HibernateException he)
           {
              log.info("could not set JNDI properties for jBPM persistence: " + he.getMessage());
           }
        }
     }
  
     public ProcessDefinition getPageflowProcessDefinition(String pageflowName)
     {
        return pageflowProcessDefinitions.get(pageflowName);
     }
     
     public boolean isPageflowProcessDefinition(String pageflowName)
     {
        return pageflowProcessDefinitions.containsKey(pageflowName);
     }
     
     public ProcessDefinition getPageflowDefinitionFromResource(String resourceName)
     {
        InputStream resource = Resources.getResourceAsStream(resourceName);
        if (resource==null)
        {
           throw new IllegalArgumentException("pageflow resource not found: " + resourceName);
        }
        return PageflowHelper.parseInputSource( new InputSource(resource) );
     }
     
     public ProcessDefinition getProcessDefinitionFromResource(String resourceName) 
     {
        InputStream resource = Resources.getResourceAsStream(resourceName);
        if (resource==null)
        {
           throw new IllegalArgumentException("process definition resource not found: " + resourceName);
        }
        return ProcessDefinition.parseXmlInputStream(resource);
     }
  
     public String[] getPageflowDefinitions() 
     {
        return pageflowDefinitions;
     }
  
     public void setPageflowDefinitions(String[] pageflowDefinitions) 
     {
        this.pageflowDefinitions = pageflowDefinitions;
     }
     
     public String[] getProcessDefinitions() 
     {
        return processDefinitions;
     }
  
     public void setProcessDefinitions(String[] processDefinitions) 
     {
        this.processDefinitions = processDefinitions;
     }
     
     /**
      * Dynamically deploy a page flow definition, if a pageflow with an 
      * identical name already exists, the pageflow is updated.
      * 
      * @return true if the pageflow definition has been updated
      */
     public boolean deployPageflowDefinition(ProcessDefinition pageflowDefinition) 
     {
        return pageflowProcessDefinitions.put( pageflowDefinition.getName(), pageflowDefinition )!=null;
     }
     
     /**
      * Read a pageflow definition
      * 
      * @param pageflowDefinition the pageflow as an XML string
      */
     public ProcessDefinition getPageflowDefinitionFromXml(String pageflowDefinition)
     {
        return PageflowHelper.parseInputSource( new InputSource( new ReaderInputStream( new StringReader(pageflowDefinition) ) ) );
     }
     
     /**
      * Read a process definition
      * 
      * @param processDefinition the process as an XML string
      */
     public ProcessDefinition getProcessDefinitionFromXml(String processDefinition)
     {
        return ProcessDefinition.parseXmlInputStream( new ReaderInputStream( new StringReader(processDefinition) ) );
     }
     
     /**
      * Remove a pageflow definition
      * 
      * @param pageflowName Name of the pageflow to remove
      * @return true if the pageflow definition has been removed
      */
     public boolean undeployPageflowDefinition(String pageflowName) 
     {     
        return pageflowProcessDefinitions.remove(pageflowName)!=null;
     }
     
     private void installPageflowDefinitions() {
        if ( pageflowDefinitions!=null )
        {
           for (String pageflow: pageflowDefinitions)
           {
              ProcessDefinition pd = getPageflowDefinitionFromResource(pageflow);
              pageflowProcessDefinitions.put( pd.getName(), pd );
           }
        }
     }
  
     private void installProcessDefinitions()
     {
        if ( processDefinitions!=null && processDefinitions.length>0 )
        {
           JbpmContext jbpmContext = getJbpmConfiguration().createJbpmContext();
           try
           {
              for ( String definitionResource : processDefinitions )
              {
                 ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource( definitionResource );
                 if (log.isDebugEnabled())
                 {
                    log.debug( "deploying process definition : " + processDefinition.getName() );
                 }
                 jbpmContext.deployProcessDefinition(processDefinition);
              }
           }
           catch (RuntimeException e)
           {
              throw new RuntimeException("could not deploy a process definition", e);
           }
           finally
           {
              jbpmContext.close();
           }
        }
     }
     
     public static Jbpm instance()
     {
        if ( !Contexts.isApplicationContextActive() )
        {
           throw new IllegalStateException("No application context active");
        }
        if ( !Init.instance().isJbpmInstalled() )
        {
           throw new IllegalStateException("jBPM support is not installed (use components.xml to install it)");
        }
        return (Jbpm) Contexts.getApplicationContext().get(Jbpm.class);
     }
  
     protected String getJbpmConfigurationJndiName()
     {
        return jbpmConfigurationJndiName;
     }
  
     protected void setJbpmConfigurationJndiName(String jbpmConfigurationJndiName)
     {
        this.jbpmConfigurationJndiName = jbpmConfigurationJndiName;
     }
     
     private static final DbSubProcessResolver DB_SUB_PROCESS_RESOLVER = new DbSubProcessResolver();
     class SeamSubProcessResolver implements SubProcessResolver
     {
        public ProcessDefinition findSubProcess(Element element)
        {
           String subProcessName = element.attributeValue("name");
           ProcessDefinition pageflow = pageflowProcessDefinitions.get(subProcessName);
           return pageflow==null ? DB_SUB_PROCESS_RESOLVER.findSubProcess(element) : pageflow;
        }
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/ManagedJbpmContext.java
  
  Index: ManagedJbpmContext.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import javax.naming.NamingException;
  import javax.transaction.RollbackException;
  import javax.transaction.Synchronization;
  import javax.transaction.SystemException;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Destroy;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.async.LocalTransactionListener;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.contexts.Lifecycle;
  import org.jboss.seam.core.TransactionListener;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.transaction.Transaction;
  import org.jbpm.JbpmContext;
  import org.jbpm.persistence.db.DbPersistenceServiceFactory;
  import org.jbpm.svc.Services;
  
  /**
   * Manages a reference to a JbpmContext.
   *
   * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
   * @author Gavin King
   */
  @Scope(ScopeType.EVENT)
  @Name("org.jboss.seam.core.jbpmContext")
  @Intercept(NEVER)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class ManagedJbpmContext implements Synchronization
  {
     private static final LogProvider log = Logging.getLogProvider(ManagedJbpmContext.class);
  
     private JbpmContext jbpmContext;
     private boolean synchronizationRegistered;
  
     @Create
     public void create() throws NamingException, RollbackException, SystemException
     {
        jbpmContext = Jbpm.instance().getJbpmConfiguration().createJbpmContext();
        assertNoTransactionManagement();
        log.debug( "created seam managed jBPM context");
     }
  
     private void assertNoTransactionManagement()
     {
        DbPersistenceServiceFactory dpsf = (DbPersistenceServiceFactory) jbpmContext.getJbpmConfiguration()
              .getServiceFactory(Services.SERVICENAME_PERSISTENCE);
        if ( dpsf.isTransactionEnabled() )
        {
           throw new IllegalStateException("jBPM transaction management is enabled, disable in jbpm.cfg.xml");
        }
     }
  
     @Unwrap
     public JbpmContext getJbpmContext() throws NamingException, RollbackException, SystemException
     {
        if ( !Transaction.instance().isActiveOrMarkedRollback() )
        {
           throw new IllegalStateException("JbpmContext may only be used inside a transaction");
        }
        if ( !synchronizationRegistered && !Lifecycle.isDestroying() && Transaction.instance().isActive() )
        {
           jbpmContext.getSession().isOpen();
           LocalTransactionListener transactionListener = TransactionListener.instance();
           if (transactionListener!=null)
           {
              transactionListener.registerSynchronization(this);
           }
           else
           {
              jbpmContext.getSession().getTransaction().registerSynchronization(this);
           }
           synchronizationRegistered = true;
        }
        return jbpmContext;
     }
     
     public void beforeCompletion()
     {
        log.debug( "flushing seam managed jBPM context" );
        /*org.jbpm.graph.exe.ProcessInstance processInstance = ProcessInstance.instance();
        if (processInstance!=null)
        {
           jbpmContext.save(processInstance);
        }*/
        if ( Contexts.isBusinessProcessContextActive() )
        {
           //in requests that come through SeamPhaseListener,
           //transactions are committed before the contexts are
           //destroyed, flush here:
           Contexts.getBusinessProcessContext().flush();
        }
        jbpmContext.getSession().flush();
        log.debug( "done flushing seam managed jBPM context" );
     }
     
     public void afterCompletion(int status) 
     {
        synchronizationRegistered = false;
        if ( !Contexts.isEventContextActive() )
        {
           //in calls to MDBs and remote calls to SBs, the 
           //transaction doesn't commit until after contexts
           //are destroyed, so wait until the transaction
           //completes before closing the session
           //on the other hand, if we still have an active
           //event context, leave it open
           closeContext();
        }
     }
     
     @Destroy
     public void destroy()
     {
        if ( !synchronizationRegistered )
        {
           //in requests that come through SeamPhaseListener,
           //there can be multiple transactions per request,
           //but they are all completed by the time contexts
           //are dstroyed
           //so wait until the end of the request to close
           //the session
           //on the other hand, if we are still waiting for
           //the transaction to commit, leave it open
           closeContext();
        }
     }
  
     private void closeContext()
     {
        log.debug( "destroying seam managed jBPM context" );
        jbpmContext.close();
        log.debug( "done destroying seam managed jBPM context" );
     }
        
     public static JbpmContext instance()
     {
        if ( !Contexts.isEventContextActive() )
        {
           throw new IllegalStateException("no active event context");
        }
        return (JbpmContext) Component.getInstance(ManagedJbpmContext.class, ScopeType.EVENT);
     }
  
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/PooledTask.java
  
  Index: PooledTask.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Transactional;
  import org.jboss.seam.web.Parameters;
  import org.jbpm.taskmgmt.exe.TaskInstance;
  
  /**
   * Support for assigning tasks in the pooled task list.
   * 
   * @see TaskInstanceList
   * @author Gavin King
   */
  @Name("org.jboss.seam.core.pooledTask")
  @Scope(ScopeType.APPLICATION)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class PooledTask
  {
     
     /**
      * Assign the TaskInstance with the id passed
      * in the request parameter named "taskId" to
      * the current actor.
      * 
      * @see Actor
      * @return a null outcome only if the task was not found
      */
     @Transactional
     public String assignToCurrentActor()
     {
        Actor actor = Actor.instance();
        if ( actor.getId()==null )
        {
           throw new IllegalStateException("no current actor id defined");
        }
        TaskInstance taskInstance = getTaskInstance();
        if (taskInstance!=null)
        {
           taskInstance.setActorId( actor.getId() );
           return "taskAssignedToActor";
        }
        else
        {
           return null;
        }
     }
     
     /**
      * Assign the TaskInstance with the id passed
      * in the request parameter named "taskId" to
      * the given actor id.
      * 
      * @param actorId the jBPM actor id
      * @return a null outcome only if the task was not found
      */
     @Transactional
     public String assign(String actorId)
     {
        TaskInstance taskInstance = getTaskInstance();
        if (taskInstance!=null)
        {
           taskInstance.setActorId(actorId);
           return "taskAssigned";
        }
        else
        {
           return null;
        }
     }
     
     /**
      * @return the TaskInstance with the id passed
      * in the request parameter named "taskId".
      */
     @Transactional
     public TaskInstance getTaskInstance()
     {
        String[] values = Parameters.instance().getRequestParameters().get("taskId");
        if ( values==null || values.length!=1 ) 
        {
           return null;
        }
        else
        {
           String taskId = values[0];
           return taskId==null ? 
                 null : 
                 ManagedJbpmContext.instance().getTaskInstanceForUpdate( Long.parseLong(taskId) );
        }
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/PooledTaskInstanceList.java
  
  Index: PooledTaskInstanceList.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Transactional;
  import org.jboss.seam.annotations.Unwrap;
  import org.jbpm.taskmgmt.exe.TaskInstance;
  
  /**
   * Support for the pooled task list.
   * 
   * @see TaskInstanceList
   * @author Gavin King
   */
  @Name("org.jboss.seam.core.pooledTaskInstanceList")
  @Scope(ScopeType.APPLICATION)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class PooledTaskInstanceList
  {
     
     @Unwrap
     @Transactional
     public List<TaskInstance> getPooledTaskInstanceList()
     {
        return ManagedJbpmContext.instance()
              .getGroupTaskList( new ArrayList( Actor.instance().getGroupActorIds() ) );
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/ProcessInstance.java
  
  Index: ProcessInstance.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.InterceptionType;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.util.Work;
  
  /**
   * A Seam component that allows injection of the current
   * jBPM ProcessInstance.
   * 
   * @author Gavin King
   */
  @Scope(ScopeType.STATELESS)
  @Name("org.jboss.seam.core.processInstance")
  @Intercept(InterceptionType.NEVER)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class ProcessInstance 
  {
     
     @Unwrap
     public org.jbpm.graph.exe.ProcessInstance getProcessInstance() throws Exception
     {
        if ( !Contexts.isConversationContextActive() ) return null;
        
        return new Work<org.jbpm.graph.exe.ProcessInstance>()
        {
           
           @Override
           protected org.jbpm.graph.exe.ProcessInstance work() throws Exception
           {         
              Long processId = BusinessProcess.instance().getProcessId();
              if (processId!=null)
              {
                 //TODO: do we need to cache this??
                 return ManagedJbpmContext.instance().getProcessInstanceForUpdate(processId);
              }
              else
              {
                 return null;
              }
           }
           
        }.workInTransaction();
        
     }
     
     public static org.jbpm.graph.exe.ProcessInstance instance()
     {
        if ( !Contexts.isConversationContextActive() || !BusinessProcess.instance().hasCurrentProcess() ) return null; //so we don't start a txn
        
        return (org.jbpm.graph.exe.ProcessInstance) Component.getInstance(ProcessInstance.class, ScopeType.STATELESS);
     }
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/ProcessInstanceFinder.java
  
  Index: ProcessInstanceFinder.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.hibernate.criterion.Order.asc;
  import static org.hibernate.criterion.Order.desc;
  import static org.hibernate.criterion.Restrictions.isNotNull;
  import static org.hibernate.criterion.Restrictions.isNull;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.util.List;
  
  import org.hibernate.Criteria;
  import org.hibernate.criterion.Restrictions;
  import org.jboss.seam.annotations.Factory;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Transactional;
  import org.jbpm.graph.exe.ProcessInstance;
  
  /**
   * Support for the process list.
   * 
   * @author Gavin King
   */
  @Name("org.jboss.seam.core.processInstanceFinder")
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class ProcessInstanceFinder
  {
     
     private String processDefinitionName;
     private String nodeName;
     private Boolean processInstanceEnded = false;
     private Boolean sortDescending = false;
     
     @Factory("org.jboss.seam.core.processInstanceList")
     @Transactional
     public List<ProcessInstance> getProcessInstanceList()
     {
        Criteria query = ManagedJbpmContext.instance().getSession()
                    .createCriteria(ProcessInstance.class);
        if ( processInstanceEnded!=null )
        {
           query.add( processInstanceEnded ? isNotNull("end") : isNull("end") );
        }
        
        if (processDefinitionName!=null)
        {
           query.createCriteria("processDefinition")
                 .add( Restrictions.eq("name", processDefinitionName) );
        }
        
        query = query.createCriteria("rootToken");
        if (sortDescending!=null)
        {
           query.addOrder( sortDescending ? desc("nodeEnter") : asc("nodeEnter") );
        }
        if (nodeName!=null)
        {
           query.createCriteria("node")
                 .add( Restrictions.eq("name", nodeName) );
        }
        
        return query.list();
     }
  
     protected String getNodeName()
     {
        return nodeName;
     }
  
     protected void setNodeName(String nodeName)
     {
        this.nodeName = nodeName;
     }
  
     protected String getProcessDefinitionName()
     {
        return processDefinitionName;
     }
  
     protected void setProcessDefinitionName(String processDefinitionName)
     {
        this.processDefinitionName = processDefinitionName;
     }
  
     protected Boolean isSortDescending()
     {
        return sortDescending;
     }
  
     protected void setSortDescending(Boolean sortDescending)
     {
        this.sortDescending = sortDescending;
     }
  
     protected Boolean getProcessInstanceEnded()
     {
        return processInstanceEnded;
     }
  
     protected void setProcessInstanceEnded(Boolean ended)
     {
        this.processInstanceEnded = ended;
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/TaskInstance.java
  
  Index: TaskInstance.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.InterceptionType;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.util.Work;
  
  /**
   * A Seam component that allows injection of the current
   * jBPM TaskInstance.
   * 
   * @author Gavin King
   * @version $Revision: 1.1 $
   */
  @Scope(ScopeType.STATELESS)
  @Name("org.jboss.seam.core.taskInstance")
  @Intercept(InterceptionType.NEVER)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class TaskInstance 
  {
     
     @Unwrap
     public org.jbpm.taskmgmt.exe.TaskInstance getTaskInstance() throws Exception
     {
        if ( !Contexts.isConversationContextActive() ) return null;
        
        return new Work<org.jbpm.taskmgmt.exe.TaskInstance>()
        {
           
           @Override
           protected org.jbpm.taskmgmt.exe.TaskInstance work() throws Exception
           {         
              Long taskId = BusinessProcess.instance().getTaskId();
              if (taskId!=null)
              {
                 //TODO: do we need to cache this??
                 return ManagedJbpmContext.instance().getTaskInstanceForUpdate(taskId);
              }
              else
              {
                 return null;
              }
           }
           
        }.workInTransaction();
     }
     
     public static org.jbpm.taskmgmt.exe.TaskInstance instance()
     {
        if ( !Contexts.isConversationContextActive() || !BusinessProcess.instance().hasCurrentTask() ) return null; //so we don't start a txn
        
        return (org.jbpm.taskmgmt.exe.TaskInstance) Component.getInstance(TaskInstance.class, ScopeType.STATELESS);
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/TaskInstanceList.java
  
  Index: TaskInstanceList.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.ScopeType.APPLICATION;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.util.List;
  
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Transactional;
  import org.jboss.seam.annotations.Unwrap;
  import org.jbpm.taskmgmt.exe.TaskInstance;
  
  /**
   * Support for the task list.
   * 
   * @see TaskInstanceListForType
   * @see PooledTask
   * @author <a href="mailto:steve at hibernate.org">Steve Ebersole</a>
   * @author Gavin King
   */
  @Name("org.jboss.seam.core.taskInstanceList")
  @Scope(APPLICATION)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class TaskInstanceList
  {
     
     @Unwrap
     @Transactional
     public List<TaskInstance> getTaskInstanceList()
     {
        return getTaskInstanceList( Actor.instance().getId() );
     }
  
     private List<TaskInstance> getTaskInstanceList(String actorId)
     {
        if ( actorId == null ) return null;
  
        return ManagedJbpmContext.instance().getTaskList(actorId);
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/TaskInstanceListForType.java
  
  Index: TaskInstanceListForType.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.ScopeType.APPLICATION;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Transactional;
  import org.jboss.seam.annotations.Unwrap;
  import org.jbpm.taskmgmt.exe.TaskInstance;
  
  /**
   * Support for a list of tasks of a particular type.
   * 
   * @see TaskInstanceList
   * @author Gavin King
   * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
   */
  @Name("org.jboss.seam.core.taskInstanceListForType")
  @Scope(APPLICATION)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class TaskInstanceListForType
  {
     
     @Unwrap
     @Transactional
     public Map<String,List<TaskInstance>> getTaskInstanceList()
     {
        return getTaskInstanceList( Actor.instance().getId() );
     }
  
     private Map<String,List<TaskInstance>> getTaskInstanceList(String actorId)
     {
        if ( actorId == null ) return null;
  
        Map<String, List<TaskInstance>> map = new HashMap<String, List<TaskInstance>>();
        List<TaskInstance> taskInstances = ManagedJbpmContext.instance().getTaskList(actorId);
        for ( TaskInstance task: taskInstances )
        {
           String name = task.getName();
           List<TaskInstance> list = map.get(name);
           if (list==null)
           {
              list = new ArrayList<TaskInstance>();
              map.put(name, list);
           }
           list.add(task);
        }
        return map;
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/TaskInstancePriorityList.java
  
  Index: TaskInstancePriorityList.java
  ===================================================================
  package org.jboss.seam.bpm;
  
  import static org.jboss.seam.ScopeType.APPLICATION;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.util.List;
  
  import org.hibernate.criterion.Order;
  import org.hibernate.criterion.Restrictions;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Transactional;
  import org.jboss.seam.annotations.Unwrap;
  import org.jbpm.taskmgmt.exe.TaskInstance;
  
  /**
   * Support for a task list ordered by priority.
   * 
   * @see TaskInstanceList
   * @see PooledTask
   * @author Gavin King
   */
  @Name("org.jboss.seam.core.taskInstancePriorityList")
  @Scope(APPLICATION)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class TaskInstancePriorityList
  {
     
     //TODO: we really need to cache the list in the event context,
     //      but then we would need some events to refresh it
     //      when tasks end, which is non-trivial to do....
     
     @Unwrap
     @Transactional
     public List<TaskInstance> getTaskInstanceList()
     {
        return getTaskInstanceList( Actor.instance().getId() );
     }
  
     private List<TaskInstance> getTaskInstanceList(String actorId)
     {
        if ( actorId == null ) return null;
  
        return ManagedJbpmContext.instance().getSession()
           .createCriteria(TaskInstance.class)
           .add( Restrictions.eq("actorId", actorId) )
           .add( Restrictions.eq("isOpen", true) )
           .add( Restrictions.ne("isSuspended", true) )
           .addOrder( Order.asc("priority") )
           .setCacheable(true)
           .list();
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/Transition.java
  
  Index: Transition.java
  ===================================================================
  package org.jboss.seam.bpm;
  import static org.jboss.seam.InterceptionType.NEVER;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  import java.io.Serializable;
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.AbstractMutable;
  /**
   * Allows the application to set the jBPM transition to be used when
   * @EndTask is encountered.
   * 
   * @author Gavin King
   */
  @Name("org.jboss.seam.core.transition")
  @Scope(ScopeType.CONVERSATION)
  @Intercept(NEVER)
  @Install(precedence=BUILT_IN, dependencies="org.jboss.seam.core.jbpm")
  public class Transition extends AbstractMutable implements Serializable {
     private static final long serialVersionUID = -3054558654376670239L;
     
     private String name;
     public String getName() 
     {
        return name;
     }
     
     /**
      * Set the jBPM transition name
      */
     public void setName(String name) 
     {
        setDirty(this.name, name);
        this.name = name;
     }
     
     public static Transition instance()
     {
        if ( !Contexts.isApplicationContextActive() )
        {
           throw new IllegalStateException("No active application context");
        }
        return (Transition) Component.getInstance(Transition.class, ScopeType.CONVERSATION);
     }
     @Override
     public String toString()
     {
        return "Transition(" + name + ")";
     }
  }
  
  
  
  1.1      date: 2007/06/19 19:12:44;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/bpm/package-info.java
  
  Index: package-info.java
  ===================================================================
  @Namespace(value="http://jboss.com/products/seam/bpm", prefix="org.jboss.seam.bpm")
  package org.jboss.seam.bpm;
  
  import org.jboss.seam.annotations.Namespace;
  
  
  



More information about the jboss-cvs-commits mailing list