VHNotificationsTabControl.java
001 /*
002  *
003  * Licensed to the Apache Software Foundation (ASF) under one
004  * or more contributor license agreements.  See the NOTICE file
005  * distributed with this work for additional information
006  * regarding copyright ownership.  The ASF licenses this file
007  * to you under the Apache License, Version 2.0 (the
008  * "License"); you may not use this file except in compliance
009  * with the License.  You may obtain a copy of the License at
010  *
011  *   http://www.apache.org/licenses/LICENSE-2.0
012  *
013  * Unless required by applicable law or agreed to in writing,
014  * software distributed under the License is distributed on an
015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016  * KIND, either express or implied.  See the License for the
017  * specific language governing permissions and limitations
018  * under the License.
019  *
020  */
021 
022 package org.apache.qpid.management.ui.views;
023 
024 import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR;
025 import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH;
026 import static org.apache.qpid.management.ui.Constants.CONSOLE_IMAGE;
027 import static org.apache.qpid.management.ui.Constants.FONT_BUTTON;
028 
029 import java.util.ArrayList;
030 import java.util.List;
031 
032 import org.apache.qpid.management.ui.ApplicationRegistry;
033 import org.apache.qpid.management.ui.ServerRegistry;
034 import org.apache.qpid.management.ui.model.NotificationObject;
035 import org.eclipse.jface.viewers.DoubleClickEvent;
036 import org.eclipse.jface.viewers.IDoubleClickListener;
037 import org.eclipse.jface.viewers.ILabelProviderListener;
038 import org.eclipse.jface.viewers.ISelection;
039 import org.eclipse.jface.viewers.IStructuredContentProvider;
040 import org.eclipse.jface.viewers.IStructuredSelection;
041 import org.eclipse.jface.viewers.ITableLabelProvider;
042 import org.eclipse.jface.viewers.StructuredSelection;
043 import org.eclipse.jface.viewers.TableViewer;
044 import org.eclipse.jface.viewers.Viewer;
045 import org.eclipse.swt.SWT;
046 import org.eclipse.swt.events.SelectionAdapter;
047 import org.eclipse.swt.events.SelectionEvent;
048 import org.eclipse.swt.graphics.Image;
049 import org.eclipse.swt.layout.GridData;
050 import org.eclipse.swt.layout.GridLayout;
051 import org.eclipse.swt.widgets.Button;
052 import org.eclipse.swt.widgets.Composite;
053 import org.eclipse.swt.widgets.Control;
054 import org.eclipse.swt.widgets.Display;
055 import org.eclipse.swt.widgets.Label;
056 import org.eclipse.swt.widgets.Shell;
057 import org.eclipse.swt.widgets.TabFolder;
058 import org.eclipse.swt.widgets.Table;
059 import org.eclipse.swt.widgets.TableColumn;
060 import org.eclipse.swt.widgets.Text;
061 import org.eclipse.ui.forms.widgets.Form;
062 import org.eclipse.ui.forms.widgets.FormToolkit;
063 
064 public class VHNotificationsTabControl extends TabControl
065 {
066     protected FormToolkit  _toolkit;
067     protected Form _form;
068     protected Table _table = null;
069     protected TableViewer _tableViewer  = null;
070      
071     protected Thread worker = null;
072     
073     protected List<NotificationObject> _notifications = null;
074     
075     private static final String COLUMN_OBJ = "Object Name";
076     private static final String COLUMN_SEQ  = "Sequence No";
077     private static final String COLUMN_TIME = "TimeStamp";
078     private static final String COLUMN_TYPE  = "Type";
079     private static final String COLUMN_MSG  = "Notification Message";
080     protected static final String[] _tableTitles = new String [] {
081             COLUMN_OBJ,
082             COLUMN_SEQ,
083             COLUMN_TIME,
084             COLUMN_TYPE,
085             COLUMN_MSG
086          };
087     
088     protected Button _clearButton       = null;
089     protected Button _refreshButton       = null;
090     
091     public VHNotificationsTabControl(TabFolder tabFolder)
092     {
093         super(tabFolder);
094         _toolkit = new FormToolkit(_tabFolder.getDisplay());
095         _form = _toolkit.createForm(_tabFolder);
096         GridLayout gridLayout = new GridLayout();      
097         gridLayout.marginWidth = 0;
098         gridLayout.marginHeight = 0;       
099         _form.getBody().setLayout(gridLayout);
100         
101         worker = new Thread(new Worker())
102         worker.start();
103     }
104     
105     protected void createWidgets()
106     {       
107         addButtons();  
108         createTableViewer();
109     }
110     
111     /**
112      @see TabControl#getControl()
113      */
114     public Control getControl()
115     {
116         if (_table == null)
117         {
118             createWidgets();
119         }
120         return _form;
121     }
122 
123     /**
124      * Creates clear buttin and refresh button
125      */
126     protected void addButtons()
127     {    
128         Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
129         composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
130         composite.setLayout(new GridLayout(2true));
131         
132         // Add Clear Button
133         _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER);
134         _clearButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
135         GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false);
136         gridData.widthHint = 80;
137         _clearButton.setLayoutData(gridData);
138         _clearButton.addSelectionListener(new SelectionAdapter()
139             {
140                 public void widgetSelected(SelectionEvent e)
141                 {  
142                     //TODO : Get selected rows and clear those
143                     IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
144                     ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
145                     serverRegistry.clearNotifications(null, ss.toList());
146                     refresh();
147                 }
148             });
149         
150         // Add Refresh Button
151         _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER);
152         _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
153         gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false);
154         gridData.widthHint = 80;
155         _refreshButton.setLayoutData(gridData);
156         _refreshButton.addSelectionListener(new SelectionAdapter()
157             {
158                 public void widgetSelected(SelectionEvent e)
159                 
160                     refresh();
161                 }
162             });
163     }
164     
165     /**
166      * Creates table to display notifications
167      */
168     private void createTable()
169     {
170         _table = _toolkit.createTable(_form.getBody(), SWT.MULTI | SWT.FULL_SELECTION);
171         _table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
172         
173         TableColumn column = new TableColumn(_table, SWT.NONE);
174         column.setText(_tableTitles[0]);
175         column.setWidth(100);
176         
177         column = new TableColumn(_table, SWT.NONE);
178         column.setText(_tableTitles[1]);
179         column.setWidth(100)
180 
181         column = new TableColumn(_table, SWT.NONE);
182         column.setText(_tableTitles[2]);
183         column.setWidth(130);
184         
185         column = new TableColumn(_table, SWT.NONE);
186         column.setText(_tableTitles[3]);
187         column.setWidth(100);
188         
189         column = new TableColumn(_table, SWT.NONE);
190         column.setText(_tableTitles[4]);
191         column.setWidth(500);
192         
193         _table.setHeaderVisible(true);
194         _table.setLinesVisible(true);
195     }
196     
197     /**
198      * Creates JFace viewer for the notifications table
199      */
200     protected void createTableViewer()
201     {
202         createTable();
203         _tableViewer = new TableViewer(_table);
204         //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
205         _tableViewer.setUseHashlookup(true);
206         _tableViewer.setContentProvider(new ContentProviderImpl());
207         _tableViewer.setLabelProvider(new LabelProviderImpl());
208         _tableViewer.setColumnProperties(_tableTitles);
209         /*
210         CellEditor[] cellEditors = new CellEditor[_tableTitles.length];
211         TextCellEditor textEditor = new TextCellEditor(table);
212         cellEditors[0] = textEditor;
213         textEditor = new TextCellEditor(table);
214         cellEditors[1] = textEditor;
215         textEditor = new TextCellEditor(table);
216         cellEditors[2] = textEditor;
217         textEditor = new TextCellEditor(table);
218         cellEditors[3] = textEditor;
219         
220         // Assign the cell editors to the viewer 
221         _tableViewer.setCellEditors(cellEditors);
222         _tableViewer.setCellModifier(new TableCellModifier());
223         */
224         
225         addTableListeners();
226         
227         //_tableViewer.addSelectionChangedListener(new );
228         
229         //_notificationDetails = new Composite(_tabControl, SWT.BORDER);
230         //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH));
231         
232         //_tabControl.layout();
233         //viewerComposite.layout();
234     }
235     
236     /**
237      * Adds listeners to the viewer for displaying notification details 
238      */
239     protected void addTableListeners()
240     {
241         _tableViewer.addDoubleClickListener(new IDoubleClickListener()
242             {
243                 Display display = null;
244                 Shell   shell = null;
245                 public void doubleClick(DoubleClickEvent event)
246                 {
247                     display = Display.getCurrent();
248                     shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.RESIZE);
249                     shell.setText("Notification");
250                     shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE));
251 
252                     int x = display.getBounds().width;
253                     int y = display.getBounds().height;
254                     shell.setBounds(x/4, y/4, x/2, y/3);
255                     StructuredSelection selection = (StructuredSelection)event.getSelection();
256                     createPopupContents((NotificationObject)selection.getFirstElement());
257                     shell.open();
258                     while (!shell.isDisposed()) {
259                         if (!display.readAndDispatch()) {
260                             display.sleep();
261                         }
262                     }
263                     
264                     //If you create it, you dispose it.
265                     shell.dispose();
266                 }
267 
268                 private void createPopupContents(NotificationObject obj)
269                 {                    
270                     shell.setLayout(new GridLayout());
271                     
272                     Composite parent = _toolkit.createComposite(shell, SWT.NONE);
273                     parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
274                     GridLayout layout = new GridLayout(4true);
275                     parent.setLayout(layout);
276                     
277                     // Object name record
278                     Label key = _toolkit.createLabel(parent, COLUMN_OBJ, SWT.TRAIL)
279                     GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1);
280                     key.setLayoutData(layoutData);
281                     Text  value = _toolkit.createText(parent, obj.getSourceName(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY);
282                     value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
283 
284                     // Sequence no record
285                     key = _toolkit.createLabel(parent, COLUMN_SEQ, SWT.TRAIL);             
286                     layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1);
287                     key.setLayoutData(layoutData);
288                     value = _toolkit.createText(parent, ""+obj.getSequenceNo(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY);
289                     value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
290 
291                     // Time row
292                     key = _toolkit.createLabel(parent, COLUMN_TIME, SWT.TRAIL);
293                     key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
294                     value = _toolkit.createText(parent, obj.getTimeStamp(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
295                     value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
296 
297                     key = _toolkit.createLabel(parent, COLUMN_TYPE, SWT.TRAIL);
298                     key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
299                     value = _toolkit.createText(parent, obj.getType(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY);
300                     value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1));
301 
302                     key = _toolkit.createLabel(parent, COLUMN_MSG, SWT.TRAIL);
303                     key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1));
304                     value = _toolkit.createText(parent, obj.getMessage(), SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
305                     GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 31);
306                     gridData.heightHint = 100;
307                     value.setLayoutData(gridData);
308                 }
309             });
310     }
311     
312     public void refresh()
313     {        
314         _notifications = null;
315         _table.deselectAll();
316         _tableViewer.getTable().clearAll();  
317         
318         Control[] children = _form.getBody().getChildren();        
319         for (int i = 0; i < children.length; i++)
320         {
321             children[i].setVisible(true);
322         }
323              
324         workerRunning = true;
325         _form.layout(true);   
326         _form.getBody().layout(true, true);
327     }
328     
329     /**
330      * Content provider class for the table viewer
331      */
332     protected class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer
333     {
334         public void inputChanged(Viewer v, Object oldInput, Object newInput)
335         {
336             
337         }
338         public void dispose()
339         {
340             
341         }
342         public Object[] getElements(Object parent
343         {
344             return _notifications.toArray(new NotificationObject[0]);
345         }
346         public void addNotification(NotificationObject notification)
347         {
348             _tableViewer.add(notification);
349         }
350         
351         public void addNotification(List<NotificationObject> notificationList)
352         {
353             _tableViewer.add(notificationList.toArray(new NotificationObject[0]));
354         }
355     }
356     
357     /**
358      * Label provider for the table viewer
359      */
360     protected class LabelProviderImpl implements ITableLabelProvider
361     {
362         List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();       
363         public void addListener(ILabelProviderListener listener)
364         {
365             listeners.add(listener);
366         }
367         
368         public void dispose(){
369             
370         }
371         
372         public Image getColumnImage(Object element, int columnIndex)
373         {
374             return null;
375         }
376         
377         public String getColumnText(Object element, int columnIndex)
378         {
379             String result = null;
380             NotificationObject t = (NotificationObject)element;
381             switch(columnIndex)
382             {
383             case 
384                 result = t.getSourceName();
385                 break;
386             case 
387                 result = String.valueOf(t.getSequenceNo());
388                 break;
389             case :
390                 result = String.valueOf(t.getTimeStamp());
391                 break;
392             case 
393                 result = t.getType();
394                 break;
395             case 
396                 result = t.getMessage();
397                 break;
398             default 
399                 result = "";
400             }
401             
402             return result;
403         }
404         
405         public boolean isLabelProperty(Object element, String property)
406         {
407             return false;
408         }
409         
410         public void removeListener(ILabelProviderListener listener)
411         {
412             listeners.remove(listener);
413         }
414     // end of LabelProviderImpl
415     
416     protected boolean workerRunning = false;
417     protected void setWorkerRunning(boolean running)
418     {
419         workerRunning = running;
420     }
421     
422     /**
423      * Worker class which keeps looking if there are new notifications coming from server for the selected mbean
424      */
425     private class Worker implements Runnable
426     {
427         public void run()
428         {
429             Display display = _tabFolder.getDisplay();
430             while(true)
431             {
432                 if (!workerRunning || display == null)
433                 {
434                     sleep();
435                     continue;
436                 }
437                 
438                 display.syncExec(new Runnable()
439                 {
440                     public void run()
441                     {
442                         if (_form == null || _form.isDisposed())
443                             return;
444                         setWorkerRunning(_form.isVisible());
445                         if (!workerRunningreturn;
446                         
447                         updateTableViewer();
448                     }
449                 });     
450             
451                 sleep();
452             }
453         }
454         
455         private void sleep()
456         {
457             try
458             {
459                 Thread.sleep(2000);
460             }
461             catch(Exception ex)
462             {
463 
464             }  
465         }
466     }
467     
468     /**
469      * Updates the table with new notifications received from mbean server for all mbeans
470      */
471     protected void updateTableViewer()
472     {
473         ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());        
474         List<NotificationObject> newList = serverRegistry.getNotifications(null);
475         if (newList == null)
476             return;
477         
478         _notifications = newList;
479         _tableViewer.setInput(_notifications);
480         _tableViewer.refresh();
481     }
482 
483 }