/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* 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 should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: ProcessMgmt.java 2893 2009-01-20 17:02:33Z drmlipp $
*/
package de.danet.an.workflow.clients.mgmtportlets.process;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import de.danet.an.util.BeanSorter;
import de.danet.an.util.jsf.JSFUtil;
import de.danet.an.util.jsf.PortletEnvironment;
import de.danet.an.workflow.api.Activity;
import de.danet.an.workflow.api.CannotRemoveException;
import de.danet.an.workflow.api.InvalidKeyException;
import de.danet.an.workflow.api.Process;
import de.danet.an.workflow.api.ProcessDefinitionDirectory;
import de.danet.an.workflow.api.ProcessDirectory;
import de.danet.an.workflow.api.ProcessMgr;
import de.danet.an.workflow.api.RangeAccess;
import de.danet.an.workflow.api.WorkflowService;
import de.danet.an.workflow.api.query.AndOperation;
import de.danet.an.workflow.api.query.AscendingOrder;
import de.danet.an.workflow.api.query.ContextVariableEquality;
import de.danet.an.workflow.api.query.DescendingOrder;
import de.danet.an.workflow.api.query.FilterCriterion;
import de.danet.an.workflow.api.query.PropertyEquality;
import de.danet.an.workflow.api.query.SortCriterion;
import de.danet.an.workflow.clients.mgmtportlets.WorkflowServiceConnection;
import de.danet.an.workflow.omgcore.ProcessDataInfo;
import de.danet.an.workflow.omgcore.WfAssignment;
import de.danet.an.workflow.omgcore.WfResource;
/**
* This class provides the central model for process management.
* <code>getProcesses</code> returns the process definition list.
* @author lipp
*/
public class ProcessMgmt implements Serializable, PhaseListener {
private static final org.apache.commons.logging.Log logger
= org.apache.commons.logging.LogFactory.getLog (ProcessMgmt.class);
private static String L10N_MSGS
= "de.danet.an.workflow.clients.mgmtportlets.process.L10n";
private WorkflowServiceConnection wsc = null;
private BeanSorter processSorter = null;
private transient DataModel processesAsModel = null;
private transient List resourceList = null;
private transient Map resourceMap = null;
private transient DataModel resourcesAsModel = null;
private transient boolean resourcesTyped = false;
private transient List assignedActivitiesList = null;
private transient DataModel assignmentsAsModel = null;
private transient List processNames = null;
private transient List managerNames = null;
private transient List contextVariables = null;
private boolean reloadBeforeRendering = false;
private String selectedResourceKey = null;
private BeanSorter activitySorter = null;
private BeanSorter dataFieldSorter = null;
private BeanSorter auditEventSorter = null;
private BeanSorter resourceSorter = null;
private BeanSorter assignedActivitiesSorter = null;
private List selectedProcesses = new ArrayList();
private boolean showFilters = false;
private String nameFilter = "";
private String processKeyFilter = "";
private String managerNameFilter = "";
private String contextVariable = "";
private String contextValue = "";
/**
* Create a new instance with all attributes initialized
* to defaults or the given values.
*
*/
public ProcessMgmt() {
JSFUtil.addPhaseListenerForPortlet(this);
}
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#getPhaseId()
*/
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#beforePhase
*/
public void beforePhase(PhaseEvent evt) {
if (evt.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)) {
selectedProcesses.clear();
} else if (evt.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
if (reloadBeforeRendering) {
// Get updated process list before rendering
// (has have been modified by action)
processesAsModel = null;
processNames = null;
managerNames = null;
contextVariables = null;
resourceList = null;
resourceMap = null;
resourcesAsModel = null;
assignedActivitiesList = null;
assignmentsAsModel = null;
reloadBeforeRendering = false;
}
if (processesAsModel != null) {
RangeAccess ra = (RangeAccess)processesAsModel.getWrappedData();
try {
if (ra.itemCount() != processesAsModel.getRowCount()) {
processesAsModel = null;
}
} catch (RemoteException e) {
processesAsModel = null;
}
}
}
}
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#afterPhase
*/
public void afterPhase(PhaseEvent evt) {
if (evt.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
selectedProcesses.clear();
} else if (evt.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
processNames = null;
managerNames = null;
contextVariables = null;
resourceList = null;
resourceMap = null;
resourcesAsModel = null;
assignedActivitiesList = null;
assignmentsAsModel = null;
}
}
/**
* @return Returns the workflow service connection.
*/
public WorkflowServiceConnection getWorkflowServiceConnection() {
return wsc;
}
/**
* @param wsc The workflow service connection to set.
*/
public void setWorkflowServiceConnection(WorkflowServiceConnection wsc) {
this.wsc = wsc;
if (logger.isDebugEnabled ()) {
logger.debug ("Workflow service connection set to: " + wsc);
}
}
/**
* @return Returns the sorter.
*/
public BeanSorter getProcessSorter() {
return processSorter;
}
/**
* @param sorter The sorter to set.
*/
public void setProcessSorter(BeanSorter sorter) {
this.processSorter = sorter;
}
/**
* @return Returns the activitySorter.
*/
public BeanSorter getActivitySorter() {
return activitySorter;
}
/**
* @param activitySorter The activitySorter to set.
*/
public void setActivitySorter(BeanSorter activitySorter) {
this.activitySorter = activitySorter;
}
/**
* @return Returns the dataFieldSorter.
*/
public BeanSorter getDataFieldSorter() {
return dataFieldSorter;
}
/**
* @param dataFieldSorter The dataFieldSorter to set.
*/
public void setDataFieldSorter(BeanSorter dataFieldSorter) {
this.dataFieldSorter = dataFieldSorter;
}
/**
* @return Returns the auditEventSorter.
*/
public BeanSorter getAuditEventSorter() {
return auditEventSorter;
}
/**
* @param auditEventSorter The auditEventSorter to set.
*/
public void setAuditEventSorter(BeanSorter auditEventSorter) {
this.auditEventSorter = auditEventSorter;
}
/**
* @return Returns the principalsSorter.
*/
public BeanSorter getResourceSorter() {
return resourceSorter;
}
/**
* @param principalsSorter The principalsSorter to set.
*/
public void setResourceSorter(BeanSorter principalsSorter) {
this.resourceSorter = principalsSorter;
}
/**
* @return Returns the assignedActivitiesSorter.
*/
public BeanSorter getAssignedActivitiesSorter() {
return assignedActivitiesSorter;
}
/**
* @param assignedActivitiesSorter The assignedActivitiesSorter to set.
*/
public void setAssignedActivitiesSorter
(BeanSorter assignedActivitiesSorter) {
this.assignedActivitiesSorter = assignedActivitiesSorter;
}
/**
* @return the list of processes
*/
public DataModel getProcesses () {
if (processesAsModel == null
|| processSorter != null && processSorter.isModified()) {
logger.debug ("Retrieving process list");
processSorter.clearModified();
ProcessDirectory pd = null;
try {
pd = wsc.getWorkflowService().processDirectory();
SortCriterion sortCriterion = null;
SortCriterion lastSortCriterion = null;
for (Iterator i = processSorter.getSortCriteria().iterator();
i.hasNext();) {
BeanSorter.SortCriterion bsc
= (BeanSorter.SortCriterion)i.next();
SortCriterion sc = null;
if (bsc.isAscending()) {
sc = new AscendingOrder(bsc.getProperty());
} else {
sc = new DescendingOrder(bsc.getProperty());
}
if (sortCriterion == null) {
sortCriterion = sc;
}
if (lastSortCriterion != null) {
lastSortCriterion.setSubCriterion(sc);
}
lastSortCriterion = sc;
}
FilterCriterion processFilter = null;
if (nameFilter.length() > 0) {
processFilter = new PropertyEquality("name", nameFilter);
}
if (managerNameFilter.length() > 0) {
FilterCriterion fc = new PropertyEquality
("managerName", managerNameFilter);
if (processFilter == null) {
processFilter = fc;
} else {
processFilter = new AndOperation(processFilter, fc);
}
}
if (processKeyFilter.length() > 0) {
FilterCriterion fc
= new PropertyEquality ("key", processKeyFilter);
if (processFilter == null) {
processFilter = fc;
} else {
processFilter = new AndOperation(processFilter, fc);
}
}
if (contextVariable.length() > 0) {
FilterCriterion fc
= new ContextVariableEquality
(contextVariable, contextValue);
if (processFilter == null) {
processFilter = fc;
} else {
processFilter = new AndOperation(processFilter, fc);
}
}
FacesContext fc = FacesContext.getCurrentInstance();
PortletEnvironment portletEnv = (PortletEnvironment)
fc.getApplication().getVariableResolver().resolveVariable
(fc, "processPortletEnv");
Integer chunk = (Integer)
portletEnv.getPreferencesAsIntegers().get("displayedRows");
processesAsModel = new PaginatedDataModel
(pd.processes(processFilter, sortCriterion),
chunk.intValue());
} catch (RemoteException e) {
JSFUtil.addMessage(FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"resourceCurrentlyUnavailable", null, e);
} finally {
wsc.getWorkflowService().release(pd);
}
}
return processesAsModel;
}
/**
* Get the process names.
* @return process names as set of strings.
*/
public List getProcessNames () {
if (processNames == null) {
ProcessDirectory pd = null;
try {
pd = wsc.getWorkflowService().processDirectory();
processNames = new ArrayList ();
processNames.add(new SelectItem (""));
for (Iterator i = pd.processNames().iterator();
i.hasNext();) {
processNames.add (new SelectItem (i.next()));
}
} catch (RemoteException e) {
JSFUtil.addMessage(FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"resourceCurrentlyUnavailable", null, e);
} finally {
wsc.getWorkflowService().release(pd);
}
}
return processNames;
}
/**
* @return Returns the managerNames
*/
public List getManagerNames() {
if (managerNames == null) {
ProcessDirectory pd = null;
try {
pd = wsc.getWorkflowService().processDirectory();
managerNames = new ArrayList ();
managerNames.add(new SelectItem (""));
for (Iterator i = pd.processMgrNames().iterator();
i.hasNext();) {
managerNames.add (new SelectItem (i.next()));
}
} catch (RemoteException e) {
JSFUtil.addMessage(FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"resourceCurrentlyUnavailable", null, e);
} finally {
wsc.getWorkflowService().release(pd);
}
}
return managerNames;
}
/**
* @return Returns the context variable names
*/
public List getContextVariables () {
if (managerNameFilter.length() == 0) {
return new ArrayList();
}
if (contextVariables == null) {
ProcessDefinitionDirectory pdd = null;
try {
pdd = wsc.getWorkflowService().processDefinitionDirectory();
String[] ids = managerNameFilter.split("/");
ProcessMgr mgr = pdd.processMgr(ids[0], ids[1]);
ProcessDataInfo pdi = mgr.contextSignature();
contextVariables = new ArrayList ();
contextVariables.add(new SelectItem (""));
for (Iterator i = pdi.entrySet().iterator(); i.hasNext();) {
Map.Entry e = (Map.Entry)i.next();
if (e.getValue().equals(String.class)) {
contextVariables.add (new SelectItem (e.getKey()));
}
}
} catch (InvalidKeyException e) {
return new ArrayList ();
} catch (RemoteException e) {
JSFUtil.addMessage(FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"resourceCurrentlyUnavailable", null, e);
} finally {
wsc.getWorkflowService().release(pdd);
}
}
return contextVariables;
}
/**
* @return number of processes in list.
*/
public int getProcessCount () {
return getProcesses().getRowCount();
}
/**
* @return Returns the allSelected.
*/
public boolean isAllSelected() {
return false;
}
/**
* @param allSelected The allSelected to set.
*/
public void setAllSelected(boolean allSelected) {
if (!allSelected) {
return;
}
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().getRequestMap()
.put("processAllSelection", Boolean.TRUE);
}
/**
* @param process the process to add
*/
public void addSelected (Process process) {
selectedProcesses.add (process);
}
/**
* Remove given process.
*/
public void remove (Process process) throws RemoteException {
ProcessDirectory procDir = wsc.getWorkflowService().processDirectory();
try {
procDir.removeProcess(process);
} catch (CannotRemoveException e) {
JSFUtil.addMessage (FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"cannotRemove", null, e);
}
reloadBeforeRendering = true;
}
/**
* Remove selected processes.
*/
public String removeSelected () throws RemoteException {
ProcessDirectory procDir = wsc.getWorkflowService().processDirectory();
for (Iterator i = selectedProcesses.iterator(); i.hasNext();) {
Process process = (Process)i.next();
try {
procDir.removeProcess(process);
} catch (CannotRemoveException e) {
// Probably removed by other user
logger.debug(e.getMessage(), e);
}
}
reloadBeforeRendering = true;
return null;
}
/**
* Action for going to process list immediately.
*/
public String showProcessList () {
return "showProcessList";
}
/**
* @return the list of resources
*/
public DataModel getResources () {
if (resourcesAsModel == null) {
if (resourceList != null) {
logger.debug ("Using previously created process list");
if (resourceSorter != null && resourceSorter.isModified ()) {
logger.debug ("Re-sorting");
resourceSorter.sort (resourceList);
}
} else {
logger.debug ("Retrieving resource list");
resourceList = new ArrayList ();
resourceMap = new HashMap ();
try {
Collection resources
= wsc.getWorkflowService().knownResources();
Locale locale = JSFUtil.activeLocale();
ResourceBundle rb = ResourceBundle.getBundle
("de.danet.an.workflow.clients.mgmtportlets.process"
+ ".L10n", locale, ProcessMgmt.class.getClassLoader());
resourcesTyped = false;
for (Iterator i = resources.iterator(); i.hasNext ();) {
ResourceWrapper res
= new ResourceWrapper ((WfResource)i.next(), rb);
if (res.isTyped()) {
resourcesTyped = true;
}
resourceList.add (res);
resourceMap.put(res.getKey(), res);
}
} catch (RemoteException e) {
JSFUtil.addMessage(FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"resourceCurrentlyUnavailable", null, e);
}
if (resourceSorter != null) {
resourceSorter.sort (resourceList);
}
}
resourcesAsModel = new ListDataModel(resourceList);
} else {
if (resourceSorter != null && resourceSorter.isModified()) {
resourceSorter.sort (resourceList);
}
}
return resourcesAsModel;
}
/**
* Return if resources are typed.
*/
public boolean isResourcesTyped () {
if (resourcesAsModel == null) {
getResources();
}
return resourcesTyped;
}
/**
* @return Returns the selected resource's key.
*/
public String getSelectedResourceKey() {
return selectedResourceKey;
}
/**
* @param selectedResource The selectedResource to set.
*/
public void setSelectedResourceKey(String selectedResource) {
this.selectedResourceKey = selectedResource;
assignmentsAsModel = null;
assignedActivitiesList = null;
}
/**
* @return Returns the selected resource's key.
*/
public ResourceWrapper getSelectedResource() {
if (selectedResourceKey == null) {
return null;
}
getResources(); // make sure that the resourceMap is initialized
return (ResourceWrapper)resourceMap.get(selectedResourceKey);
}
/**
* @return the list of assigned activities
*/
public DataModel getAssignedActivities () {
if (assignmentsAsModel == null) {
if (assignedActivitiesList != null) {
logger.debug ("Using previously created assignments list");
if (assignedActivitiesSorter != null
&& assignedActivitiesSorter.isModified ()) {
logger.debug ("Re-sorting");
assignedActivitiesSorter.sort (assignedActivitiesList);
}
} else {
logger.debug ("Retrieving assignments list");
assignedActivitiesList = new ArrayList ();
if (selectedResourceKey != null) {
try {
WorkflowService wfs = wsc.getWorkflowService();
WfResource resource
= wfs.resourceByKey(selectedResourceKey);
Collection assignments = resource.workItems();
for (Iterator i = assignments.iterator(); i.hasNext ();) {
WfAssignment assignment = (WfAssignment)i.next();
assignedActivitiesList.add
(new ActivityWrapper
(wfs, (Activity)assignment.activity()));
}
} catch (RemoteException e) {
JSFUtil.addMessage(FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"resourceCurrentlyUnavailable", null, e);
} catch (InvalidKeyException e) {
selectedResourceKey = null;
}
}
if (assignedActivitiesSorter != null) {
assignedActivitiesSorter.sort (assignedActivitiesList);
}
}
assignmentsAsModel = new ListDataModel(assignedActivitiesList);
} else {
if (assignedActivitiesSorter != null
&& assignedActivitiesSorter.isModified()) {
assignedActivitiesSorter.sort (assignedActivitiesList);
}
}
return assignmentsAsModel;
}
/**
* Action for going to resurces list immediately.
*/
public String showResources () {
return "showResources";
}
/**
* Refresh the view
* @return
*/
public String refresh () {
processesAsModel = null;
return null;
}
/**
* Show filters.
*/
public String showFilters () {
setShowFilters(true);
setNameFilter("");
setProcessKeyFilter("");
setManagerNameFilter("");
setContextVariable("");
setContextValue("");
return null;
}
/**
* Hide filters.
*/
public String hideFilters () {
setShowFilters(false);
setNameFilter("");
setProcessKeyFilter("");
setManagerNameFilter("");
setContextVariable("");
setContextValue("");
return null;
}
/**
* @return Returns the showFilters.
*/
public boolean isShowFilters() {
return showFilters;
}
/**
* @param showFilters The showFilters to set.
*/
public void setShowFilters(boolean showFilters) {
this.showFilters = showFilters;
}
/**
* @return Returns the nameFilter.
*/
public String getNameFilter() {
return nameFilter;
}
/**
* @param nameFilter The nameFilter to set.
*/
public void setNameFilter(String nameFilter) {
// Normalize
if (nameFilter == null) {
nameFilter = "";
}
if (!this.nameFilter.equals(nameFilter)) {
this.nameFilter = nameFilter;
reloadBeforeRendering = true;
}
}
/**
* @return Returns the processKeyFilter.
*/
public String getProcessKeyFilter() {
return processKeyFilter;
}
/**
* @param processKeyFilter The processKeyFilter to set.
*/
public void setProcessKeyFilter(String processKeyFilter) {
// Normalize
if (processKeyFilter == null) {
processKeyFilter = "";
}
if (!this.processKeyFilter.equals(processKeyFilter)) {
this.processKeyFilter = processKeyFilter;
reloadBeforeRendering = true;
}
}
/**
* @return Returns the managerNameFilter.
*/
public String getManagerNameFilter() {
return managerNameFilter;
}
/**
* @param managerNameFilter The managerNameFilter to set.
*/
public void setManagerNameFilter(String managerNameFilter) {
// Normalize
if (managerNameFilter == null) {
managerNameFilter = "";
}
if (!this.managerNameFilter.equals(managerNameFilter)) {
this.managerNameFilter = managerNameFilter;
reloadBeforeRendering = true;
}
}
/**
* @return Returns the contextVariable.
*/
public String getContextVariable() {
return contextVariable;
}
/**
* @param contextVariable The contextVariable to set.
*/
public void setContextVariable(String contextVariable) {
// Normalize
if (contextVariable == null) {
contextVariable = "";
}
if (!this.contextVariable.equals(contextVariable)) {
this.contextVariable = contextVariable;
reloadBeforeRendering = true;
}
}
/**
* @return Returns the contextValue.
*/
public String getContextValue() {
return contextValue;
}
/**
* @param contextValue The contextValue to set.
*/
public void setContextValue(String contextValue) {
// Normalize
if (contextValue == null) {
contextValue = "";
}
if (!this.contextValue.equals(contextValue)) {
this.contextValue = contextValue;
reloadBeforeRendering = true;
}
}
/**
* Apply filters.
*/
public String applyFilters () {
return null;
}
}