NotificationsTabControl.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 package org.apache.qpid.management.ui.views;
022 
023 import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR;
024 import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH;
025 import static org.apache.qpid.management.ui.Constants.DESCRIPTION;
026 import static org.apache.qpid.management.ui.Constants.FONT_BOLD;
027 import static org.apache.qpid.management.ui.Constants.FONT_BUTTON;
028 import static org.apache.qpid.management.ui.Constants.FONT_ITALIC;
029 import static org.apache.qpid.management.ui.Constants.SUBSCRIBE_BUTTON;
030 import static org.apache.qpid.management.ui.Constants.UNSUBSCRIBE_BUTTON;
031 
032 import java.util.List;
033 
034 import org.apache.qpid.management.ui.ApplicationRegistry;
035 import org.apache.qpid.management.ui.ManagedBean;
036 import org.apache.qpid.management.ui.ServerRegistry;
037 import org.apache.qpid.management.ui.jmx.MBeanUtility;
038 import org.apache.qpid.management.ui.model.NotificationInfoModel;
039 import org.apache.qpid.management.ui.model.NotificationObject;
040 import org.eclipse.jface.viewers.IStructuredSelection;
041 import org.eclipse.swt.SWT;
042 import org.eclipse.swt.events.SelectionAdapter;
043 import org.eclipse.swt.events.SelectionEvent;
044 import org.eclipse.swt.events.SelectionListener;
045 import org.eclipse.swt.layout.FormAttachment;
046 import org.eclipse.swt.layout.FormData;
047 import org.eclipse.swt.layout.FormLayout;
048 import org.eclipse.swt.layout.GridData;
049 import org.eclipse.swt.layout.GridLayout;
050 import org.eclipse.swt.widgets.Button;
051 import org.eclipse.swt.widgets.Combo;
052 import org.eclipse.swt.widgets.Composite;
053 import org.eclipse.swt.widgets.Control;
054 import org.eclipse.swt.widgets.Label;
055 import org.eclipse.swt.widgets.TabFolder;
056 
057 /**
058  * Creates control composite for Notifications tab
059  @author Bhupendra Bhardwaj
060  */
061 public class NotificationsTabControl extends VHNotificationsTabControl
062 {    
063     private static final String SELECT_NOTIFICATIONNAME = "Select Notification";
064     private static final String SELECT_NOTIFICATIONTYPE = "Select Type";
065     private SelectionListener selectionListener;
066     private SelectionListener comboListener;    
067     
068     private Combo notificationNameCombo = null;
069     private Combo typesCombo = null;
070     private Label descriptionLabel = null;
071     private Button _subscribeButton   = null;
072     private Button _unsubscribeButton = null;
073     
074     public NotificationsTabControl(TabFolder tabFolder)
075     {
076         super(tabFolder);
077     }
078     
079     protected void createWidgets()
080     {       
081         selectionListener = new SelectionListenerImpl();
082         comboListener = new ComboSelectionListener();
083         createNotificationInfoComposite();
084         //addFilterComposite();
085         addButtons();  
086         createTableViewer();
087     }
088     
089     /**
090      * Creates composite and populates for displaying Notification Information (name, type, description)
091      * and creates buttons for subscribing or unsubscribing for notifications
092      */
093     private void createNotificationInfoComposite()
094     {
095         Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
096         composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
097         composite.setLayout(new FormLayout());
098         
099         Label label = _toolkit.createLabel(composite, "Select the notification to subscribe or unsubscribe");
100         label.setFont(ApplicationRegistry.getFont(FONT_BOLD));
101         FormData formData = new FormData();
102         formData.top = new FormAttachment(010);
103         formData.left = new FormAttachment(010);
104         label.setLayoutData(formData);
105         
106         notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
107         formData = new FormData();
108         formData.top = new FormAttachment(label, 10);
109         formData.left = new FormAttachment(010);
110         formData.right = new FormAttachment(40);
111         notificationNameCombo.setLayoutData(formData);
112         notificationNameCombo.addSelectionListener(comboListener);
113         
114         typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
115         formData = new FormData();
116         formData.top = new FormAttachment(label, 10);
117         formData.left = new FormAttachment(notificationNameCombo, 5);
118         formData.right = new FormAttachment(65);
119         typesCombo.setLayoutData(formData);
120         typesCombo.addSelectionListener(comboListener);
121         
122         _subscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER);
123         _subscribeButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
124         _subscribeButton.setText(SUBSCRIBE_BUTTON);
125         formData = new FormData();
126         formData.top = new FormAttachment(label, 10);
127         formData.left = new FormAttachment(6510);
128         formData.width = 80;
129         _subscribeButton.setLayoutData(formData);
130         _subscribeButton.addSelectionListener(selectionListener);
131         
132         _unsubscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER);
133         _unsubscribeButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
134         _unsubscribeButton.setText(UNSUBSCRIBE_BUTTON);
135         formData = new FormData();
136         formData.top = new FormAttachment(label, 10);
137         formData.left = new FormAttachment(_subscribeButton, 10);
138         formData.width = 80;
139         _unsubscribeButton.setLayoutData(formData);
140         _unsubscribeButton.addSelectionListener(selectionListener);
141         
142         Label fixedLabel = _toolkit.createLabel(composite, "");
143         formData = new FormData();
144         formData.top = new FormAttachment(notificationNameCombo, 5);
145         formData.left = new FormAttachment(010);
146         fixedLabel.setLayoutData(formData);
147         fixedLabel.setText(DESCRIPTION + " : ");
148         fixedLabel.setFont(ApplicationRegistry.getFont(FONT_BOLD));
149         
150         descriptionLabel = _toolkit.createLabel(composite, "");
151         formData = new FormData();
152         formData.top = new FormAttachment(notificationNameCombo, 5);
153         formData.left = new FormAttachment(fixedLabel, 10);
154         formData.right = new FormAttachment(100);
155         descriptionLabel.setLayoutData(formData);
156         descriptionLabel.setText("      ");
157         descriptionLabel.setFont(ApplicationRegistry.getFont(FONT_ITALIC));
158     }
159     
160     /**
161      * Creates clear buttin and refresh button
162      */
163     protected void addButtons()
164     {    
165         Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
166         composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
167         composite.setLayout(new GridLayout(2true));
168         
169         // Add Clear Button
170         _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER);
171         _clearButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
172         GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false);
173         gridData.widthHint = 80;
174         _clearButton.setLayoutData(gridData);
175         _clearButton.addSelectionListener(new SelectionAdapter()
176             {
177                 public void widgetSelected(SelectionEvent e)
178                 {    
179                     if (_mbean == null)
180                         return;
181                     
182                     IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
183                     ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
184                     serverRegistry.clearNotifications(_mbean, ss.toList());
185                     refresh();
186                 }
187             });
188         
189         // Add Refresh Button
190         _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER);
191         _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
192         gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false);
193         gridData.widthHint = 80;
194         _refreshButton.setLayoutData(gridData);
195         _refreshButton.addSelectionListener(new SelectionAdapter()
196             {
197                 public void widgetSelected(SelectionEvent e)
198                 {    
199                     if (_mbean == null)
200                         return;
201                     
202                     refresh();
203                 }
204             });
205     }
206   
207     @Override
208     public void refresh(ManagedBean mbean)
209     {
210         _mbean = mbean;
211         _notifications = null;
212         _table.deselectAll();
213         _tableViewer.getTable().clearAll();
214         
215         if (_mbean == null)
216         {            
217             _tableViewer.getTable().clearAll();
218             _subscribeButton.setEnabled(false);
219             _unsubscribeButton.setEnabled(false);
220             return;
221         }        
222         
223         if (!doesMBeanSendsNotification())
224         {
225             Control[] children = _form.getBody().getChildren();        
226             for (int i = 0; i < children.length; i++)
227             {
228                 children[i].setVisible(false);
229             }
230             
231             String name = (_mbean.getName() != null? _mbean.getName() : _mbean.getType();
232             _form.setText(name + " does not send any notification");
233             return;
234         }
235         
236         Control[] children = _form.getBody().getChildren();        
237         for (int i = 0; i < children.length; i++)
238         {
239             children[i].setVisible(true);
240         }
241         
242         populateNotificationInfo();        
243         workerRunning = true;
244         _form.layout(true);   
245         _form.getBody().layout(true, true);
246     }
247     
248     public void refresh()
249     {
250         _notifications = null;
251         _table.deselectAll();
252         _tableViewer.getTable().clearAll();
253     }
254     
255     /**
256      * Fills the notification information widgets for selected mbean
257      */
258     private void populateNotificationInfo()
259     {
260         notificationNameCombo.removeAll();
261         NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
262         if (items.length > 1)
263         {
264             notificationNameCombo.add(SELECT_NOTIFICATIONNAME);
265         }
266         
267         for (int i = 0; i < items.length; i++)
268         {
269             notificationNameCombo.add(items[i].getName());
270             notificationNameCombo.setData(items[i].getName(), items[i]);
271         
272         notificationNameCombo.select(0);
273         
274         typesCombo.removeAll();
275         typesCombo.add("Select Type"0);
276         typesCombo.select(0);
277         typesCombo.setEnabled(false);
278         
279         populateNotificationType(notificationNameCombo.getItem(0));
280         checkForEnablingButtons();
281     }
282     
283     /**
284      * Checks and the enabing/disabling of buttons
285      */
286     private void checkForEnablingButtons()
287     {
288         int nameIndex = notificationNameCombo.getSelectionIndex();
289         int itemCount = notificationNameCombo.getItems().length;
290         if ((itemCount > 1&& (nameIndex == 0))
291         {
292             _subscribeButton.setEnabled(false);
293             _unsubscribeButton.setEnabled(false);
294             descriptionLabel.setText("");
295             return;
296         }
297         
298         int typeIndex = typesCombo.getSelectionIndex();
299         itemCount = typesCombo.getItems().length;
300         if ((itemCount > 1&& (typeIndex == 0))
301         {
302             _subscribeButton.setEnabled(false);
303             _unsubscribeButton.setEnabled(false);
304             return;
305         }
306         
307         String type = typesCombo.getItem(typeIndex);
308         String name = notificationNameCombo.getItem(nameIndex);
309         ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
310         
311         if (serverRegistry.hasSubscribedForNotifications(_mbean, name, type))
312         {
313             _subscribeButton.setEnabled(false);
314             _unsubscribeButton.setEnabled(true);
315         }
316         else
317         {
318             _subscribeButton.setEnabled(true);
319             _unsubscribeButton.setEnabled(false);
320         }
321     }
322     
323     private boolean doesMBeanSendsNotification()
324     {
325         NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
326         if (items == null || items.length == 0)
327             return false;
328         else
329             return true;
330     }
331     
332     /**
333      * Selection listener for subscribing or unsubscribing the notifications
334      */
335     private class SelectionListenerImpl extends SelectionAdapter
336     {
337         public void widgetSelected(SelectionEvent e)
338         {
339             if (_mbean == null)
340                 return;
341             
342             Button source = (Button)e.getSource();
343             String type = typesCombo.getItem(typesCombo.getSelectionIndex());
344             String name = notificationNameCombo.getItem(notificationNameCombo.getSelectionIndex());
345             if (source == _unsubscribeButton)
346             {
347                 try
348                 {
349                     MBeanUtility.removeNotificationListener(_mbean, name, type);
350                 }
351                 catch(Exception ex)
352                 {
353                     MBeanUtility.handleException(ex);
354                 }
355             }
356             else if (source == _subscribeButton)
357             {
358                 try
359                 {
360                     MBeanUtility.createNotificationlistener(_mbean, name, type);
361                 }
362                 catch(Exception ex)
363                 {
364                     MBeanUtility.handleException(ex);
365                 }
366             }
367             checkForEnablingButtons();
368         }
369     }
370     
371     /**
372      * Selection listener class for the Notification Name. The notification type and description will be 
373      * displayed accordingly
374      */
375     private class ComboSelectionListener extends SelectionAdapter
376     {
377         public void widgetSelected(SelectionEvent e)
378         {
379             if (_mbean == null)
380                 return;
381             
382             Combo combo = (Combo)e.getSource();
383             if (combo == notificationNameCombo)
384             {
385                 String selectedItem = combo.getItem(combo.getSelectionIndex());                
386                 populateNotificationType(selectedItem);
387             }
388             checkForEnablingButtons();
389         }
390     }
391     
392     private void populateNotificationType(String notificationName)
393     {
394         NotificationInfoModel data = (NotificationInfoModel)notificationNameCombo.getData(notificationName);
395         if (data == null)
396         {
397             descriptionLabel.setText("");
398             typesCombo.select(0);
399             typesCombo.setEnabled(false);
400             return;
401         }
402         descriptionLabel.setText(data.getDescription());
403         typesCombo.removeAll();       
404         typesCombo.setItems(data.getTypes());
405         if (typesCombo.getItemCount() 1)
406         {
407             typesCombo.add(SELECT_NOTIFICATIONTYPE, 0);
408         }
409         typesCombo.select(0);
410         typesCombo.setEnabled(true);
411     }
412     
413     /**
414      * Updates the table with new notifications received from mbean server for the selected mbean
415      */
416     protected void updateTableViewer()
417     {
418         ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);        
419         List<NotificationObject> newList = serverRegistry.getNotifications(_mbean);
420         if (newList == null)
421             return;
422         
423         _notifications = newList;
424         _tableViewer.setInput(_notifications);
425         _tableViewer.refresh();
426     }
427 }