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

org.activiti.engine.impl.event.logger.EventLogger Maven / Gradle / Ivy

There is a newer version: 3.0.Beta
Show newest version
package org.activiti.engine.impl.event.logger;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.activiti.engine.delegate.event.ActivitiEntityEvent;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.event.logger.handler.*;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandContextCloseListener;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.runtime.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**

 */
public class EventLogger implements ActivitiEventListener {
	
	private static final Logger logger = LoggerFactory.getLogger(EventLogger.class);
	
	private static final String EVENT_FLUSHER_KEY = "eventFlusher";
	
	protected Clock clock;
	protected ObjectMapper objectMapper;
	
	// Mapping of type -> handler
	protected Map> eventHandlers 
		= new HashMap>();
	
	// Listeners for new events
	protected List listeners;
	
	public EventLogger() {
		initializeDefaultHandlers();
	}
	
	public EventLogger(Clock clock, ObjectMapper objectMapper) {
		this();
		this.clock = clock;
		this.objectMapper = objectMapper;
	}

	protected void initializeDefaultHandlers() {
	  addEventHandler(ActivitiEventType.TASK_CREATED, TaskCreatedEventHandler.class);
		addEventHandler(ActivitiEventType.TASK_COMPLETED, TaskCompletedEventHandler.class);
		addEventHandler(ActivitiEventType.TASK_ASSIGNED, TaskAssignedEventHandler.class);
		
		addEventHandler(ActivitiEventType.SEQUENCEFLOW_TAKEN, SequenceFlowTakenEventHandler.class);
		
		addEventHandler(ActivitiEventType.ACTIVITY_COMPLETED, ActivityCompletedEventHandler.class);
		addEventHandler(ActivitiEventType.ACTIVITY_STARTED, ActivityStartedEventHandler.class);
		addEventHandler(ActivitiEventType.ACTIVITY_SIGNALED, ActivitySignaledEventHandler.class);
		addEventHandler(ActivitiEventType.ACTIVITY_MESSAGE_RECEIVED, ActivityMessageEventHandler.class);
		addEventHandler(ActivitiEventType.ACTIVITY_COMPENSATE, ActivityCompensatedEventHandler.class);
		addEventHandler(ActivitiEventType.ACTIVITY_ERROR_RECEIVED, ActivityErrorReceivedEventHandler.class);
		
		addEventHandler(ActivitiEventType.VARIABLE_CREATED, VariableCreatedEventHandler.class);
		addEventHandler(ActivitiEventType.VARIABLE_DELETED, VariableDeletedEventHandler.class);
		addEventHandler(ActivitiEventType.VARIABLE_UPDATED, VariableUpdatedEventHandler.class);
  }
	
	@Override
	public void onEvent(ActivitiEvent event) {
		EventLoggerEventHandler eventHandler = getEventHandler(event);
		if (eventHandler != null) {

			// Events are flushed when command context is closed
			CommandContext currentCommandContext = Context.getCommandContext();
			EventFlusher eventFlusher = (EventFlusher) currentCommandContext.getAttribute(EVENT_FLUSHER_KEY);
			
			if (eventFlusher == null) {
				
				eventFlusher = createEventFlusher();
				if (eventFlusher == null) {
					eventFlusher = new DatabaseEventFlusher(); // Default
				}
				currentCommandContext.addAttribute(EVENT_FLUSHER_KEY, eventFlusher);
				
				currentCommandContext.addCloseListener(eventFlusher);
				currentCommandContext
				    .addCloseListener(new CommandContextCloseListener() {

					    @Override
					    public void closing(CommandContext commandContext) {
					    }

					    @Override
					    public void closed(CommandContext commandContext) {
						    // For those who are interested: we can now broadcast the events were added
								if (listeners != null) {
									for (EventLoggerListener listener : listeners) {
										listener.eventsAdded(EventLogger.this);
									}
								}
					    }

              public void afterSessionsFlush(CommandContext commandContext) {
              }

              @Override
              public void closeFailure(CommandContext commandContext) {
              }
					    
				    });
			}

			eventFlusher.addEventHandler(eventHandler);
		}
	}
	
	// Subclasses can override this if defaults are not ok
	protected EventLoggerEventHandler getEventHandler(ActivitiEvent event) {

		Class eventHandlerClass = null;
		if (event.getType().equals(ActivitiEventType.ENTITY_INITIALIZED)) {
			Object entity = ((ActivitiEntityEvent) event).getEntity();
			if (entity instanceof ExecutionEntity) {
				ExecutionEntity executionEntity = (ExecutionEntity) entity;
				if (executionEntity.getProcessInstanceId().equals(executionEntity.getId())) {
					eventHandlerClass = ProcessInstanceStartedEventHandler.class;
				}
			}
		} else if (event.getType().equals(ActivitiEventType.ENTITY_DELETED)) {
			Object entity = ((ActivitiEntityEvent) event).getEntity();
			if (entity instanceof ExecutionEntity) {
				ExecutionEntity executionEntity = (ExecutionEntity) entity;
				if (executionEntity.getProcessInstanceId().equals(executionEntity.getId())) {
					eventHandlerClass = ProcessInstanceEndedEventHandler.class;
				}
			}
		} else {
			// Default: dedicated mapper for the type
			eventHandlerClass = eventHandlers.get(event.getType());
		}
		
		if (eventHandlerClass != null) {
			return instantiateEventHandler(event, eventHandlerClass);
		}
		
		return null;
	}

	protected EventLoggerEventHandler instantiateEventHandler(ActivitiEvent event,
      Class eventHandlerClass) {
		try {
			EventLoggerEventHandler eventHandler = eventHandlerClass.newInstance();
			eventHandler.setTimeStamp(clock.getCurrentTime());
			eventHandler.setEvent(event);
			eventHandler.setObjectMapper(objectMapper);
			return eventHandler;
		} catch (Exception e) {
			logger.warn("Could not instantiate " + eventHandlerClass + ", this is most likely a programmatic error");
		}
		return null;
  }
	
	@Override
  public boolean isFailOnException() {
		return false;
  }
	
	public void addEventHandler(ActivitiEventType eventType, Class eventHandlerClass) {
		eventHandlers.put(eventType, eventHandlerClass);
	}
	
	public void addEventLoggerListener(EventLoggerListener listener) {
		if (listeners == null) {
			listeners = new ArrayList(1);
		}
		listeners.add(listener);
	}
	
	/**
	 * Subclasses that want something else than the database flusher should override this method
	 */
	protected EventFlusher createEventFlusher() {
		return null;
	}

	public Clock getClock() {
		return clock;
	}

	public void setClock(Clock clock) {
		this.clock = clock;
	}

	public ObjectMapper getObjectMapper() {
		return objectMapper;
	}

	public void setObjectMapper(ObjectMapper objectMapper) {
		this.objectMapper = objectMapper;
	}

	public List getListeners() {
		return listeners;
	}

	public void setListeners(List listeners) {
		this.listeners = listeners;
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy