Package org.camunda.bpm.engine.impl.interceptor

Source Code of org.camunda.bpm.engine.impl.interceptor.CommandContext

/* 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.interceptor;

import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.camunda.bpm.application.ProcessApplicationReference;
import org.camunda.bpm.engine.BadUserRequestException;
import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.OptimisticLockingException;
import org.camunda.bpm.engine.TaskAlreadyClaimedException;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cfg.TransactionContext;
import org.camunda.bpm.engine.impl.cfg.TransactionContextFactory;
import org.camunda.bpm.engine.impl.cmmn.entity.repository.CaseDefinitionManager;
import org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionEntity;
import org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseExecutionManager;
import org.camunda.bpm.engine.impl.cmmn.entity.runtime.CaseSentryPartManager;
import org.camunda.bpm.engine.impl.cmmn.operation.CmmnAtomicOperation;
import org.camunda.bpm.engine.impl.context.Context;
import org.camunda.bpm.engine.impl.context.ProcessApplicationContextUtil;
import org.camunda.bpm.engine.impl.db.entitymanager.DbEntityManager;
import org.camunda.bpm.engine.impl.db.sql.DbSqlSession;
import org.camunda.bpm.engine.impl.identity.Authentication;
import org.camunda.bpm.engine.impl.identity.ReadOnlyIdentityProvider;
import org.camunda.bpm.engine.impl.identity.WritableIdentityProvider;
import org.camunda.bpm.engine.impl.jobexecutor.FailedJobCommandFactory;
import org.camunda.bpm.engine.impl.persistence.entity.AttachmentManager;
import org.camunda.bpm.engine.impl.persistence.entity.AuthorizationManager;
import org.camunda.bpm.engine.impl.persistence.entity.ByteArrayManager;
import org.camunda.bpm.engine.impl.persistence.entity.CommentManager;
import org.camunda.bpm.engine.impl.persistence.entity.DeploymentManager;
import org.camunda.bpm.engine.impl.persistence.entity.EventSubscriptionManager;
import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity;
import org.camunda.bpm.engine.impl.persistence.entity.ExecutionManager;
import org.camunda.bpm.engine.impl.persistence.entity.FilterManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricActivityInstanceManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricCaseActivityInstanceManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricCaseInstanceManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricDetailManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricIncidentManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricStatisticsManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricTaskInstanceManager;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricVariableInstanceManager;
import org.camunda.bpm.engine.impl.persistence.entity.IdentityInfoManager;
import org.camunda.bpm.engine.impl.persistence.entity.IdentityLinkManager;
import org.camunda.bpm.engine.impl.persistence.entity.IncidentManager;
import org.camunda.bpm.engine.impl.persistence.entity.JobDefinitionManager;
import org.camunda.bpm.engine.impl.persistence.entity.JobManager;
import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionManager;
import org.camunda.bpm.engine.impl.persistence.entity.PropertyManager;
import org.camunda.bpm.engine.impl.persistence.entity.ResourceManager;
import org.camunda.bpm.engine.impl.persistence.entity.StatisticsManager;
import org.camunda.bpm.engine.impl.persistence.entity.TableDataManager;
import org.camunda.bpm.engine.impl.persistence.entity.TaskManager;
import org.camunda.bpm.engine.impl.persistence.entity.UserOperationLogManager;
import org.camunda.bpm.engine.impl.persistence.entity.VariableInstanceManager;
import org.camunda.bpm.engine.impl.pvm.runtime.AtomicOperation;

/**
* @author Tom Baeyens
* @author Agim Emruli
* @author Daniel Meyer
*/
public class CommandContext {

  private static Logger log = Logger.getLogger(CommandContext.class.getName());

  protected TransactionContext transactionContext;
  protected Map<Class< ? >, SessionFactory> sessionFactories;
  protected Map<Class< ? >, Session> sessions = new HashMap<Class< ? >, Session>();
  protected List<Session> sessionList = new ArrayList<Session>();
  protected ProcessEngineConfigurationImpl processEngineConfiguration;
  protected FailedJobCommandFactory failedJobCommandFactory;

  protected List<CommandContextListener> commandContextListeners = new LinkedList<CommandContextListener>();

  public CommandContext(ProcessEngineConfigurationImpl processEngineConfiguration) {
    this(processEngineConfiguration, processEngineConfiguration.getTransactionContextFactory());
  }

  public CommandContext(ProcessEngineConfigurationImpl processEngineConfiguration, TransactionContextFactory transactionContextFactory) {
    this.processEngineConfiguration = processEngineConfiguration;
    this.failedJobCommandFactory = processEngineConfiguration.getFailedJobCommandFactory();
    sessionFactories = processEngineConfiguration.getSessionFactories();
    this.transactionContext = transactionContextFactory.openTransactionContext(this);
  }

  public void performOperation(final AtomicOperation executionOperation, final ExecutionEntity execution) {

    ProcessApplicationReference targetProcessApplication = getTargetProcessApplication(execution);

    if(requiresContextSwitch(targetProcessApplication)) {

      Context.executeWithinProcessApplication(new Callable<Void>() {
        public Void call() throws Exception {
          performOperation(executionOperation, execution);
          return null;
        }

      }, targetProcessApplication);

    } else {
      try {
        Context.setExecutionContext(execution);
        if (log.isLoggable(Level.FINEST)) {
          log.finest("AtomicOperation: " + executionOperation + " on " + this);
        }
        executionOperation.execute(execution);
      } finally {
        Context.removeExecutionContext();
      }
    }

  }

  public void performOperation(final CmmnAtomicOperation executionOperation, final CaseExecutionEntity execution) {
    ProcessApplicationReference targetProcessApplication = getTargetProcessApplication(execution);

    if(requiresContextSwitch(targetProcessApplication)) {

      Context.executeWithinProcessApplication(new Callable<Void>() {
        public Void call() throws Exception {
          performOperation(executionOperation, execution);
          return null;
        }

      }, targetProcessApplication);

    } else {
      try {
        Context.setExecutionContext(execution);
        if (log.isLoggable(Level.FINEST)) {
          log.finest("AtomicOperation: " + executionOperation + " on " + this);
        }
        executionOperation.execute(execution);
      } finally {
        Context.removeExecutionContext();
      }
    }
  }

  protected ProcessApplicationReference getTargetProcessApplication(ExecutionEntity execution) {
    return ProcessApplicationContextUtil.getTargetProcessApplication(execution);
  }

  protected ProcessApplicationReference getTargetProcessApplication(CaseExecutionEntity execution) {
    return ProcessApplicationContextUtil.getTargetProcessApplication(execution);
  }

  protected boolean requiresContextSwitch(ProcessApplicationReference processApplicationReference) {
    return ProcessApplicationContextUtil.requiresContextSwitch(processApplicationReference);
  }

  public void close(CommandInvocationContext commandInvocationContext) {
    // the intention of this method is that all resources are closed properly,
    // even
    // if exceptions occur in close or flush methods of the sessions or the
    // transaction context.

    try {
      try {
        try {

          if (commandInvocationContext.getThrowable() == null) {
            fireCommandContextClose();
            flushSessions();
          }

        } catch (Throwable exception) {
          commandInvocationContext.trySetThrowable(exception);
        } finally {

          try {
            if (commandInvocationContext.getThrowable() == null) {
              transactionContext.commit();
            }
          } catch (Throwable exception) {
            commandInvocationContext.trySetThrowable(exception);
          }

          if (commandInvocationContext.getThrowable() != null) {
            // fire command failed (must not fail itself)
            fireCommandFailed(commandInvocationContext.getThrowable());

            Level loggingLevel = Level.SEVERE;
            if (shouldLogInfo(commandInvocationContext.getThrowable())) {
              loggingLevel = Level.INFO; // reduce log level, because this is not really a technical exception
            }
            else if (shouldLogFine(commandInvocationContext.getThrowable())) {
              loggingLevel = Level.FINE;
            }
            if (log.isLoggable(loggingLevel)) {
              log.log(loggingLevel, "Error while closing command context", commandInvocationContext.getThrowable());
            }
            transactionContext.rollback();
          }
        }
      } catch (Throwable exception) {
        commandInvocationContext.trySetThrowable(exception);
      } finally {
        closeSessions(commandInvocationContext);
      }
    } catch (Throwable exception) {
      commandInvocationContext.trySetThrowable(exception);
    }

    // rethrow the original exception if there was one
    commandInvocationContext.rethrow();
  }

  protected boolean shouldLogInfo(Throwable exception) {
    return exception instanceof TaskAlreadyClaimedException;
  }

  protected boolean shouldLogFine(Throwable exception) {
    return exception instanceof OptimisticLockingException || exception instanceof BadUserRequestException;
  }

  protected void fireCommandContextClose() {
    for (CommandContextListener listener : commandContextListeners) {
      listener.onCommandContextClose(this);
    }
  }

  protected void fireCommandFailed(Throwable t) {
    for (CommandContextListener listener : commandContextListeners) {
      try {
        listener.onCommandFailed(this, t);
      } catch(Throwable ex) {
        log.log(Level.SEVERE, "Exception while invoking onCommandFailed()", t);
      }
    }
  }

  protected void flushSessions() {
    for (int i = 0; i< sessionList.size(); i++) {
      sessionList.get(i).flush();
    }
  }

  protected void closeSessions(CommandInvocationContext commandInvocationContext) {
    for (Session session : sessionList) {
      try {
        session.close();
      } catch (Throwable exception) {
        commandInvocationContext.trySetThrowable(exception);
      }
    }
  }

  @SuppressWarnings({"unchecked"})
  public <T> T getSession(Class<T> sessionClass) {
    Session session = sessions.get(sessionClass);
    if (session == null) {
      SessionFactory sessionFactory = sessionFactories.get(sessionClass);
      ensureNotNull("no session factory configured for " + sessionClass.getName(), "sessionFactory", sessionFactory);
      session = sessionFactory.openSession();
      sessions.put(sessionClass, session);
      sessionList.add(0, session);
    }

    return (T) session;
  }

  public DbEntityManager getDbEntityManager() {
    return getSession(DbEntityManager.class);
  }

  public DbSqlSession getDbSqlSession() {
    return getSession(DbSqlSession.class);
  }

  public DeploymentManager getDeploymentManager() {
    return getSession(DeploymentManager.class);
  }

  public ResourceManager getResourceManager() {
    return getSession(ResourceManager.class);
  }

  public ByteArrayManager getByteArrayManager() {
    return getSession(ByteArrayManager.class);
  }

  public ProcessDefinitionManager getProcessDefinitionManager() {
    return getSession(ProcessDefinitionManager.class);
  }

  public ExecutionManager getExecutionManager() {
    return getSession(ExecutionManager.class);
  }

  public TaskManager getTaskManager() {
    return getSession(TaskManager.class);
  }

  public IdentityLinkManager getIdentityLinkManager() {
    return getSession(IdentityLinkManager.class);
  }

  public VariableInstanceManager getVariableInstanceManager() {
    return getSession(VariableInstanceManager.class);
  }

  public HistoricProcessInstanceManager getHistoricProcessInstanceManager() {
    return getSession(HistoricProcessInstanceManager.class);
  }

  public HistoricCaseInstanceManager getHistoricCaseInstanceManager() {
    return getSession(HistoricCaseInstanceManager.class);
  }

  public HistoricDetailManager getHistoricDetailManager() {
    return getSession(HistoricDetailManager.class);
  }

  public UserOperationLogManager getOperationLogManager() {
    return getSession(UserOperationLogManager.class);
  }

  public HistoricVariableInstanceManager getHistoricVariableInstanceManager() {
    return getSession(HistoricVariableInstanceManager.class);
  }

  public HistoricActivityInstanceManager getHistoricActivityInstanceManager() {
    return getSession(HistoricActivityInstanceManager.class);
  }

  public HistoricCaseActivityInstanceManager getHistoricCaseActivityInstanceManager() {
    return getSession(HistoricCaseActivityInstanceManager.class);
  }

  public HistoricTaskInstanceManager getHistoricTaskInstanceManager() {
    return getSession(HistoricTaskInstanceManager.class);
  }

  public HistoricIncidentManager getHistoricIncidentManager() {
    return getSession(HistoricIncidentManager.class);
  }

  public JobManager getJobManager() {
    return getSession(JobManager.class);
  }

  public JobDefinitionManager getJobDefinitionManager() {
    return getSession(JobDefinitionManager.class);
  }

  public IncidentManager getIncidentManager() {
    return getSession(IncidentManager.class);
  }

  public IdentityInfoManager getIdentityInfoManager() {
    return getSession(IdentityInfoManager.class);
  }

  public AttachmentManager getAttachmentManager() {
    return getSession(AttachmentManager.class);
  }

  public TableDataManager getTableDataManager() {
    return getSession(TableDataManager.class);
  }

  public CommentManager getCommentManager() {
    return getSession(CommentManager.class);
  }

  public EventSubscriptionManager getEventSubscriptionManager() {
    return getSession(EventSubscriptionManager.class);
  }

  public Map<Class< ? >, SessionFactory> getSessionFactories() {
    return sessionFactories;
  }

  public PropertyManager getPropertyManager() {
    return getSession(PropertyManager.class);
  }

  public StatisticsManager getStatisticsManager() {
    return getSession(StatisticsManager.class);
  }

  public HistoricStatisticsManager getHistoricStatisticsManager() {
    return getSession(HistoricStatisticsManager.class);
  }

  public AuthorizationManager getAuthorizationManager() {
    return getSession(AuthorizationManager.class);
  }

  public ReadOnlyIdentityProvider getReadOnlyIdentityProvider() {
    return getSession(ReadOnlyIdentityProvider.class);
  }

  public WritableIdentityProvider getWritableIdentityProvider() {
    return getSession(WritableIdentityProvider.class);
  }

  // CMMN /////////////////////////////////////////////////////////////////////

  public CaseDefinitionManager getCaseDefinitionManager() {
    return getSession(CaseDefinitionManager.class);
  }

  public CaseExecutionManager getCaseExecutionManager() {
    return getSession(CaseExecutionManager.class);
  }

  public CaseSentryPartManager getCaseSentryPartManager() {
    return getSession(CaseSentryPartManager.class);
  }

  // Filter ////////////////////////////////////////////////////////////////////

  public FilterManager getFilterManager() {
    return getSession(FilterManager.class);
  }

  // getters and setters //////////////////////////////////////////////////////

  public void registerCommandContextListener(CommandContextListener commandContextListener) {
    if(!commandContextListeners.contains(commandContextListener)) {
      commandContextListeners.add(commandContextListener);
    }
  }

  public TransactionContext getTransactionContext() {
    return transactionContext;
  }

  public Map<Class< ? >, Session> getSessions() {
    return sessions;
  }

  public FailedJobCommandFactory getFailedJobCommandFactory() {
    return failedJobCommandFactory;
  }

  public Authentication getAuthentication() {
    IdentityService identityService = processEngineConfiguration.getIdentityService();
    return identityService.getCurrentAuthentication();
  }

  public void runWithoutAuthentication(Runnable runnable) {
    IdentityService identityService = processEngineConfiguration.getIdentityService();
    Authentication currentAuthentication = identityService.getCurrentAuthentication();
    try {
      identityService.clearAuthentication();
      runnable.run();
    } finally {
      identityService.setAuthentication(currentAuthentication);
    }
  }

  public String getAuthenticatedUserId() {
    IdentityService identityService = processEngineConfiguration.getIdentityService();
    Authentication currentAuthentication = identityService.getCurrentAuthentication();
    if(currentAuthentication == null) {
      return null;
    } else {
      return currentAuthentication.getUserId();
    }
  }

  public List<String> getAuthenticatedGroupIds() {
    IdentityService identityService = processEngineConfiguration.getIdentityService();
    Authentication currentAuthentication = identityService.getCurrentAuthentication();
    if(currentAuthentication == null) {
      return null;
    } else {
      return currentAuthentication.getGroupIds();
    }
  }
}
TOP

Related Classes of org.camunda.bpm.engine.impl.interceptor.CommandContext

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.