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

org.activiti.engine.impl.bpmn.deployer.BpmnDeploymentHelper 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.bpmn.deployer;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.DeploymentEntity;
import org.activiti.engine.impl.persistence.entity.IdentityLinkEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityManager;
import org.activiti.engine.task.IdentityLinkType;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * Methods for working with deployments.  Much of the actual work of {@link BpmnDeployer} is
 * done by orchestrating the different pieces of work this class does; by having them here,
 * we allow other deployers to make use of them.   
 */
public class BpmnDeploymentHelper  {
  
  protected TimerManager timerManager;
  protected EventSubscriptionManager eventSubscriptionManager;
  
  /**
   * Verifies that no two process definitions share the same key, to prevent database unique
   * index violation.
   * 
   * @throws ActivitiException if any two processes have the same key
   */
  public void verifyProcessDefinitionsDoNotShareKeys(
      Collection processDefinitions) {
    Set keySet = new LinkedHashSet();
    for (ProcessDefinitionEntity processDefinition : processDefinitions) {
      if (keySet.contains(processDefinition.getKey())) {
        throw new ActivitiException(
            "The deployment contains process definitions with the same key (process id attribute), this is not allowed");
      }
      keySet.add(processDefinition.getKey());
    }
  }

  /**
   * Updates all the process definition entities to match the deployment's values for tenant,
   * engine version, and deployment id.
   */
  public void copyDeploymentValuesToProcessDefinitions(DeploymentEntity deployment, 
      List processDefinitions) {
    String engineVersion = deployment.getEngineVersion();
    String tenantId = deployment.getTenantId();
    String deploymentId = deployment.getId();

    for (ProcessDefinitionEntity processDefinition : processDefinitions) {
      
      // Backwards compatibility
      if (engineVersion != null) {
        processDefinition.setEngineVersion(engineVersion);
      }

      // process definition inherits the tenant id
      if (tenantId != null) {
        processDefinition.setTenantId(tenantId); 
      }

      processDefinition.setDeploymentId(deploymentId);
    }
  }

  /**
   * Updates all the process definition entities to have the correct resource names.
   */
  public void setResourceNamesOnProcessDefinitions(ParsedDeployment parsedDeployment) {
    for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) {
      String resourceName = parsedDeployment.getResourceForProcessDefinition(processDefinition).getName();
      processDefinition.setResourceName(resourceName);
    }
  }

  /**
   * Gets the most recent persisted process definition that matches this one for tenant and key.
   * If none is found, returns null.  This method assumes that the tenant and key are properly
   * set on the process definition entity.
   */
  public ProcessDefinitionEntity getMostRecentVersionOfProcessDefinition(ProcessDefinitionEntity processDefinition) {
    String key = processDefinition.getKey();
    String tenantId = processDefinition.getTenantId();
    ProcessDefinitionEntityManager processDefinitionManager 
      = Context.getCommandContext().getProcessEngineConfiguration().getProcessDefinitionEntityManager();

    ProcessDefinitionEntity existingDefinition = null;

    if (tenantId != null && !tenantId.equals(ProcessEngineConfiguration.NO_TENANT_ID)) {
      existingDefinition = processDefinitionManager.findLatestProcessDefinitionByKeyAndTenantId(key, tenantId);
    } else {
      existingDefinition = processDefinitionManager.findLatestProcessDefinitionByKey(key);
    }

    return existingDefinition;
  }

  /**
   * Gets the persisted version of the already-deployed process definition.  Note that this is
   * different from {@link #getMostRecentVersionOfProcessDefinition} as it looks specifically for
   * a process definition that is already persisted and attached to a particular deployment,
   * rather than the latest version across all deployments.
   */
  public ProcessDefinitionEntity getPersistedInstanceOfProcessDefinition(ProcessDefinitionEntity processDefinition) {
    String deploymentId = processDefinition.getDeploymentId();
    if (StringUtils.isEmpty(processDefinition.getDeploymentId())) {
      throw new IllegalStateException("Provided process definition must have a deployment id.");
    }

    ProcessDefinitionEntityManager processDefinitionManager 
      = Context.getCommandContext().getProcessEngineConfiguration().getProcessDefinitionEntityManager();
    ProcessDefinitionEntity persistedProcessDefinition = null;
    if (processDefinition.getTenantId() == null || ProcessEngineConfiguration.NO_TENANT_ID.equals(processDefinition.getTenantId())) {
      persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKey(deploymentId, processDefinition.getKey());
    } else {
      persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKeyAndTenantId(deploymentId, processDefinition.getKey(), processDefinition.getTenantId());
    }

    return persistedProcessDefinition;
  }

  /**
   * Updates all timers and events for the process definition.  This removes obsolete message and signal
   * subscriptions and timers, and adds new ones.
   */
  public void updateTimersAndEvents(ProcessDefinitionEntity processDefinition, 
      ProcessDefinitionEntity previousProcessDefinition, ParsedDeployment parsedDeployment) {
    
    Process process = parsedDeployment.getProcessModelForProcessDefinition(processDefinition);
    BpmnModel bpmnModel = parsedDeployment.getBpmnModelForProcessDefinition(processDefinition);

    eventSubscriptionManager.removeObsoleteMessageEventSubscriptions(previousProcessDefinition);
    eventSubscriptionManager.addMessageEventSubscriptions(processDefinition, process, bpmnModel);

    eventSubscriptionManager.removeObsoleteSignalEventSubScription(previousProcessDefinition);
    eventSubscriptionManager.addSignalEventSubscriptions(Context.getCommandContext(), processDefinition, process, bpmnModel);

    timerManager.removeObsoleteTimers(processDefinition);
    timerManager.scheduleTimers(processDefinition, process);
  }

  enum ExpressionType {
    USER, GROUP
  }

  /**
   * @param processDefinition
   */
  public void addAuthorizationsForNewProcessDefinition(Process process, ProcessDefinitionEntity processDefinition) {
    CommandContext commandContext = Context.getCommandContext();
    
    addAuthorizationsFromIterator(commandContext, process.getCandidateStarterUsers(), processDefinition, ExpressionType.USER);
    addAuthorizationsFromIterator(commandContext, process.getCandidateStarterGroups(), processDefinition, ExpressionType.GROUP);
  }
  
  protected void addAuthorizationsFromIterator(CommandContext commandContext, List expressions, 
      ProcessDefinitionEntity processDefinition, ExpressionType expressionType) {
    
    if (expressions != null) {
      Iterator iterator = expressions.iterator();
      while (iterator.hasNext()) {
        @SuppressWarnings("cast")
        String expression = iterator.next();
        IdentityLinkEntity identityLink = commandContext.getIdentityLinkEntityManager().create();
        identityLink.setProcessDef(processDefinition);
        if (expressionType.equals(ExpressionType.USER)) {
          identityLink.setUserId(expression);
        } else if (expressionType.equals(ExpressionType.GROUP)) {
          identityLink.setGroupId(expression);
        }
        identityLink.setType(IdentityLinkType.CANDIDATE);
        commandContext.getIdentityLinkEntityManager().insert(identityLink);
      }
    }
    
  }

  public TimerManager getTimerManager() {
    return timerManager;
  }

  public void setTimerManager(TimerManager timerManager) {
    this.timerManager = timerManager;
  }

  public EventSubscriptionManager getEventSubscriptionManager() {
    return eventSubscriptionManager;
  }

  public void setEventSubscriptionManager(EventSubscriptionManager eventSubscriptionManager) {
    this.eventSubscriptionManager = eventSubscriptionManager;
  }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy