All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroyScope Maven / Gradle / Ivy

The newest version!
/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.activiti.engine.impl.pvm.runtime;

import java.util.List;

import org.activiti.engine.impl.TaskContext;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author Tom Baeyens
 */
public class AtomicOperationTransitionDestroyScope implements AtomicOperation {
  
  private static Logger log = LoggerFactory.getLogger(AtomicOperationTransitionDestroyScope.class);
  
  public boolean isAsync(InterpretableExecution execution) {
    return false;
  }

  @SuppressWarnings("unchecked")
  public void execute(InterpretableExecution execution) {
    InterpretableExecution propagatingExecution = null;

    ActivityImpl activity = (ActivityImpl) execution.getActivity();
    boolean refreshTaskContext = false;
    // if this transition is crossing a scope boundary
    if (activity.isScope(execution,execution.getProcessInstanceId())) {
//      if(execution.getTaskContext().isIsmulti())
      
	      InterpretableExecution parentScopeInstance = null;
	      // if this is a concurrent execution crossing a scope boundary
	      if (execution.isConcurrent() && !execution.isScope()) {
	        // first remove the execution from the current root
	        InterpretableExecution concurrentRoot = (InterpretableExecution) execution.getParent();
	        parentScopeInstance = (InterpretableExecution) execution.getParent().getParent();
	
	        log.debug("moving concurrent {} one scope up under {}", execution, parentScopeInstance);
	        List parentScopeInstanceExecutions = (List) parentScopeInstance.getExecutions();
	        List concurrentRootExecutions = (List) concurrentRoot.getExecutions();
	        // if the parent scope had only one single scope child
	        if (parentScopeInstanceExecutions.size()==1) {
	          // it now becomes a concurrent execution
	          parentScopeInstanceExecutions.get(0).setConcurrent(true);
	        }
	        
	        concurrentRootExecutions.remove(execution);
	        parentScopeInstanceExecutions.add(execution);
	        execution.setParent(parentScopeInstance);
	        execution.setActivity(activity);
	        propagatingExecution = execution;
	        
	        // if there is only a single concurrent execution left
	        // in the concurrent root, auto-prune it.  meaning, the 
	        // last concurrent child execution data should be cloned into
	        // the concurrent root.   
	        if (concurrentRootExecutions.size()==1) {
	          InterpretableExecution lastConcurrent = concurrentRootExecutions.get(0);
	          if (lastConcurrent.isScope()) {
	            lastConcurrent.setConcurrent(false);
	            
	          } else {
	            log.debug("merging last concurrent {} into concurrent root {}", lastConcurrent, concurrentRoot);
	            
	            // We can't just merge the data of the lastConcurrent into the concurrentRoot.
	            // This is because the concurrent root might be in a takeAll-loop.  So the 
	            // concurrent execution is the one that will be receiving the take
	            concurrentRoot.setActivity((ActivityImpl) lastConcurrent.getActivity());
	            concurrentRoot.setActive(lastConcurrent.isActive());
	            lastConcurrent.setReplacedBy(concurrentRoot);
	            lastConcurrent.remove();
	          }
	        }
	
	      } else if (execution.isConcurrent() && execution.isScope()) {
	        log.debug("scoped concurrent {} becomes concurrent and remains under {}", execution, execution.getParent());
	
	        // TODO!
	        execution.destroy();
	        propagatingExecution = execution;
	        
	      } else {
	        propagatingExecution = (InterpretableExecution) execution.getParent();
	        propagatingExecution.setActivity((ActivityImpl) execution.getActivity());
	        propagatingExecution.setTransition(execution.getTransition());
	        TaskContext taskContext = execution.getTaskContext();
	        propagatingExecution.setActive(true);
	        TaskContext taskContext1 = propagatingExecution.getTaskContext();
	        if(taskContext1 != null)
	        {
	        	if(taskContext != null)
	        	{
			        taskContext1.setIsrejected(taskContext.isIsrejected());
			        taskContext1.setIswithdraw(taskContext.isIswithdraw());
			        taskContext1.setIsjump(taskContext.isIsjump());
			        taskContext1.setOp(taskContext.getOp());
			        taskContext1.setReturntoreject(taskContext.isReturntoreject());
			        taskContext1.setRejecttype(taskContext.getRejecttype());
			        taskContext1.setRejectedtaskid(taskContext.getRejectedtaskid());
			        taskContext1.setRejectednode(taskContext.getRejectednode());
			        refreshTaskContext = true;
	        	}
	        }
	        else
	        {
	        	if(taskContext != null)
	        		propagatingExecution.setTaskContext(taskContext);
	        }
	        log.debug("destroy scope: scoped {} continues as parent scope {}", execution, propagatingExecution);
	        execution.destroy();
	        execution.remove();
	      }
      
//      else
//      {
//    	  propagatingExecution = execution;
//      }
      
    } else {
      propagatingExecution = execution;
    }
    
    // if there is another scope element that is ended
    ScopeImpl nextOuterScopeElement = activity.getParent();
    TransitionImpl transition = propagatingExecution.getTransition();
    ActivityImpl destination = transition.getDestination();
    if (transitionLeavesNextOuterScope(nextOuterScopeElement, destination)) {
      propagatingExecution.setActivity((ActivityImpl) nextOuterScopeElement);
      propagatingExecution.performOperation(TRANSITION_NOTIFY_LISTENER_END);
    } else {
//    	ActivityImpl source = (ActivityImpl)propagatingExecution.getActivity();
//      if(destination.isUserTask())
//      {
//    	  
//    	  if(!refreshTaskContext){
//    		  if( source.getId().equals(destination.getId()))
//    		{
//    		  TaskContext taskContext1 = propagatingExecution.getTaskContext();
//    		  
//    		  
//    		  TaskContext newTaskContext = Context.createTaskContext((ExecutionEntity) propagatingExecution, destination.getId());
//    		  if(taskContext1 != null)
//    		  {
//    			  if(taskContext1.isIsrejected())
//    			  {
//    				  newTaskContext.setIsrejected(taskContext1.isIsrejected());
//    				  newTaskContext.setReturntoreject(taskContext1.isReturntoreject());
//    				  newTaskContext.setRejecttype(taskContext1.getRejecttype());
//    				  newTaskContext.setRejectedtaskid(taskContext1.getRejectedtaskid());
//    				  newTaskContext.setRejectednode(taskContext1.getRejectednode());
//    			      refreshTaskContext = true;
//    			  }
//    		  }
//    		}
//    	  }
//    	  
//    	 
//      }
//      else
//      {
//    	  propagatingExecution.setTaskContext(null);
//      }
      propagatingExecution.performOperation(TRANSITION_NOTIFY_LISTENER_TAKE);
    }
  }

  public boolean transitionLeavesNextOuterScope(ScopeImpl nextScopeElement, ActivityImpl destination) {
    return !nextScopeElement.contains(destination);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy