KickJava   Java API By Example, From Geeks To Geeks.

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


1 package org.enhydra.shark.swingclient.worklist;
2
3
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.util.*;
7
8 import javax.swing.*;
9 import javax.swing.table.*;
10
11
12 import org.enhydra.shark.api.client.timebase.*;
13
14
15 import org.enhydra.shark.api.client.wfmodel.*;
16 import org.enhydra.shark.swingclient.*;
17 import org.enhydra.shark.swingclient.worklist.actions.*;
18
19 /**
20  * Implements the worklist. It presents the table which rows represents
21  * the workitems. The user can accept workitem, update it's variables,
22  * view it's description and complete it.
23  *
24  * @author Sasa Bojanic
25  * @version 1.0
26  */

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

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

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

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

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

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

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

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

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

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

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

175    public boolean isWorkitemContextUpdated (String JavaDoc workitemKey) {
176       return procVariables.containsKey(workitemKey);
177    }
178
179    /**
180     * Returns the (updated) context of workitem with a given key.
181     */

182    public Map getWorkitemContext (String JavaDoc workitemKey) {
183       return (Map)procVariables.get(workitemKey);
184    }
185
186    /**
187     * Adds mapping of workitem key to it's context.
188     */

189    public void putWorkitemContext (String JavaDoc workitemKey,Map context) {
190       procVariables.put(workitemKey,context);
191    }
192
193    /**
194     * Clears the worklist (sets it's resource object to null, and clears
195     * all workitems within it.
196     */

197    public void clear () {
198       myResource=null;
199       workitems.clear();
200       procVariables.clear();
201       worklistTableModel.clearTable();
202    }
203
204    /**
205     * Releases all assignments of the user, which means making the workitem
206     * accepted status false.
207     */

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

227    public synchronized void refresh () {
228 long t1, t2, t3, t4, t5, t6;
229 t1=System.currentTimeMillis();
230       // retrieve the assignments from the engine
231
WfAssignment[] ass=null;
232       try {
233          ass=myResource.get_sequence_work_item(0);
234       } catch (Exception JavaDoc ex) {
235          return;
236       }
237 t2=System.currentTimeMillis();
238 //System.out.println("OP1F");
239
// Updates the arrays with workitems to add, remove and retain
240
ArrayList toAdd=new ArrayList();
241       ArrayList toRemove=new ArrayList();
242       ArrayList toRetain=new ArrayList();
243       createWorkitemLists(ass,toAdd,toRemove,toRetain);
244 t3=System.currentTimeMillis();
245 //System.out.println("OP2F");
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             ex.printStackTrace();
256          }
257       }
258 t4=System.currentTimeMillis();
259 //System.out.println("OP3F");
260

261       // add new workitems that can be completed by the user
262
it=toAdd.iterator();
263       while (it.hasNext()) {
264          WfActivity wa=(WfActivity)it.next();
265          try {
266             if (wa.state().startsWith("open")) {
267                Vector vRow=new Vector();
268                vRow.add(wa.key());
269                if (wa.state().equals("open.running")) {
270                   vRow.add(new Boolean JavaDoc(true));
271                } else {
272                   vRow.add(new Boolean JavaDoc(false));
273                }
274                WfProcess proc=wa.container();
275                String JavaDoc name=proc.name();
276                String JavaDoc pDefName=SharkClient.getAdminMiscUtilities().getProcessMgrProcDefName(proc.manager().name());
277                if (pDefName.equals("") || pDefName.equals(name)) {
278                   String JavaDoc procId=proc.key();
279                   int ind_=procId.indexOf("_");
280                   if (ind_>0) {
281                      name=name+"-"+procId.substring(0,ind_);
282                   }
283                }
284                vRow.add(name);
285                vRow.add(wa.name());
286                vRow.add(new Integer JavaDoc(wa.priority()));
287                String JavaDoc date="";
288                String JavaDoc duration="";
289                if (wa.state().startsWith("open.running")) {
290                   try {
291                      UtcT lastStateT=wa.last_state_time();
292                      date=WorkflowUtilities.getDateFromUTC(lastStateT);
293                      duration=WorkflowUtilities.getDuration(lastStateT);
294                   } catch (Exception JavaDoc ex) {
295                   }
296                }
297                vRow.add(date);
298                vRow.add(duration);
299                worklistTableModel.addRow(vRow);
300             }
301          } catch (Exception JavaDoc ex){
302             ex.printStackTrace();
303          }
304       }
305 t5=System.currentTimeMillis();
306 //System.out.println("OP4F");
307

308       // refresh retained workitem times (the acceptance,
309
// start date, and duration)
310
it=toRetain.iterator();
311       while (it.hasNext()) {
312          WfActivity wa=(WfActivity)it.next();
313          try {
314             String JavaDoc id=wa.key();
315             boolean accepted=((WfAssignment)workitems.get(id)).get_accepted_status();
316             String JavaDoc date="";
317             String JavaDoc duration="";
318             if (accepted) {
319                try {
320                   UtcT lastStateT=wa.last_state_time();
321                   date=WorkflowUtilities.getDateFromUTC(lastStateT);
322                   duration=WorkflowUtilities.getDuration(lastStateT);
323                } catch (Exception JavaDoc ex) {
324                }
325             }
326             worklistTableModel.updateWorkitemProperties(wa.key(),accepted,
327                                                         date,duration);
328          } catch (Exception JavaDoc ex){
329             ex.printStackTrace();
330          }
331       }
332 t6=System.currentTimeMillis();
333 //System.out.println("RWL: t1="+(t2-t1)+", t2="+(t3-t2)+", t3="+(t4-t3)+", t4="+(t5-t4)+", t5="+(t6-t5));
334

335    }
336
337    /**
338     * Fills the lists of workitems to add, remove and retain. Also, it
339     * updates the map of all workitems.
340     */

341    private void createWorkitemLists (WfAssignment[] ass,
342                                      ArrayList toAdd,ArrayList toRemove,ArrayList toRetain) {
343
344       // create new mapping of: workitem id->workitem
345
Map newWorkitems=new HashMap();
346       if (ass!=null) {
347          for (int i=0; i<ass.length; i++) {
348             WfActivity wa;
349             try {
350                wa=ass[i].activity();
351                newWorkitems.put(wa.key(),ass[i]);
352             } catch (Exception JavaDoc ex) {}
353          }
354       }
355
356       // create the lists of id's of workitems to add, remove and retain
357
ArrayList toAddIds=new ArrayList(newWorkitems.keySet());
358       toAddIds.removeAll(workitems.keySet());
359       ArrayList toRemoveIds=new ArrayList(workitems.keySet());
360       toRemoveIds.removeAll(newWorkitems.keySet());
361       ArrayList toRetainIds=new ArrayList(workitems.keySet());
362       toRetainIds.retainAll(newWorkitems.keySet());
363 /*
364 System.out.println("TAdd="+toAddIds);
365 System.out.println("TRem="+toRemoveIds);
366 System.out.println("TRet="+toRetainIds);
367 */

368       // creating the list of workitems to add using the list of id's
369
Iterator addIt=toAddIds.iterator();
370       while (addIt.hasNext()) {
371          try {
372             toAdd.add(((WfAssignment)newWorkitems.get(addIt.next())).activity());
373          } catch (Exception JavaDoc ex) {}
374       }
375       // creating the list of workitems to remove using the list of id's
376
Iterator removeIt=toRemoveIds.iterator();
377       while (removeIt.hasNext()) {
378          try {
379             Object JavaDoc nextId=removeIt.next();
380             //toRemove.add(((WfAssignment)workitems.get(nextId)).activity());
381
toRemove.add(nextId);
382             procVariables.remove(nextId);
383          } catch (Exception JavaDoc ex) {}
384       }
385       // creating the list of workitems to retain using the list of id's
386
Iterator retIt=toRetainIds.iterator();
387       while (retIt.hasNext()) {
388          try {
389             toRetain.add(((WfAssignment)newWorkitems.get(retIt.next())).activity());
390          } catch (Exception JavaDoc ex) {}
391       }
392
393       // update old mapping with the new one
394
workitems.clear();
395       workitems=newWorkitems;
396    }
397
398    /**
399     * The model for the worklist table.
400     */

401    class WorklistTableModel extends DefaultTableModel {
402       /**
403        * Sets the appropriate column names of worklist table. The first
404        * column that shows the workitem key is hidden.
405        */

406       WorklistTableModel () {
407          super(new String JavaDoc[] {
408                   ResourceManager.getLanguageDependentString("IdKey"),
409                      ResourceManager.getLanguageDependentString("AcceptedKey"),
410                      //ResourceManager.getLanguageDependentString("ProcessIdKey"),
411
ResourceManager.getLanguageDependentString("ProcessNameKey"),
412                      ResourceManager.getLanguageDependentString("WorkitemKey"),
413                      ResourceManager.getLanguageDependentString("PriorityKey"),
414                      ResourceManager.getLanguageDependentString("StartedKey"),
415                      ResourceManager.getLanguageDependentString("DurationKey")
416                },0);
417       }
418
419       /**
420        * Removes the row which first column contains the given workitem key.
421        */

422       public void removeRow (Object JavaDoc workitemKey) {
423          int rowCnt=getRowCount();
424          for (int row=0; row<rowCnt;row++) {
425             if (getValueAt(row,0).equals(workitemKey)) {
426                removeRow(row);
427                break;
428             }
429          }
430       }
431
432       /**
433        * Clears all workitems from the table.
434        */

435       public void clearTable () {
436          int rowCnt=getRowCount();
437          // must go from the top index
438
for (int row=rowCnt-1; row>=0; row--) {
439             removeRow(row);
440          }
441       }
442
443       /**
444        * Updates workitem properties.
445        *
446        * @param workitemKey The key of workitem to update.
447        * @param accept The new accepted status of workitem.
448        * @param newDate The new value of the starting date and
449        * time of workitem
450        * @param newDuration The new value of the duration of workitem.
451        */

452       public void updateWorkitemProperties (String JavaDoc workitemKey,boolean accept,
453                                             String JavaDoc newDate,String JavaDoc newDuration) {
454          int rowCnt=getRowCount();
455          for (int row=0; row<rowCnt;row++) {
456             if (getValueAt(row,0).equals(workitemKey)) {
457                super.setValueAt(new Boolean JavaDoc(accept),row,1);
458                super.setValueAt(newDate,row,5);
459                super.setValueAt(newDuration,row,6);
460                break;
461             }
462          }
463       }
464
465       /*
466        * JTable uses this method to determine the default renderer/
467        * editor for each cell. If we didn't implement this method,
468        * then the 'accepted' column would contain text ("true"/"false"),
469        * rather than a check box.
470        */

471       public Class JavaDoc getColumnClass(int c) {
472          return getValueAt(0, c).getClass();
473       }
474
475       /**
476        * Only the cell for acceptance is editable.
477        */

478       public boolean isCellEditable(int row, int col) {
479          if (col==1) {
480             return true;
481          } else {
482             return false;
483          }
484       }
485
486       /**
487        * Overrides super method to signal to the workitem that it is
488        * mark as accepted or not accepted.
489        */

490       public void setValueAt(Object JavaDoc value, int row, int col) {
491          super.setValueAt(value,row,col);
492          if (col==1) {
493             boolean accepted=((Boolean JavaDoc)value).booleanValue();
494             try {
495                WfAssignment ass=(WfAssignment)workitems.get(getValueAt(row,0));
496                ass.set_accepted_status(accepted);
497                if (accepted) {
498                   UtcT lastStateT=ass.activity().last_state_time();
499                   String JavaDoc newDate=WorkflowUtilities.getDateFromUTC(lastStateT);
500                   String JavaDoc newDuration=WorkflowUtilities.getDuration(lastStateT);
501                   super.setValueAt(newDate,row,5);
502                   super.setValueAt(newDuration,row,6);
503                } else {
504                   super.setValueAt("",row,5);
505                   super.setValueAt("",row,6);
506                }
507             } catch (CannotAcceptSuspended cas) {
508                JOptionPane.showMessageDialog(workflowClient.getFrame(),
509                                              ResourceManager.getLanguageDependentString(
510                                                 "WarningCannotAcceptSuspendedWorkitem"),
511                                              workflowClient.getAppTitle(),JOptionPane.WARNING_MESSAGE);
512                refresh();
513             } catch (Exception JavaDoc ex) {
514                JOptionPane.showMessageDialog(workflowClient.getFrame(),
515                                              ResourceManager.getLanguageDependentString(
516                                                 "WarningTheWorkitemIsPerformedByAnotherUser"),
517                                              workflowClient.getAppTitle(),JOptionPane.WARNING_MESSAGE);
518                refresh();
519             }
520          }
521       }
522
523    }
524
525 }
526
Popular Tags