KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > shark > corbaclient > worklist > Worklist


1 package org.enhydra.shark.corbaclient.worklist;
2
3
4 import java.awt.Component JavaDoc;
5 import java.awt.Dimension JavaDoc;
6 import java.awt.event.*;
7 import java.util.*;
8
9 import javax.swing.*;
10 import javax.swing.table.DefaultTableModel JavaDoc;
11 import javax.swing.table.TableColumn JavaDoc;
12
13 import org.enhydra.shark.corbaclient.*;
14 import org.enhydra.shark.corbaclient.worklist.actions.*;
15 import org.enhydra.shark.corbaclient.SharkClient;
16 import org.omg.TimeBase.UtcT;
17 import org.omg.WfBase.NameValue;
18 import org.omg.WorkflowModel.*;
19
20 /**
21  * Implements the worklist. It presents the table which rows represents
22  * the workitems. The user can accept workitem, update it's variables,
23  * view it's description and complete it.
24  *
25  * @author Sasa Bojanic
26  * @version 1.0
27  */

28 public class Worklist extends ActionPanel {
29
30    /** Maps workitem ID to the assignment. */
31    private Map workitems=new HashMap();
32    /** Maps the workitem to the set of it's context variables. */
33    private Map procVariables=new HashMap();
34
35    /** The table that shows all workitems for the given user. */
36    private JTable worklistTable;
37    /**
38     * The model of worklist table - enables accepting workitems, as well
39     * as removing and adding workitems to the table.
40     */

41    private WorklistTableModel worklistTableModel;
42
43    /**
44     * The client application that uses this worklist (used only to provide
45     * the reference to the application frame, and to get the application
46     * title, which is used when calling some dialogs or writting a messages
47     * within the JOptionPane.
48     */

49    SharkClient workflowClient;
50
51    /**
52     * The reference to the resource object of the user which is responsible
53     * for accomplishment of the workitems given in the worklist.
54     */

55    WfResource myResource;
56
57    /**
58     * Constructs the worklist panel with control buttons disabled or enabled.
59     */

60    public Worklist (SharkClient wc,boolean disableButtons) {
61       super();
62       this.workflowClient=wc;
63       super.init();
64
65       setButtonPanelEnabled(!disableButtons);
66    }
67
68    protected void createActions () {
69       defaultActions=new Action[] {
70          new CompleteWorkitem(this),
71             new UpdateActivityVariables(this),
72             new WorkitemDescription(this)
73       };
74    }
75    /**
76     * Creates the worklist table, which uses specifc WorklistTableModel,
77     * within the scrollpane.
78     */

79    protected Component JavaDoc createCenterComponent () {
80       JScrollPane tablePane=new JScrollPane();
81       worklistTableModel=new WorklistTableModel();
82       worklistTable=new JTable(worklistTableModel);
83       // setting some table properties
84
worklistTable.setColumnSelectionAllowed(false);
85       worklistTable.setRowSelectionAllowed(true);
86       worklistTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
87       worklistTable.getTableHeader().setReorderingAllowed(false);
88       worklistTable.setPreferredScrollableViewportSize(new Dimension JavaDoc(500,300));
89       // setting the first column (ID column) to be invisible
90
TableColumn JavaDoc column=worklistTable.getColumnModel().getColumn(0);
91       column.setMinWidth(0);
92       column.setMaxWidth(0);
93       column.setPreferredWidth(0);
94       column.setResizable(false);
95
96       // mouse listener for invoking CompleteWorkitem on double-click
97
worklistTable.addMouseListener(new MouseAdapter() {
98                public void mouseClicked (MouseEvent me) {
99                   /*try {
100                      if (!workflowClient.getUsername().equals(myResource.resource_key())) return;
101                    } catch (Exception ex) {}*/

102                   if (me.getClickCount()>1) {
103                      getAction(Utils.getUnqualifiedClassName(CompleteWorkitem.class)).
104                         actionPerformed(null);
105                   }
106                }
107             });
108
109       // key for invoking CompleteWorkitem on Enter
110
worklistTable.getInputMap(JComponent.WHEN_FOCUSED).
111          put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,false),"edit");
112       worklistTable.getActionMap().put("edit",new AbstractAction() {
113                public void actionPerformed(ActionEvent e) {
114                   getAction(Utils.getUnqualifiedClassName(CompleteWorkitem.class)).
115                      actionPerformed(null);
116                }
117             });
118
119       tablePane.setViewportView(worklistTable);
120       return tablePane;
121    }
122
123    /**
124     * Sets the new resource object, which implicates that the worklist
125     * will be refreshed to hold the workitems of the user that corresponds
126     * to the given resource.
127     */

128    public void setResource (WfResource newResource) {
129       try {
130          if (!newResource.resource_key().equals(myResource.resource_key())) {
131             clear();
132          }
133       } catch (Exception JavaDoc ex) {
134          // ex.printStackTrace();
135
}
136
137
138       myResource=newResource;
139       refresh();
140    }
141
142    /**
143     * Sets the control buttons of worklist to be enabled or disabled.
144     * The method doesn't affect the button that is used to show
145     * the description of the selected workitem - it is always enabled.
146     */

147    public void setButtonPanelEnabled (boolean enabled) {
148       // disable/enable all except Description
149
for (int i=0; i<buttonPanel.getComponentCount()-1; i++) {
150          buttonPanel.getComponent(i).setEnabled(enabled);
151       }
152    }
153
154    /**
155     * Returns the resource object of user that worklist belong to.
156     */

157    public WfResource getResource () {
158       return myResource;
159    }
160
161    /**
162     * Gets the currently selected assignment from the worklist table.
163     * <p> Assignment is consisted of the workitem (WfActivity instance),
164     * and it's performer (WfResource instance).
165     */

166    public WfAssignment getSelectedAssignment () {
167       int selRow=worklistTable.getSelectedRow();
168       if (selRow>=0) {
169          String JavaDoc id=(String JavaDoc)worklistTableModel.getValueAt(selRow,0);
170          return (WfAssignment)workitems.get(id);
171       }
172       return null;
173    }
174
175    /**
176     * Returns true if the context variables of workitem determined with
177     * the given key are updated (which means if the dialog for it's update
178     * is entered).
179     */

180    public boolean isWorkitemContextUpdated (String JavaDoc workitemKey) {
181       return procVariables.containsKey(workitemKey);
182    }
183
184    /**
185     * Returns the (updated) context of workitem with a given key.
186     */

187    public NameValue[] getWorkitemContext (String JavaDoc workitemKey) {
188       return (NameValue[])procVariables.get(workitemKey);
189    }
190
191    /**
192     * Adds mapping of workitem key to it's context.
193     */

194    public void putWorkitemContext (String JavaDoc workitemKey,NameValue[] context) {
195       procVariables.put(workitemKey,context);
196    }
197
198    /**
199     * Clears the worklist (sets it's resource object to null, and clears
200     * all workitems within it.
201     */

202    public void clear () {
203       myResource=null;
204       workitems.clear();
205       procVariables.clear();
206       worklistTableModel.clearTable();
207    }
208
209    /**
210     * Releases all assignments of the user, which means making the workitem
211     * accepted status false.
212     */

213    public void releaseAllAssignments () {
214       Iterator it=workitems.values().iterator();
215       while (it.hasNext()) {
216          WfAssignment ass=(WfAssignment)it.next();
217          try {
218             ass.set_accepted_status(false);
219          } catch (Exception JavaDoc ex) {}
220       }
221       workitems.clear();
222    }
223
224    /**
225     * Refreshes the list of workitems. It uses the resource (CORBA) object to
226     * get all the assignments for the user that is responsible for the worklist,
227     * and to refresh it's view within the worklist table.
228     * <p> This method is supposed to be called periodically by the client
229     * application, or to be called when ever the user manually request the
230     * refreshment of the worklist.
231     */

232    public synchronized void refresh () {
233       // retrieve the assignments from the engine
234
WfAssignment[] ass=null;
235       try {
236          ass=myResource.get_sequence_work_item(0);
237       } catch (Exception JavaDoc ex) {
238          return;
239       }
240
241       // Updates the arrays with workitems to add, remove and retain
242
ArrayList toAdd=new ArrayList();
243       ArrayList toRemove=new ArrayList();
244       ArrayList toRetain=new ArrayList();
245       createWorkitemLists(ass,toAdd,toRemove,toRetain);
246
247       // remove finished workitems, and workitems accepted by other user
248
Iterator it=toRemove.iterator();
249       while (it.hasNext()) {
250          //WfActivity wa=(WfActivity)it.next();
251
try {
252             //worklistTableModel.removeRow(wa.key());
253
worklistTableModel.removeRow(it.next());
254          } catch (Exception JavaDoc ex){}
255       }
256
257       // add new workitems that can be completed by the user
258
it=toAdd.iterator();
259       while (it.hasNext()) {
260          WfActivity wa=(WfActivity)it.next();
261          try {
262             if (wa.state().startsWith("open")) {
263                Vector vRow=new Vector();
264                vRow.add(wa.key());
265                if (wa.state().equals("open.running")) {
266                   vRow.add(new Boolean JavaDoc(true));
267                } else {
268                   vRow.add(new Boolean JavaDoc(false));
269                }
270                WfProcess proc=wa.container();
271                String JavaDoc name=proc.name();
272                String JavaDoc pDefName=SharkClient.getAdminMiscUtilities().getProcessMgrProcDefName(proc.manager().name());
273                if (pDefName.equals("") || pDefName.equals(name)) {
274                   String JavaDoc procId=proc.key();
275                   int ind_=procId.indexOf("_");
276                   if (ind_>0) {
277                      name=name+"-"+procId.substring(0,ind_);
278                   }
279                }
280                vRow.add(name);
281                vRow.add(wa.name());
282                vRow.add(new Integer JavaDoc(wa.priority()));
283                String JavaDoc date="";
284                String JavaDoc duration="";
285                if (wa.state().startsWith("open.running")) {
286                   try {
287                      UtcT lastStateT=wa.last_state_time();
288                      date=WorkflowUtilities.getDateFromUTC(lastStateT);
289                      duration=WorkflowUtilities.getDuration(lastStateT);
290                   } catch (Exception JavaDoc ex) {
291                   }
292                }
293                vRow.add(date);
294                vRow.add(duration);
295                worklistTableModel.addRow(vRow);
296             }
297          } catch (Exception JavaDoc ex){}
298       }
299
300       // refresh retained workitem times (the acceptance,
301
// start date, and duration)
302
it=toRetain.iterator();
303       while (it.hasNext()) {
304          WfActivity wa=(WfActivity)it.next();
305          try {
306             String JavaDoc id=wa.key();
307             boolean accepted=((WfAssignment)workitems.get(id)).get_accepted_status();
308             String JavaDoc date="";
309             String JavaDoc duration="";
310             if (accepted) {
311                try {
312                   UtcT lastStateT=wa.last_state_time();
313                   date=WorkflowUtilities.getDateFromUTC(lastStateT);
314                   duration=WorkflowUtilities.getDuration(lastStateT);
315                } catch (Exception JavaDoc ex) {
316                }
317             }
318             worklistTableModel.updateWorkitemProperties(wa.key(),accepted,
319                                                         date,duration);
320          } catch (Exception JavaDoc ex){}
321       }
322    }
323
324    /**
325     * Fills the lists of workitems to add, remove and retain. Also, it
326     * updates the map of all workitems.
327     */

328    private void createWorkitemLists (WfAssignment[] ass,
329                                      ArrayList toAdd,ArrayList toRemove,ArrayList toRetain) {
330
331       // create new mapping of: workitem id->workitem
332
Map newWorkitems=new HashMap();
333       if (ass!=null) {
334          for (int i=0; i<ass.length; i++) {
335             WfActivity wa;
336             try {
337                wa=ass[i].activity();
338                newWorkitems.put(wa.key(),ass[i]);
339             } catch (Exception JavaDoc ex) {}
340          }
341       }
342
343       // create the lists of id's of workitems to add, remove and retain
344
ArrayList toAddIds=new ArrayList(newWorkitems.keySet());
345       toAddIds.removeAll(workitems.keySet());
346       ArrayList toRemoveIds=new ArrayList(workitems.keySet());
347       toRemoveIds.removeAll(newWorkitems.keySet());
348       ArrayList toRetainIds=new ArrayList(workitems.keySet());
349       toRetainIds.retainAll(newWorkitems.keySet());
350
351       //System.out.println("TAdd="+toAddIds);
352
//System.out.println("TRem="+toRemoveIds);
353
//System.out.println("TRet="+toRetainIds);
354
// creating the list of workitems to add using the list of id's
355
Iterator addIt=toAddIds.iterator();
356       while (addIt.hasNext()) {
357          try {
358             toAdd.add(((WfAssignment)newWorkitems.get(addIt.next())).activity());
359          } catch (Exception JavaDoc ex) {}
360       }
361       // creating the list of workitems to remove using the list of id's
362
Iterator removeIt=toRemoveIds.iterator();
363       while (removeIt.hasNext()) {
364          try {
365             Object JavaDoc nextId=removeIt.next();
366             //toRemove.add(((WfAssignment)workitems.get(nextId)).activity());
367
toRemove.add(nextId);
368             procVariables.remove(nextId);
369          } catch (Exception JavaDoc ex) {}
370       }
371       // creating the list of workitems to retain using the list of id's
372
Iterator retIt=toRetainIds.iterator();
373       while (retIt.hasNext()) {
374          try {
375             toRetain.add(((WfAssignment)newWorkitems.get(retIt.next())).activity());
376          } catch (Exception JavaDoc ex) {}
377       }
378
379       // update old mapping with the new one
380
workitems.clear();
381       workitems=newWorkitems;
382    }
383
384    /**
385     * The model for the worklist table.
386     */

387    class WorklistTableModel extends DefaultTableModel JavaDoc {
388       /**
389        * Sets the appropriate column names of worklist table. The first
390        * column that shows the workitem key is hidden.
391        */

392       WorklistTableModel () {
393          super(new String JavaDoc[] {
394                   ResourceManager.getLanguageDependentString("IdKey"),
395                      ResourceManager.getLanguageDependentString("AcceptedKey"),
396                      //ResourceManager.getLanguageDependentString("ProcessIdKey"),
397
ResourceManager.getLanguageDependentString("ProcessNameKey"),
398                      ResourceManager.getLanguageDependentString("WorkitemKey"),
399                      ResourceManager.getLanguageDependentString("PriorityKey"),
400                      ResourceManager.getLanguageDependentString("StartedKey"),
401                      ResourceManager.getLanguageDependentString("DurationKey")
402                },0);
403       }
404
405       /**
406        * Removes the row which first column contains the given workitem key.
407        */

408       public void removeRow (Object JavaDoc workitemKey) {
409          int rowCnt=getRowCount();
410          for (int row=0; row<rowCnt;row++) {
411             if (getValueAt(row,0).equals(workitemKey)) {
412                removeRow(row);
413                break;
414             }
415          }
416       }
417
418       /**
419        * Clears all workitems from the table.
420        */

421       public void clearTable () {
422          int rowCnt=getRowCount();
423          // must go from the top index
424
for (int row=rowCnt-1; row>=0; row--) {
425             removeRow(row);
426          }
427       }
428
429       /**
430        * Updates workitem properties.
431        *
432        * @param workitemKey The key of workitem to update.
433        * @param accept The new accepted status of workitem.
434        * @param newDate The new value of the starting date and
435        * time of workitem
436        * @param newDuration The new value of the duration of workitem.
437        */

438       public void updateWorkitemProperties (String JavaDoc workitemKey,boolean accept,
439                                             String JavaDoc newDate,String JavaDoc newDuration) {
440          int rowCnt=getRowCount();
441          for (int row=0; row<rowCnt;row++) {
442             if (getValueAt(row,0).equals(workitemKey)) {
443                super.setValueAt(new Boolean JavaDoc(accept),row,1);
444                super.setValueAt(newDate,row,5);
445                super.setValueAt(newDuration,row,6);
446                break;
447             }
448          }
449       }
450
451       /*
452        * JTable uses this method to determine the default renderer/
453        * editor for each cell. If we didn't implement this method,
454        * then the 'accepted' column would contain text ("true"/"false"),
455        * rather than a check box.
456        */

457       public Class JavaDoc getColumnClass(int c) {
458          return getValueAt(0, c).getClass();
459       }
460
461       /**
462        * Only the cell for acceptance is editable.
463        */

464       public boolean isCellEditable(int row, int col) {
465          if (col==1) {
466             return true;
467          }
468          return false;
469       }
470
471       /**
472        * Overrides super method to signal to the workitem that it is
473        * mark as accepted or not accepted.
474        */

475       public void setValueAt(Object JavaDoc value, int row, int col) {
476          super.setValueAt(value,row,col);
477          if (col==1) {
478             boolean accepted=((Boolean JavaDoc)value).booleanValue();
479             try {
480                WfAssignment ass=(WfAssignment)workitems.get(getValueAt(row,0));
481                ass.set_accepted_status(accepted);
482                if (accepted) {
483                   UtcT lastStateT=ass.activity().last_state_time();
484                   String JavaDoc newDate=WorkflowUtilities.getDateFromUTC(lastStateT);
485                   String JavaDoc newDuration=WorkflowUtilities.getDuration(lastStateT);
486                   super.setValueAt(newDate,row,5);
487                   super.setValueAt(newDuration,row,6);
488                } else {
489                   super.setValueAt("",row,5);
490                   super.setValueAt("",row,6);
491                }
492             } catch (CannotAcceptSuspended cas) {
493                JOptionPane.showMessageDialog(workflowClient.getFrame(),
494                                              ResourceManager.getLanguageDependentString(
495                                                 "WarningCannotAcceptSuspendedWorkitem"),
496                                              workflowClient.getAppTitle(),JOptionPane.WARNING_MESSAGE);
497                refresh();
498             } catch (Exception JavaDoc ex) {
499                JOptionPane.showMessageDialog(workflowClient.getFrame(),
500                                              ResourceManager.getLanguageDependentString(
501                                                 "WarningTheWorkitemIsPerformedByAnotherUser"),
502                                              workflowClient.getAppTitle(),JOptionPane.WARNING_MESSAGE);
503                refresh();
504             }
505          }
506       }
507
508    }
509
510 }
511
Popular Tags