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

org.ow2.bonita.facade.runtime.impl.ActivityInstanceImpl Maven / Gradle / Ivy

/**
 * Copyright (C) 2007  Bull S. A. S.
 * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation
 * version 2.1 of the License.
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License along with this
 * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA  02110-1301, USA.
 **/
package org.ow2.bonita.facade.runtime.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.ow2.bonita.facade.runtime.ActivityInstance;
import org.ow2.bonita.facade.runtime.ActivityState;
import org.ow2.bonita.facade.runtime.AssignUpdate;
import org.ow2.bonita.facade.runtime.StateUpdate;
import org.ow2.bonita.facade.runtime.TaskInstance;
import org.ow2.bonita.facade.runtime.Update;
import org.ow2.bonita.facade.runtime.VariableUpdate;
import org.ow2.bonita.facade.uuid.ActivityInstanceUUID;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessInstanceUUID;
import org.ow2.bonita.pvm.internal.type.Variable;
import org.ow2.bonita.util.CopyTool;
import org.ow2.bonita.util.ExceptionManager;
import org.ow2.bonita.util.Misc;


/**
 * @author Pierre Vigneras
 */
public class ActivityInstanceImpl extends RuntimeRecordImpl implements ActivityInstance, TaskInstance {
	private static final long serialVersionUID = -8515098234372896097L;

	protected long dbid;

	protected ActivityInstanceUUID uuid;
	protected String activityName;
	protected String activityLabel;
	protected String activityDescription;
	protected String iterationId;
	protected String activityInstanceId;
	protected List stateUpdates = new ArrayList();

	protected boolean isTask;

	protected Map variables;
	
	protected List variableUpdates = new ArrayList();

	protected List assignUpdates;

	protected ActivityInstanceImpl() { }

	public ActivityInstanceImpl(final ActivityInstanceUUID uuid, final String activityName, final String activityLabel, final String activityDescription,
			final ProcessDefinitionUUID processUUID,
			final ProcessInstanceUUID instanceUUID, final String iterationId, final String activityInstanceId, final boolean isTask) {
		super(processUUID, instanceUUID);
		this.uuid = uuid;
		this.activityName = activityName;
		this.activityLabel = activityLabel;
		this.activityDescription = activityDescription;
		this.iterationId = iterationId;
		this.activityInstanceId = activityInstanceId;

		this.isTask = isTask;
	}

	public ActivityInstanceImpl(final ActivityInstance src) {
		super(src);
		this.uuid = new ActivityInstanceUUID(src.getUUID());
		this.activityName = src.getActivityName();
		this.activityLabel = src.getActivityLabel();
		this.activityDescription = src.getActivityDescription();
		this.iterationId = src.getIterationId();
		this.activityInstanceId = src.getActivityInstanceId();

		this.variables = CopyTool.createVariableMap(src.getVariablesBeforeStarted());

		List list = src.getVariableUpdates();
		if (list != null && !list.isEmpty()) {
			this.variableUpdates = new ArrayList();
			for (VariableUpdate varUpdate : list) {
				this.variableUpdates.add(new VariableUpdateImpl(varUpdate));
			}
		}
		final List stateList = src.getStateUpdates();
		if (stateList != null && !stateList.isEmpty()) {
			this.stateUpdates = new ArrayList();
			for (final StateUpdate update : stateList) {
				this.stateUpdates.add(new StateUpdateImpl(update));
			}
		}
		this.isTask = src.isTask();

		if (isTask()) {
			TaskInstance task = src.getTask();

			List assignList = task.getAssignUpdates();
			if (assignList != null && !assignList.isEmpty()) {
				this.assignUpdates = new ArrayList();
				for (AssignUpdate update : assignList) {
					this.assignUpdates.add(new AssignUpdateImpl(update));
				}
			}
		}
	}

	public String getActivityLabel() {
		return activityLabel;
	}

	public String getActivityDescription() {
		return activityDescription;
	}

	public String toString() {
		String userId;
		try {
			userId = getTaskUser();
		} catch (IllegalStateException e) {
			userId = null;
		}
		Set candidates;
		try {
			candidates = getTaskCandidates();
		} catch (IllegalStateException e) {
			candidates = null;
		}

		String st = this.getClass().getName()
		+ "[uuid: " + getUUID()
		    + ", activityId: " + getActivityName()
		    + ", iterationId: " + getIterationId()
		    + ", processDefinitionUUID: " + getProcessDefinitionUUID()
		    + ", processUUID: " + getProcessInstanceUUID()
		    + ", variablesBeforeStarted: " + getVariablesBeforeStarted()
		    + ", variableUpdates: " + getVariableUpdates()
		    + ", startedDate: " + getStartedDate()
		    + ", endedDate: " + getEndedDate()
		    + ", readyDate: " + getReadyDate()
		    + ", userId: " + userId
		    + ", candidates: " + candidates
		    + ", state: " + getState()
		    + ", createdDate: " + getCreatedDate()
		    + ", startedBy: " + getStartedBy()
		    + ", startedDate: " + getStartedDate()
		    + ", endedDate: " + getEndedDate()
		    + ", endedBy: " + getEndedBy()
		    + "]";
		return st;
	}

	public Map getVariablesBeforeStarted() {
		return CopyTool.getVariableValues(this.variables);
	}

	public Object getVariableValueBeforeStarted(String variableId) {
		return getVariablesBeforeStarted().get(variableId);
	}

	public TaskInstance getTask() {
		if (isTask()) {
			return (TaskInstance) this;
		}
		return null;
	}

	public boolean isTask() {
		return isTask;
	}

	public String getIterationId() {
		return this.iterationId;
	}


	public String getActivityInstanceId() {
		return activityInstanceId;
	}

	public String getActivityName() {
		return activityName;
	}


	public List getVariableUpdates() {
		return variableUpdates;
	}

	public Map getLastKnownVariableValues() {
		Map var = getVariablesBeforeStarted();
		if (var != null) {
			var = new HashMap(var);
		} else {
			var = new HashMap();
		}
		for (VariableUpdate varUp : getVariableUpdates()) {
			var.put(varUp.getName(), varUp.getValue());
		}
		return var;
	}


	public ActivityInstanceUUID getUUID() {
		return uuid;
	}

	private StateUpdate getFirstStateUpdate(final ActivityState... activityStates) {
		if (this.stateUpdates != null && activityStates != null && activityStates.length > 0) {
			for (StateUpdate su : this.stateUpdates) {
				ActivityState state = su.getActivityState();
				for (ActivityState as : activityStates) {
					if (as.equals(state)) {
						return su;
					}
				}
			}
		}
		return null;
	}

	public Date getStartedDate() {
		StateUpdate su = getFirstStateUpdate(ActivityState.EXECUTING);
		if (su != null) {
			return su.getUpdatedDate();
		}
		return null;
	}

	public Date getEndedDate() {
		StateUpdate su = getFirstStateUpdate(ActivityState.FINISHED, ActivityState.ABORTED, ActivityState.CANCELLED);
		if (su != null) {
			return su.getUpdatedDate();
		}
		return null;
	}

	public Date getReadyDate() {
		StateUpdate su = getFirstStateUpdate(ActivityState.READY);
		if (su != null) {
			return su.getUpdatedDate();
		}
		return null;
	}

	public Date getCreatedDate() {
		return getReadyDate();
	}

	public String getEndedBy() {
		StateUpdate su = getFirstStateUpdate(ActivityState.FINISHED, ActivityState.ABORTED, ActivityState.CANCELLED);
		if (su != null) {
			return su.getUpdatedBy();
		}
		return null;
	}

	public String getStartedBy() {
		StateUpdate su = getFirstStateUpdate(ActivityState.EXECUTING);
		if (su != null) {
			return su.getUpdatedBy();
		}
		return null;
	}

	public List getStateUpdates() {
		return this.stateUpdates;
	}

	public ActivityState getState() {
		if (getStateUpdates() != null && !getStateUpdates().isEmpty()) {
			final StateUpdate stateUpdate = getStateUpdates().get(getStateUpdates().size() - 1);
			if (stateUpdate.getActivityState() != null) {
				return stateUpdate.getActivityState();
			}
		}
		return ActivityState.READY;
	}

	public void setActivityState(final ActivityState newState, final String userId) {
		// TODO: why not simply calling getState() to have old state ?
				ActivityState oldState;
	final Date actual = new Date();
	if (getStateUpdates().isEmpty()) {
		oldState = ActivityState.READY;
	} else {
		// get last state update
		final StateUpdate oldStateUpdate = getStateUpdates().get(getStateUpdates().size() - 1);
		final Date lastUpdate = oldStateUpdate.getUpdatedDate();
		//get the old task state from the previous update
		oldState = oldStateUpdate.getActivityState();
		// check last state update append before this state update
		if (actual.before(lastUpdate)) {
			UpdateImpl.logClockInconsistency();
		}
	}
	//add a state update
	this.getStateUpdates().add(new StateUpdateImpl(actual, newState, oldState, userId));
	}

	public void addVariableUpdate(final VariableUpdate varUpdate) {
		this.variableUpdates.add(varUpdate);
	}

	public String getUpdatedBy() {
		Update lastUpdate = getLastUpdate();
		if (lastUpdate == null) {
			return null;
		}
		if (lastUpdate.getUpdatedBy() != null) {
			return lastUpdate.getUpdatedBy();
		}
		String message = ExceptionManager.getInstance().getFullMessage("baoi_TII_2", this.getUUID());
		throw new IllegalStateException(message);
	}

	public String getTaskUser() {
		//only AssignUpdate type has recorded userId
		AssignUpdate last = getLastAssignUpdate();
		if (last != null) {
			return last.getAssignedUserId();
		}
		/*
    if (getAssignUpdates() != null && !getAssignUpdates().isEmpty()) {
      AssignUpdate assignUpdate = getAssignUpdates().get(getAssignUpdates().size() - 1);
      if (assignUpdate.getAssignedUserId() != null) {
        return assignUpdate.getAssignedUserId();
      }
    }
		 */
		return null;
	}

	public Set getTaskCandidates() {
		if (getAssignUpdates() != null && !getAssignUpdates().isEmpty()) {
			AssignUpdate assignUpdate = getAssignUpdates().get(getAssignUpdates().size() - 1);
			if (assignUpdate.getCandidates() != null) {
				return assignUpdate.getCandidates();
			}
		}
		return Collections.emptySet();
	}

	public boolean isTaskAssigned() {
		return getTaskUser() != null;
	}

	public List getAssignUpdates() {
		return assignUpdates;
	}

	public StateUpdate getLastStateUpdate() {
		if (stateUpdates != null && !stateUpdates.isEmpty()) {
			return stateUpdates.get(stateUpdates.size() - 1); 
		}
		return null;
	}

	public AssignUpdate getLastAssignUpdate() {
		if (assignUpdates != null && !assignUpdates.isEmpty()) {
			return assignUpdates.get(assignUpdates.size() - 1); 
		}
		return null;
	}

	protected Update getLastUpdate() {
		Update lastState = null;
		if (stateUpdates != null && !stateUpdates.isEmpty()) { 
			lastState = stateUpdates.get(stateUpdates.size() - 1);
		}

		Update lastAssign = null;
		if (assignUpdates != null && !assignUpdates.isEmpty()) { 
			lastAssign = assignUpdates.get(assignUpdates.size() - 1);
		}

		if (lastState == null && lastAssign == null) {
			return null;
		} else if (lastState == null && lastAssign != null) { 
			return lastAssign;
		} else if (lastState != null && lastAssign == null) {
			return lastState;
		}
		int comp = lastAssign.getUpdatedDate().compareTo(lastState.getUpdatedDate());
		if (comp == 0 || comp == 1) {
			return lastState;
		}
		return lastAssign;
	}

	public void setTaskAssign(final ActivityState taskState,
			final String loggedInUserId,
			final Set candidates,
			final String assignedUserId) {
		if (getAssignUpdates() == null) {
			this.assignUpdates = new ArrayList();
		} else {
			if (!getAssignUpdates().isEmpty()
					&& new Date().before(getAssignUpdates().get(getAssignUpdates().size() - 1).getUpdatedDate())) {
				UpdateImpl.logClockInconsistency();
			}
		}
		this.getAssignUpdates().add(new AssignUpdateImpl(new Date(), taskState, loggedInUserId, candidates, assignedUserId));
	}

	public void setVariablesBeforeReady(final Map variables) {
		Misc.badStateIfNotNull(this.variables, "variablesBeforeStarted can not be set twice!");
		this.variables = variables;
	}

	public long getDbid() {
		return dbid;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy