Package org.camunda.bpm.engine.impl.pvm.runtime.operation

Source Code of org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityEnd

/* 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.camunda.bpm.engine.impl.pvm.runtime.operation;

import java.util.List;

import org.camunda.bpm.engine.impl.pvm.delegate.ActivityBehavior;
import org.camunda.bpm.engine.impl.pvm.delegate.CompositeActivityBehavior;
import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;
import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
import org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl;

/**
* @author Tom Baeyens
* @author Daniel Meyer
*/
public class PvmAtomicOperationActivityEnd implements PvmAtomicOperation {

  protected ScopeImpl getScope(PvmExecutionImpl execution) {
    return execution.getActivity();
  }

  public boolean isAsync(PvmExecutionImpl execution) {
    return execution.getActivity().isAsyncAfter();
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  public void execute(PvmExecutionImpl execution) {

    ActivityImpl activity = execution.getActivity();
    ActivityImpl parentActivity = activity.getParentActivity();

    // if the execution is a single path of execution inside the process definition scope
    if ( (parentActivity!=null)
         &&(!parentActivity.isScope())
          ) {
      execution.setActivity(parentActivity);
      execution.performOperation(ACTIVITY_NOTIFY_LISTENER_END);

    } else if (execution.isProcessInstanceExecution()) {
      execution.performOperation(PROCESS_END);

    } else if (execution.isScope()) {

      ActivityBehavior parentActivityBehavior = (parentActivity!=null ? parentActivity.getActivityBehavior() : null);
      if (parentActivityBehavior instanceof CompositeActivityBehavior) {
        CompositeActivityBehavior compositeActivityBehavior = (CompositeActivityBehavior) parentActivity.getActivityBehavior();

        if(activity.isScope() && activity.getOutgoingTransitions().isEmpty()) {
          // there is no transition destroying the scope
          PvmExecutionImpl parentScopeExecution = execution.getParent();
          execution.destroy();
          execution.remove();
          parentScopeExecution.setActivity(parentActivity);
          compositeActivityBehavior.lastExecutionEnded(parentScopeExecution);
        } else {
          execution.setActivity(parentActivity);
          compositeActivityBehavior.lastExecutionEnded(execution);
        }
      } else {
        // default destroy scope behavior
        PvmExecutionImpl parentScopeExecution = execution.getParent();
        execution.destroy();
        execution.remove();
        // if we are a scope under the process instance
        // and have no outgoing transitions: end the process instance here
        if(activity.getParent() == activity.getProcessDefinition()
                && activity.getOutgoingTransitions().isEmpty()) {
          parentScopeExecution.setActivity(activity);
          // we call end() because it sets isEnded on the execution
          parentScopeExecution.performOperation(PROCESS_END);
        } else {
          parentScopeExecution.setActivity(parentActivity);
          parentScopeExecution.performOperation(ACTIVITY_NOTIFY_LISTENER_END);
        }
      }

    } else { // execution.isConcurrent() && !execution.isScope()

      execution.remove();

      // prune if necessary
      PvmExecutionImpl concurrentRoot = execution.getParent();
      if (concurrentRoot.getExecutions().size()==1) {
        PvmExecutionImpl lastConcurrent = concurrentRoot.getExecutions().get(0);
        if (!lastConcurrent.isScope()) {
          concurrentRoot.setActivity(lastConcurrent.getActivity());
          lastConcurrent.setReplacedBy(concurrentRoot);

          // Move children of lastConcurrent one level up
          if (lastConcurrent.getExecutions().size() > 0) {
            concurrentRoot.getExecutions().clear();
            for (PvmExecutionImpl childExecution : lastConcurrent.getExecutions()) {
              ((List)concurrentRoot.getExecutions()).add(childExecution); // casting ... damn generics
              childExecution.setParent(concurrentRoot);
            }
            lastConcurrent.getExecutions().clear();
          }

          // Copy execution-local variables of lastConcurrent
          concurrentRoot.setVariablesLocal(lastConcurrent.getVariablesLocal());

          // Make sure parent execution is re-activated when the last concurrent child execution is active
          if (!concurrentRoot.isActive() && lastConcurrent.isActive()) {
            concurrentRoot.setActive(true);
          }

          lastConcurrent.remove();
        } else {
          lastConcurrent.setConcurrent(false);
        }
      }
    }
  }

  protected boolean isExecutionAloneInParent(PvmExecutionImpl execution) {
    ScopeImpl parentScope = execution.getActivity().getParent();
    for (PvmExecutionImpl other: execution.getParent().getExecutions()) {
      if (other!=execution && parentScope.contains(other.getActivity())) {
        return false;
      }
    }
    return true;
  }

  public String getCanonicalName() {
    return "activity-end";
  }

}
TOP

Related Classes of org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityEnd

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.