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(2, true));
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(4, true);
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, 3, 1);
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 0 :
384 result = t.getSourceName();
385 break;
386 case 1 :
387 result = String.valueOf(t.getSequenceNo());
388 break;
389 case 2 :
390 result = String.valueOf(t.getTimeStamp());
391 break;
392 case 3 :
393 result = t.getType();
394 break;
395 case 4 :
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 (!workerRunning) return;
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 }
|