/*******************************************************************************
* Imixs Workflow
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
* http://www.imixs.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You can receive a copy of the GNU General Public
* License at http://www.gnu.org/licenses/gpl.html
*
* Project:
* http://www.imixs.org
* http://java.net/projects/imixs-workflow
*
* Contributors:
* Imixs Software Solutions GmbH - initial API and implementation
* Ralph Soika - Software Developer
*******************************************************************************/
package org.imixs.marty.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.inject.Named;
import org.imixs.marty.ejb.ProcessService;
import org.imixs.marty.ejb.ProfileService;
import org.imixs.marty.util.WorkitemHelper;
import org.imixs.marty.workflow.WorkflowEvent;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.ItemCollectionComparator;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.engine.WorkflowService;
import org.imixs.workflow.faces.util.LoginController;
/**
* The ProcessController provides informations about the process and space
* entities. A Workitem can be assigned to a process and one or more spaces. The
* controller is session scoped and holds information depending on the current
* user grants.
*
* The ProcessController can load a process and provide agregated information
* about the process like the Team or member lists
*
* @author rsoika
*
*/
@Named("processController")
@SessionScoped
public class ProcessController implements Serializable {
private static final long serialVersionUID = 1L;
private List<ItemCollection> spaces = null;
private List<ItemCollection> processList = null;
private ItemCollection process = null;
@Inject
protected LoginController loginController = null;
@EJB
protected DocumentService documentService;
@EJB
protected ProcessService processService;
@EJB
protected ProfileService profileService;
private static Logger logger = Logger.getLogger(ProcessController.class
.getName());
/**
* Reset the internal cache
*/
@PostConstruct
public void reset() {
spaces = null;
processList = null;
process = null;
}
/**
* Returns the current process entity
*
* @return
*/
public ItemCollection getProcess() {
return process;
}
/**
* Set the current process entity
*
* @param process
*/
public void setProcess(ItemCollection process) {
this.process = process;
}
/**
* Loads a process entity by its UniqueID from the internal cache and
* updates the current process entity.
*
* @param uniqueid
* - of process entity
*
* @return current process entity
*/
public ItemCollection loadProcess(String uniqueid) {
if (this.process == null
|| !this.process.getItemValue(WorkflowService.UNIQUEID).equals(
uniqueid)) {
setProcess(this.getProcessById(uniqueid));
}
return getProcess();
}
/**
* Returns the process for a given uniqueID. The method uses the internal
* cache.
*
* @param uniqueId
* @return itemCollection of process or null if not process with the
* specified id exists
*/
public ItemCollection getProcessById(String uniqueId) {
if (uniqueId != null && !uniqueId.isEmpty()) {
// iterate over all spaces and compare the $UniqueIDRef
List<ItemCollection> list = getProcessList();
for (ItemCollection process : list) {
if (uniqueId.equals(process
.getItemValueString(WorkflowService.UNIQUEID))) {
return process;
}
}
}
return null;
}
/**
* This method returns all process entities - indepenedend if the current
* user is member of.
*
* The returned project list is optimized and provides additional the
* following attributes
* <p>
* isMember, isTeam, isOwner, isManager, isAssist
*
* @return
*/
public List<ItemCollection> getProcessList() {
if (processList == null) {
processList = processService.getProcessList();
}
return processList;
}
/**
* This method returns all space entities for the current user. This list
* can be used to display space informations inside a form. The returned
* space list is optimized and provides additional the following attributes
* <p>
* isMember, isTeam, isOwner, isManager, isAssist
*
* @return
*/
@SuppressWarnings("unchecked")
public List<ItemCollection> getSpaces() {
if (spaces == null) {
spaces = new ArrayList<ItemCollection>();
// String sQuery = "SELECT space FROM Entity AS space "
// + " JOIN space.textItems AS t2"
// + " WHERE space.type = 'space'"
// + " AND t2.itemName = 'txtname'"
// + " ORDER BY t2.itemValue asc";
List<ItemCollection> col = documentService.getDocumentsByType("space");
// sort by txtname
Collections.sort(col, new ItemCollectionComparator("txtname", true));
// create optimized list
for (ItemCollection space : col) {
ItemCollection clone = WorkitemHelper.clone(space);
clone.replaceItemValue("isTeam", false);
clone.replaceItemValue("isManager", false);
// check the isTeam status for the current user
List<String> userNameList = documentService.getUserNameList();
Vector<String> vNameList = (Vector<String>) space
.getItemValue("namTeam");
// check if one entry matches....
for (String username : userNameList) {
if (vNameList.indexOf(username) > -1) {
clone.replaceItemValue("isTeam", true);
break;
}
}
// check the isManager status for the current user
vNameList = (Vector<String>) space.getItemValue("namManager");
// check if one entry matches....
for (String username : userNameList) {
if (vNameList.indexOf(username) > -1) {
clone.replaceItemValue("isManager", true);
break;
}
}
// check the isAssist status for the current user
vNameList = (Vector<String>) space.getItemValue("namAssist");
// check if one entry matches....
for (String username : userNameList) {
if (vNameList.indexOf(username) > -1) {
clone.replaceItemValue("isAssist", true);
break;
}
}
// check if user is member of team or manager list
boolean bMember = false;
if (clone.getItemValueBoolean("isTeam")
|| clone.getItemValueBoolean("isManager")
|| clone.getItemValueBoolean("isAssist"))
bMember = true;
clone.replaceItemValue("isMember", bMember);
// add custom fields into clone...
clone.replaceItemValue("txtdescription",
space.getItemValue("txtdescription"));
spaces.add(clone);
}
}
return spaces;
}
/**
* This method returns a space or process entity by its UniqueID. The space
* and process entities are read from the internal cache.
*
* @param uniqueid
* @return
*/
public ItemCollection getEntityById(String uniqueid) {
if (uniqueid == null || uniqueid.isEmpty())
return null;
// get the process list form local cache
List<ItemCollection> alist = getProcessList();
for (ItemCollection aProcess : alist) {
if (uniqueid.equals(aProcess
.getItemValueString(WorkflowService.UNIQUEID)))
return aProcess;
}
// get the space list form local cache
alist = getSpaces();
for (ItemCollection aSpace : alist) {
if (uniqueid.equals(aSpace
.getItemValueString(WorkflowService.UNIQUEID)))
return aSpace;
}
return null;
}
/**
* Returns a Space for a given uniqueID.
*
* @param uniqueId
* @return itemCollection of process or null if not process with the
* specified id exists
*/
public ItemCollection getSpaceById(String uniqueId) {
if (uniqueId != null && !uniqueId.isEmpty()) {
// iterate over all spaces and compare the $UniqueIDRef
List<ItemCollection> list = getSpaces();
for (ItemCollection space : list) {
if (uniqueId.equals(space
.getItemValueString(WorkflowService.UNIQUEID))) {
return space;
}
}
}
return null;
}
/**
* Returns a process by its name
*
* @param name
* @return itemCollection of process or null if not process with the
* specified id exists
*/
public ItemCollection getProcessByName(String name) {
if (name != null && !name.isEmpty()) {
// iterate over all processes and compare the txtname
List<ItemCollection> list = getProcessList();
for (ItemCollection process : list) {
if (name.equals(process.getItemValueString("txtName"))) {
return process;
}
}
}
return null;
}
/**
* Returns a space by its name
*
* @param name
* @return itemCollection of process or null if not process with the
* specified id exists
*/
public ItemCollection getSpaceByName(String name) {
if (name != null && !name.isEmpty()) {
// iterate over all processes and compare the txtname
List<ItemCollection> list = getSpaces();
for (ItemCollection process : list) {
if (name.equals(process.getItemValueString("txtName"))) {
return process;
}
}
}
return null;
}
/**
* Returns a list of all spaces which are assigned to a given process
* entity.
*
* @param uniqueId
* of a processEntity
* @return
*/
public List<ItemCollection> getSpacesByProcessId(String uniqueId) {
List<ItemCollection> result = new ArrayList<ItemCollection>();
if (uniqueId != null && !uniqueId.isEmpty()) {
// find project
ItemCollection process = getProcessById(uniqueId);
result = getSpacesByProcess(process);
}
return result;
}
/**
* Returns a list of all spaces which are assigned to a given process
* entity.
*
* @param uniqueId
* of a processEntity
* @return
*/
@SuppressWarnings("unchecked")
public List<ItemCollection> getSpacesByProcess(ItemCollection process) {
List<ItemCollection> result = new ArrayList<ItemCollection>();
if (process != null) {
Vector<String> refs = (Vector<String>) process
.getItemValue("$UniqueIDRef");
if (refs != null && !refs.isEmpty()) {
// iterate over all spaces and compare the $UniqueIDRef
List<ItemCollection> list = getSpaces();
for (ItemCollection space : list) {
if (refs.contains(space
.getItemValueString(WorkflowService.UNIQUEID))) {
result.add(space);
}
}
}
}
return result;
}
/**
* Returns a list of all spaces which are siblings to a given UniqueID.
*
* @param uniqueId
* @return
*/
public List<ItemCollection> getSpacesByRef(String uniqueId) {
List<ItemCollection> result = new ArrayList<ItemCollection>();
if (uniqueId != null && !uniqueId.isEmpty()) {
// iterate over all spaces and compare the $UniqueIDRef
List<ItemCollection> list = getSpaces();
for (ItemCollection space : list) {
logger.fine("Spacename= " + space.getItemValueString("txtName")
+ " uniquidref= "
+ space.getItemValueString(WorkflowService.UNIQUEIDREF));
if (uniqueId.equals(space
.getItemValueString(WorkflowService.UNIQUEIDREF))) {
result.add(space);
}
}
}
return result;
}
/**
* Returns a unique sorted list of managers for the current project. The
* returned list contains cloned user profile entities.
*
*
* @return list of profile entities for the current team managers
*/
public List<ItemCollection> getManagers(String aUniqueID) {
List<ItemCollection> resultList = getMemberListByRole(aUniqueID,
"namManager");
// sort by username..
Collections.sort(resultList,
new ItemCollectionComparator("txtUserName", true));
return resultList;
}
/**
* Returns a unique sorted list of team members for the current project. The
* returned list contains cloned user profile entities.
*
*
* @return list of profile entities for the current team members
*/
public List<ItemCollection> getTeam(String aUniqueID) {
List<ItemCollection> resultList = getMemberListByRole(aUniqueID,
"namTeam");
// sort by username..
Collections.sort(resultList,
new ItemCollectionComparator("txtUserName", true));
return resultList;
}
/**
* Returns a unique sorted list of assist members for the current project.
* The returned list contains cloned user profile entities.
*
*
* @return list of profile entities for the current team members
*/
public List<ItemCollection> getAssist(String aUniqueID) {
List<ItemCollection> resultList = getMemberListByRole(aUniqueID,
"namAssist");
// sort by username..
Collections.sort(resultList,
new ItemCollectionComparator("txtUserName", true));
return resultList;
}
/**
* Returns a unique sorted list of all members (Managers, Team, Assist) for
* the current project. The returned list contains cloned user profile
* entities.
*
*
* @return list of profile entities for the current team members
*/
public List<ItemCollection> getProcessMembers(String aUniqueID) {
List<ItemCollection> resultList = new ArrayList<ItemCollection>();
List<String> dupplicatedIds = new ArrayList<String>();
List<ItemCollection> assistList = getMemberListByRole(aUniqueID,
"namAssist");
List<ItemCollection> teamList = getMemberListByRole(aUniqueID,
"namTeam");
List<ItemCollection> managerList = getMemberListByRole(aUniqueID,
"namManager");
for (ItemCollection profile : teamList) {
// avoid duplicates..
if (!dupplicatedIds.contains(profile
.getItemValueString(WorkflowService.UNIQUEID))) {
resultList.add(profile);
}
dupplicatedIds.add(profile
.getItemValueString(WorkflowService.UNIQUEID));
}
for (ItemCollection profile : managerList) {
// avoid duplicates..
if (!dupplicatedIds.contains(profile
.getItemValueString(WorkflowService.UNIQUEID))) {
resultList.add(profile);
}
dupplicatedIds.add(profile
.getItemValueString(WorkflowService.UNIQUEID));
}
for (ItemCollection profile : assistList) {
// avoid duplicates..
if (!dupplicatedIds.contains(profile
.getItemValueString(WorkflowService.UNIQUEID))) {
resultList.add(profile);
}
dupplicatedIds.add(profile
.getItemValueString(WorkflowService.UNIQUEID));
}
// sort by username..
Collections.sort(resultList,
new ItemCollectionComparator("txtUserName", true));
return resultList;
}
/**
* Returns true if current user is manager of a given space or process
* entity. Therefore the method checks the cloned field 'isManager'
*
* @return
*/
public boolean isManagerOf(String aUniqueID) {
// find Process/Space entity
ItemCollection entity = getEntityById(aUniqueID);
if (entity != null)
return entity.getItemValueBoolean("isManager");
else
return false;
}
/**
* Returns true if current user is member of the teamList of a given project
* Therefore the method checks the cloned field 'isTeam'
*
* @return
*/
public boolean isTeamMemberOf(String aUniqueID) {
// find project
ItemCollection entity = getEntityById(aUniqueID);
if (entity != null)
return entity.getItemValueBoolean("isTeam");
else
return false;
}
/**
* Returns true if current user is teamMember or manager of a given space or
* process
*
* @return
*/
@SuppressWarnings("unchecked")
public boolean isMemberOf(String aUniqueID) {
// find project
ItemCollection entity = getEntityById(aUniqueID);
if (entity != null) {
String remoteUser = loginController.getUserPrincipal();
List<String> vTeam = entity.getItemValue("namTeam");
List<String> vManager = entity.getItemValue("namManager");
if (vTeam.indexOf(remoteUser) > -1
|| vManager.indexOf(remoteUser) > -1)
return true;
}
return false;
}
/**
* WorkflowEvent listener
*
* If a project WorkItem was processed the modellController will be reseted.
*
*
* @param workflowEvent
*/
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) {
if (workflowEvent == null)
return;
if (WorkflowEvent.WORKITEM_AFTER_PROCESS == workflowEvent
.getEventType()) {
// test if a space or process entity was processed
String sType = workflowEvent.getWorkitem().getItemValueString(
"type");
if ("space".equals(sType) || "process".equals(sType)) {
reset();
logger.fine("ModelController:WorkflowEvent="
+ workflowEvent.getEventType());
}
}
}
/**
* Returns a unique sorted list of profile itemCollections for a team list
* in a project. The returned list contains cloned user profile entities.
*
* @param listType
* - the member field of the project (namTeam, namManager,
* namAssist)
* @return list of team profiles
*/
@SuppressWarnings("unchecked")
private List<ItemCollection> getMemberListByRole(String aUniqueID,
String role) {
List<ItemCollection> resultList = new ArrayList<ItemCollection>();
List<String> dupplicatedIds = new ArrayList<String>();
// find Process/Space entity
ItemCollection entity = getEntityById(aUniqueID);
if (entity == null)
return resultList;
List<String> members = entity.getItemValue(role);
for (String member : members) {
// avoid duplicates..
if (!dupplicatedIds.contains(member)) {
ItemCollection profile = profileService.findProfileById(member);
if (profile != null) {
resultList.add(profile);
}
dupplicatedIds.add(member);
}
}
return resultList;
}
}