/*
* 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: ProcDefMgmt.java 2443 2007-09-07 19:17:17Z mlipp $
*
* $Log$
* Revision 1.20 2007/09/06 06:08:40 mlipp
* Fixed problem with process definition display not being updated
* after process definition upload.
*
* Revision 1.19 2007/03/04 20:09:41 mlipp
* Optimized table model loading.
*
* Revision 1.18 2006/12/04 14:17:56 drmlipp
* Fixed multiple deletes.
*
* Revision 1.17 2006/11/23 14:55:03 drmlipp
* Improved performance.
*
* Revision 1.16 2006/09/29 12:32:13 drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.15 2005/11/10 20:52:55 mlipp
* Fixed problem with classloader dependend Lifecycle access.
*
* Revision 1.14 2005/11/07 16:41:38 drmlipp
* Added multi deletes.
*
* Revision 1.13 2005/10/31 16:38:02 drmlipp
* Implementation of debug features continued.
*
* Revision 1.12 2005/10/04 14:28:32 drmlipp
* Improved debug messages.
*
* Revision 1.11 2005/09/28 15:12:41 drmlipp
* Updated MyFaces to 1.1.
*
* Revision 1.10 2005/09/16 15:17:06 drmlipp
* Improved handling of missing file.
*
* Revision 1.9 2005/09/16 13:51:50 drmlipp
* Finished process definition upload and improved UI.
*
* Revision 1.8 2005/09/14 15:23:14 drmlipp
* Added process defintion upload portlet.
*
* Revision 1.7 2005/09/08 15:14:31 drmlipp
* Added possibility to get list size.
*
* Revision 1.6 2005/06/22 15:14:01 drmlipp
* Added delete icon.
*
* Revision 1.5 2005/06/22 12:53:21 drmlipp
* Added enabled column.
*
* Revision 1.4 2005/06/22 07:43:53 drmlipp
* Completed sorting, added process creation.
*
* Revision 1.3 2005/06/20 15:09:30 drmlipp
* Added columns, started process creation.
*
* Revision 1.2 2005/06/16 15:10:51 drmlipp
* Added create column, started using MyFaces data table.
*
* Revision 1.1 2005/05/11 14:28:57 drmlipp
* Initial version of process definition table.
*
*/
package de.danet.an.workflow.clients.mgmtportlets.procdef;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
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 de.danet.an.util.BeanSorter;
import de.danet.an.util.jsf.JSFUtil;
import de.danet.an.workflow.omgcore.AlreadyRunningException;
import de.danet.an.workflow.omgcore.CannotStartException;
import de.danet.an.workflow.omgcore.InvalidRequesterException;
import de.danet.an.workflow.omgcore.InvalidStateException;
import de.danet.an.workflow.omgcore.NotEnabledException;
import de.danet.an.workflow.omgcore.RequesterRequiredException;
import de.danet.an.workflow.api.DefaultRequester;
import de.danet.an.workflow.api.InvalidKeyException;
import de.danet.an.workflow.api.Process;
import de.danet.an.workflow.api.ProcessDefinition;
import de.danet.an.workflow.api.ProcessDefinitionDirectory;
import de.danet.an.workflow.api.ProcessMgr;
import de.danet.an.workflow.clients.mgmtportlets.ApplicationContext;
import de.danet.an.workflow.clients.mgmtportlets.WorkflowServiceConnection;
/**
* The process definition list.
* @author lipp
*/
public class ProcDefMgmt implements PhaseListener {
private static final org.apache.commons.logging.Log logger
= org.apache.commons.logging.LogFactory.getLog (ProcDefMgmt.class);
private static String L10N_MSGS
= "de.danet.an.workflow.clients.mgmtportlets.procdef.L10n";
private ApplicationContext applicationContext = null;
private WorkflowServiceConnection wsc = null;
private BeanSorter sorter = null;
private transient List defListCache = null;
private transient DataModel defsModelCache = null;
private boolean reloadBeforeRendering = false;
private Integer procDefsCount = null;
private List selectedProcDefs = new ArrayList ();
private boolean startInDebugMode = false;
/**
* Create a new instance with all attributes initialized
* to defaults or the given values.
*
*/
public ProcDefMgmt() {
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)) {
selectedProcDefs.clear();
} else if (evt.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
if (reloadBeforeRendering
|| applicationContext.isReloadDefinitionsBeforeRendering()) {
// Get updated process list before rendering
// (may have been modified by action)
defListCache = null;
defsModelCache = null;
procDefsCount = null;
reloadBeforeRendering = false;
applicationContext.setReloadDefinitionsBeforeRendering(false);
}
}
}
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#afterPhase
*/
public void afterPhase(PhaseEvent evt) {
if (evt.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
selectedProcDefs.clear();
} else if (evt.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
defListCache = null;
defsModelCache = null;
}
}
/**
* @return Returns the applicationContext.
*/
public ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* @param applicationContext The applicationContext to set.
*/
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* @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 getSorter() {
return sorter;
}
/**
* @param sorter The sorter to set.
*/
public void setSorter(BeanSorter sorter) {
this.sorter = sorter;
}
/**
* @return Returns the startInDebugMode.
*/
public boolean isStartInDebugMode() {
return startInDebugMode;
}
/**
* @param startInDebugMode The startInDebugMode to set.
*/
public void setStartInDebugMode(boolean startInDebugMode) {
this.startInDebugMode = startInDebugMode;
}
/**
* @return the list of processes
*/
public DataModel getProcessDefinitions () {
if (defsModelCache == null) {
if (defListCache == null) {
logger.debug ("Retrieving process definition list");
ProcessDefinitionDirectory pdd = null;
defListCache = new ArrayList ();
try {
pdd = wsc.getWorkflowService().processDefinitionDirectory();
Collection defs = pdd.processDefinitions();
for (Iterator i = defs.iterator(); i.hasNext ();) {
defListCache.add (new ProcDefWrapper
(wsc.getWorkflowService(),
pdd, (ProcessDefinition)i.next()));
}
procDefsCount = new Integer (defListCache.size());
} catch (RemoteException e) {
JSFUtil.addMessage(FacesMessage.SEVERITY_ERROR, L10N_MSGS,
"resourceCurrentlyUnavailable", null, e);
} finally {
wsc.getWorkflowService().release(pdd);
}
} else {
logger.debug
("Using previsously created process definition list");
}
defsModelCache = new ListDataModel (defListCache);
if (sorter != null) {
sorter.sort (defListCache);
}
} else {
if (sorter != null && sorter.isModified ()) {
logger.debug ("Re-sorting");
sorter.sort (defListCache);
}
}
return defsModelCache;
}
/**
* @return number of process definitions
*/
public int getProcessDefinitionCount () {
if (procDefsCount == null) {
getProcessDefinitions();
}
return procDefsCount.intValue();
}
/**
* Create and start a process.
* @param packageId the packageId
* @param processId the processId
* @throws RemoteException if a system level error occurs
*/
public void createAndStartProcess (String packageId, String processId)
throws RemoteException, InvalidKeyException {
ProcessDefinitionDirectory pdd = null;
try {
pdd = wsc.getWorkflowService().processDefinitionDirectory();
ProcessMgr pmgr = pdd.processMgr(packageId, processId);
Process p = (Process)pmgr.createProcess
(new DefaultRequester(wsc.getWorkflowService()));
if (isStartInDebugMode()) {
p.setDebugEnabled (true);
}
p.start ();
setStartInDebugMode(false);
} catch (InvalidStateException e) {
// shouldn't happen
logger.error (e.getMessage (), e);
} catch (RequesterRequiredException e) {
// shouldn't happen
logger.error (e.getMessage (), e);
} catch (InvalidRequesterException e) {
// shouldn't happen
logger.error (e.getMessage (), e);
} catch (NotEnabledException e) {
// shouldn't happen
logger.error (e.getMessage (), e);
} catch (CannotStartException e) {
// shouldn't happen
logger.error (e.getMessage (), e);
} catch (AlreadyRunningException e) {
// shouldn't happen
logger.error (e.getMessage (), e);
} finally {
wsc.getWorkflowService().release(pdd);
}
}
/**
* Set the enabled state of a process definition.
* @param packageId the package id
* @param processId the process id
* @param state the new enabled state
* @throws RemoteException if a system level error occurs
*/
public void setEnabled (String packageId, String processId, boolean state)
throws RemoteException, InvalidKeyException {
ProcessDefinitionDirectory pdd = null;
try {
pdd = wsc.getWorkflowService().processDefinitionDirectory();
pdd.setEnabled(packageId, processId, state);
} finally {
wsc.getWorkflowService().release(pdd);
}
}
/**
* Delete a process definition.
* @param packageId the package id
* @param processId the process id
* @throws RemoteException if a system level error occurs
*/
public void remove (String packageId, String processId)
throws RemoteException, InvalidKeyException {
ProcessDefinitionDirectory pdd = null;
try {
pdd = wsc.getWorkflowService().processDefinitionDirectory();
pdd.removeProcessDefinition(packageId, processId);
} finally {
wsc.getWorkflowService().release(pdd);
}
reloadBeforeRendering = true;
}
/**
* @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("procDefAllSelection", Boolean.TRUE);
}
/**
* @param selected process definition
*/
public void addSelected (ProcDefWrapper pdw) {
selectedProcDefs.add (pdw);
}
/**
* Remove selected processes.
*/
public String removeSelected () throws RemoteException {
for (Iterator i = selectedProcDefs.iterator(); i.hasNext();) {
ProcDefWrapper procDef = (ProcDefWrapper)i.next();
procDef.remove();
}
reloadBeforeRendering = true;
return null;
}
}