Package org.activiti.cdi.impl.context

Source Code of org.activiti.cdi.impl.context.DefaultContextAssociationManager$RequestScopedAssociation

/* 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.cdi.impl.context;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
import javax.inject.Scope;

import org.activiti.cdi.ActivitiCdiException;
import org.activiti.cdi.impl.util.ProgrammaticBeanLookup;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.context.ExecutionContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.task.Task;

/**
* Default implementation of the business process association manager. Uses a
* fallback-strategy to associate the process instance with the "broadest"
* active scope, starting with the conversation.
* <p />
* Subclass in order to implement custom association schemes and association
* with custom scopes.
*
* @author Daniel Meyer
*/
@SuppressWarnings("serial")
public class DefaultContextAssociationManager implements ContextAssociationManager, Serializable {
 
  private final static Logger log = Logger.getLogger(DefaultContextAssociationManager.class.getName());
 
  protected static class ScopedAssociation {
   
    @Inject
    private RuntimeService runtimeService;
   
    protected Map<String, Object> cachedVariables = new HashMap<String, Object>();
    protected Execution execution;   
    protected Task task;
   
    public Execution getExecution() {
      return execution;
    }
   
    public void setExecution(Execution execution) {
      this.execution = execution;
    }
   
    public Task getTask() {
      return task;
    }
   
    public void setTask(Task task) {
      this.task = task;
    }

    public <T> T getVariable(String variableName) {
      Object value = cachedVariables.get(variableName);
      if(value == null) {
        if(execution != null) {
          value = runtimeService.getVariable(execution.getId(), variableName);
          cachedVariables.put(variableName, value);
        }
      }
      return (T) value;
    }

    public void setVariable(String variableName, Object value) {
      cachedVariables.put(variableName, value);
    }

    public Map<String, Object> getCachedVariables() {
      return cachedVariables;
    }
  
  }
 
  @ConversationScoped protected static class ConversationScopedAssociation extends ScopedAssociation implements Serializable {}
  @RequestScoped protected static class RequestScopedAssociation extends ScopedAssociation implements Serializable {}
 
  @Inject private BeanManager beanManager;

  protected Class< ? extends ScopedAssociation> getBroadestActiveContext() {
    for (Class< ? extends ScopedAssociation> scopeType : getAvailableScopedAssociationClasses()) {
      Annotation scopeAnnotation = scopeType.getAnnotations().length > 0 ? scopeType.getAnnotations()[0] : null;
      if (scopeAnnotation == null || !beanManager.isScope(scopeAnnotation.annotationType())) {
        throw new ActivitiException("ScopedAssociation must carry exactly one annotation and it must be a @Scope annotation");
      }
      try {
        beanManager.getContext(scopeAnnotation.annotationType());
        return scopeType;
      } catch (ContextNotActiveException e) {
        log.finest("Context " + scopeAnnotation.annotationType() + " not active.");           
      }
    }
    throw new ActivitiException("Could not determine an active context to associate the current process instance / task instance with.");
  }
 
  /**
   * Override to add different / additional contexts.
   *
   * @returns a list of {@link Scope}-types, which are used in the given order
   *          to resolve the broadest active context (@link
   *          #getBroadestActiveContext()})
   */
  protected List<Class< ? extends ScopedAssociation>> getAvailableScopedAssociationClasses() {
    ArrayList<Class< ? extends ScopedAssociation>> scopeTypes = new ArrayList<Class< ? extends ScopedAssociation>>();
    scopeTypes.add(ConversationScopedAssociation.class);
    scopeTypes.add(RequestScopedAssociation.class);
    return scopeTypes;
  }
 
  protected ScopedAssociation getScopedAssociation() {
    return ProgrammaticBeanLookup.lookup(getBroadestActiveContext(), beanManager);
  }

  @Override
  public void setExecution(Execution execution) {
    if(execution == null) {
      throw new ActivitiCdiException("Cannot associate with execution: null");
    }
   
    if(Context.getCommandContext() != null) {
      throw new ActivitiCdiException("Cannot work with scoped associations inside command context.");
    }
   
    ScopedAssociation scopedAssociation = getScopedAssociation();
    Execution associatedExecution = scopedAssociation.getExecution();
    if(associatedExecution!=null && !associatedExecution.getId().equals(execution.getId())) {
      throw new ActivitiCdiException("Cannot associate "+execution+", already associated with "+associatedExecution+". Disassociate first!");
    }
   
    if (log.isLoggable(Level.FINE)) {
      log.fine("Associating "+execution+" (@"
                + scopedAssociation.getClass().getAnnotations()[0].annotationType().getSimpleName() + ")");
    }
    scopedAssociation.setExecution(execution);
  }

  @Override
  public void disAssociate() {
    if(Context.getCommandContext() != null) {
      throw new ActivitiCdiException("Cannot work with scoped associations inside command context.");
    }
    ScopedAssociation scopedAssociation = getScopedAssociation();
    if (scopedAssociation.getExecution() == null) {
      throw new ActivitiException("Cannot dissasociate execution, no "
                + scopedAssociation.getClass().getAnnotations()[0].annotationType().getSimpleName()
                + " execution associated. ");
    }
    if (log.isLoggable(Level.FINE)) {
      log.fine("Disassociating");
    }
    scopedAssociation.setExecution(null);
    scopedAssociation.setTask(null);
  }
 
  @Override
  public String getExecutionId() {
    Execution execution = getExecution();
    if (execution != null) {
      return execution.getId();
    } else {
      return null;
    }
  }
 
  @Override
  public Execution getExecution() {
    ExecutionEntity execution = getExecutionFromContext();
    if(execution != null) {
      return execution;
    } else {
      return getScopedAssociation().getExecution();    
    }
  }

  @Override
  public Object getVariable(String variableName) {
    ExecutionEntity execution = getExecutionFromContext();
    if(execution != null) {
      return execution.getVariable(variableName);
    } else {
      return getScopedAssociation().getVariable(variableName)
    }
  }
 
  @Override
  public void setVariable(String variableName, Object value) {
    ExecutionEntity execution = getExecutionFromContext();
    if(execution != null) {
      execution.setVariable(variableName, value);
      execution.getVariable(variableName);
    } else {
      getScopedAssociation().setVariable(variableName, value)
    }
  }
 
  protected ExecutionEntity getExecutionFromContext() {
    if(Context.getCommandContext() != null) {
      ExecutionContext executionContext = Context.getExecutionContext();
      if(executionContext != null) {
        return executionContext.getExecution();
      }
    }
    return null;
  }

  public Task getTask() {   
    if(Context.getCommandContext() != null) {
      throw new ActivitiCdiException("Cannot work with tasks in an activiti command.");
    }
    return getScopedAssociation().getTask();
  }
 
  public void setTask(Task task) {
    if(Context.getCommandContext() != null) {
      throw new ActivitiCdiException("Cannot work with tasks in an activiti command.");
    }
    getScopedAssociation().setTask(task);
  }

  @Override
  public Map<String, Object> getCachedVariables() {
    if(Context.getCommandContext() != null) {
      throw new ActivitiCdiException("Cannot work with cached variables in an activiti command.");
    }
    return getScopedAssociation().getCachedVariables();
  }

}
TOP

Related Classes of org.activiti.cdi.impl.context.DefaultContextAssociationManager$RequestScopedAssociation

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.
d', 'pageview');