KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > common > DatasourceUIHelper


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.j2ee.common;
21
22 import java.awt.Color JavaDoc;
23 import java.awt.Component JavaDoc;
24 import java.awt.Dimension JavaDoc;
25 import java.awt.event.ActionEvent JavaDoc;
26 import java.awt.event.ActionListener JavaDoc;
27 import java.awt.event.InputEvent JavaDoc;
28 import java.awt.event.KeyAdapter JavaDoc;
29 import java.awt.event.KeyEvent JavaDoc;
30 import java.lang.reflect.Method JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Collection JavaDoc;
33 import java.util.Collections JavaDoc;
34 import java.util.Comparator JavaDoc;
35 import java.util.HashSet JavaDoc;
36 import java.util.LinkedList JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Set JavaDoc;
39 import javax.swing.AbstractListModel JavaDoc;
40 import javax.swing.ComboBoxEditor JavaDoc;
41 import javax.swing.ComboBoxModel JavaDoc;
42 import javax.swing.DefaultListCellRenderer JavaDoc;
43 import javax.swing.JComboBox JavaDoc;
44 import javax.swing.JList JavaDoc;
45 import javax.swing.JSeparator JavaDoc;
46 import javax.swing.MutableComboBoxModel JavaDoc;
47 import javax.swing.SwingUtilities JavaDoc;
48 import javax.swing.text.JTextComponent JavaDoc;
49 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
50 import org.netbeans.modules.j2ee.deployment.common.api.Datasource;
51 import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException;
52 import org.netbeans.modules.j2ee.common.EventRequestProcessor.Action;
53 import org.netbeans.modules.j2ee.common.EventRequestProcessor.AsynchronousAction;
54 import org.netbeans.modules.j2ee.common.EventRequestProcessor.Context;
55 import org.openide.ErrorManager;
56 import org.openide.util.NbBundle;
57
58 /**
59  *
60  * DatasourceUIHelper populates and manages the content of the combobox for a data sources management.
61  *
62  * @author Libor Kotouc
63  *
64  * @since 1.6
65  */

66 public final class DatasourceUIHelper {
67
68     private static final class Separator extends JSeparator JavaDoc {
69         Separator() {
70             setPreferredSize(new Dimension JavaDoc(getWidth(), 1));
71             setForeground(Color.BLACK);
72         }
73     }
74     
75     static final Separator JavaDoc SEPARATOR_ITEM = new Separator JavaDoc();
76     static final Object JavaDoc NEW_ITEM = new Object JavaDoc() {
77         public String JavaDoc toString() {
78             return NbBundle.getMessage(DatasourceUIHelper.class, "LBL_NEW_DATASOURCE"); // NOI18N
79
}
80     };
81     
82     private static class DatasourceComboBoxModel extends AbstractListModel JavaDoc implements MutableComboBoxModel JavaDoc {
83         
84         private List JavaDoc<Object JavaDoc> items;
85         private Object JavaDoc selectedItem;
86         private List JavaDoc<Datasource> datasources;
87         private Object JavaDoc previousItem;
88         
89         private DatasourceComboBoxModel(List JavaDoc<Datasource> datasources, List JavaDoc<Object JavaDoc> items) {
90             this.datasources = datasources;
91             this.items = items;
92         }
93
94         public void setSelectedItem(Object JavaDoc anItem) {
95             
96             if (selectedItem == null || !selectedItem.equals(anItem)) {
97                         
98                 previousItem = selectedItem;
99                 selectedItem = anItem;
100
101                 fireContentsChanged(this, 0, -1);
102             }
103         }
104
105         public Object JavaDoc getSelectedItem() {
106             return selectedItem;
107         }
108         
109         public Object JavaDoc getElementAt(int index) {
110             return items.get(index);
111         }
112         
113         public int getSize() {
114             return items.size();
115         }
116         
117         Object JavaDoc getPreviousItem() {
118             return previousItem;
119         }
120         
121         List JavaDoc<Datasource> getDatasources() {
122             return datasources;
123         }
124         
125         public void addElement(Object JavaDoc elem) {
126            items.add(elem);
127         }
128
129         public void removeElement(Object JavaDoc elem) {
130             items.remove(elem);
131         }
132
133         public void insertElementAt(Object JavaDoc elem, int index) {
134             items.set(index, elem);
135         }
136
137         public void removeElementAt(int index) {
138             items.remove(index);
139         }
140         
141     }
142     
143     private static class DatasourceListCellRenderer extends DefaultListCellRenderer JavaDoc {
144
145         public Component JavaDoc getListCellRendererComponent(JList JavaDoc list, Object JavaDoc value, int index, boolean isSelected, boolean cellHasFocus) {
146
147             if (isSelected) {
148                 setBackground(list.getSelectionBackground());
149                 setForeground(list.getSelectionForeground());
150             } else {
151                 setBackground(list.getBackground());
152                 setForeground(list.getForeground());
153             }
154
155             if (value instanceof Datasource) {
156                 Datasource ds = (Datasource) value;
157                 setText(ds != null ? ds.getDisplayName() : ""); // NOI18N
158
setToolTipText(ds.toString());
159             }
160             else
161             if (value == SEPARATOR_ITEM) {
162                 return SEPARATOR_ITEM;
163             }
164             else {
165                 setText(value != null ? value.toString() : ""); // NOI18N
166
setToolTipText(""); // NOI18N
167
}
168             
169             return this;
170         }
171
172     }
173     
174     private static class DatasourceComparator implements Comparator JavaDoc<Datasource> {
175         
176         public int compare(Datasource ds1, Datasource ds2) {
177             
178             if (ds1 == null) {
179                 return ds2 == null ? 0 : -1;
180             }
181             else {
182                 if (ds2 == null) {
183                     return 1;
184                 }
185                 else {
186                     String JavaDoc dispName1 = ds1.getDisplayName();
187                     String JavaDoc dispName2 = ds2.getDisplayName();
188                     if (dispName1 == null) {
189                         return dispName2 == null ? 0 : -1;
190                     }
191                     else {
192                         return dispName2 == null ? 1 : dispName1.compareToIgnoreCase(dispName2);
193                     }
194                 }
195             }
196         }
197     }
198     
199     private static class DatasourceComboBoxEditor implements ComboBoxEditor JavaDoc {
200         
201         private ComboBoxEditor JavaDoc delegate;
202         private Object JavaDoc oldValue;
203         
204         DatasourceComboBoxEditor(ComboBoxEditor JavaDoc delegate) {
205             this.delegate = delegate;
206         }
207
208         public Component JavaDoc getEditorComponent() {
209             return delegate.getEditorComponent();
210         }
211
212         public void setItem(Object JavaDoc anObject) {
213             
214             JTextComponent JavaDoc editor = getEditor();
215             
216             if (anObject != null) {
217                 String JavaDoc text = (anObject instanceof Datasource ? ((Datasource)anObject).getJndiName() : anObject.toString());
218                 editor.setText(text);
219
220                 oldValue = anObject;
221             }
222             else {
223                 editor.setText("");
224             }
225         }
226
227         // this method is taken from javax.swing.plaf.basic.BasicComboBoxEditor
228
public Object JavaDoc getItem() {
229             
230             JTextComponent JavaDoc editor = getEditor();
231             
232             Object JavaDoc newValue = editor.getText();
233
234             if (oldValue != null && !(oldValue instanceof String JavaDoc)) {
235                 // The original value is not a string. Should return the value in it's
236
// original type.
237
if (newValue.equals(oldValue.toString())) {
238                     return oldValue;
239                 } else {
240                     // Must take the value from the editor and get the value and cast it to the new type.
241
Class JavaDoc<?> cls = oldValue.getClass();
242                     try {
243                         Method JavaDoc method = cls.getMethod("valueOf", String JavaDoc.class); // NOI18N
244
newValue = method.invoke(oldValue, new Object JavaDoc[] { editor.getText() });
245                     } catch (Exception JavaDoc ex) {
246                         // Fail silently and return the newValue (a String object)
247
}
248                 }
249             }
250             return newValue;
251         }
252
253         public void selectAll() {
254             delegate.selectAll();
255         }
256
257         public void addActionListener(ActionListener JavaDoc l) {
258             delegate.addActionListener(l);
259         }
260
261         public void removeActionListener(ActionListener JavaDoc l) {
262             delegate.removeActionListener(l);
263         }
264         
265         private JTextComponent JavaDoc getEditor() {
266             
267             Component JavaDoc comp = getEditorComponent();
268             assert (comp instanceof JTextComponent JavaDoc);
269             
270             return (JTextComponent JavaDoc)comp;
271         }
272
273     }
274     
275     private DatasourceUIHelper() {
276     }
277
278     /**
279      * Entry point for the combobox initialization. It connects combobox with its content and
280      * add items for the combobox content management.
281      *
282      * @param combo combobox to manage
283      */

284     public static void connect(J2eeModuleProvider provider, JComboBox JavaDoc combo) {
285         connect(provider, combo, null);
286     }
287     
288     private static final void connect(final J2eeModuleProvider provider, final JComboBox JavaDoc combo, final Datasource selectedDatasource) {
289         
290         assert(provider != null);
291         
292         combo.setEditor(new DatasourceComboBoxEditor(combo.getEditor()));
293         
294         combo.setRenderer(new DatasourceListCellRenderer());
295         
296         // fetch datasources asynchronously
297
Collection JavaDoc<Action> actions = new ArrayList JavaDoc<Action>();
298         final List JavaDoc<Datasource> datasources = new ArrayList JavaDoc<Datasource>();
299         actions.add(new AsynchronousAction() {
300             public void run(Context actionContext) {
301                 String JavaDoc msg = NbBundle.getMessage(DatasourceUIHelper.class, "MSG_retrievingDS");
302                 actionContext.getProgress().progress(msg);
303                 datasources.addAll(getDatasources(provider));
304             }
305         });
306         EventRequestProcessor eventRP = new EventRequestProcessor();
307         eventRP.invoke(actions);
308
309         populate(datasources, provider.isDatasourceCreationSupported(), combo, selectedDatasource, false);
310         Component JavaDoc toListenOn = (combo.isEditable() ? combo.getEditor().getEditorComponent() : combo);
311             
312         toListenOn.addKeyListener(new KeyAdapter JavaDoc() {
313             public void keyPressed(final KeyEvent JavaDoc e) {
314                 int keyCode = e.getKeyCode();
315                 if (KeyEvent.VK_ENTER == keyCode) {
316                     Object JavaDoc selectedItem = combo.getSelectedItem();
317                     if (selectedItem == NEW_ITEM) {
318                         performCreateDatasource(provider, combo, false);
319                         e.consume();
320                     }
321                 }
322             }
323         });
324         
325         combo.addActionListener(new ActionListener JavaDoc() {
326             
327             Object JavaDoc previousItem;
328             int previousIndex = combo.getSelectedIndex();
329
330             public void actionPerformed(ActionEvent JavaDoc e) {
331
332                 Object JavaDoc selectedItem = combo.getSelectedItem();
333                 // skipping of separator
334
if (selectedItem == SEPARATOR_ITEM) {
335                     int selectedIndex = combo.getSelectedIndex();
336                     if (selectedIndex > previousIndex) {
337                         previousIndex = selectedIndex + 1;
338                         previousItem = combo.getItemAt(previousIndex);
339                     } else {
340                         previousIndex = selectedIndex - 1;
341                         previousItem = combo.getItemAt(previousIndex);
342                     }
343                     combo.setSelectedItem(previousItem);
344                     // handling mouse click, see KeyEvent.getKeyModifiersText(e.getModifiers())
345
} else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
346                     if (selectedItem == NEW_ITEM) {
347                         performCreateDatasource(provider, combo, true);
348                     }
349                 }
350             }
351         });
352
353     }
354     
355     private static void performCreateDatasource(final J2eeModuleProvider provider, final JComboBox JavaDoc combo, boolean selectItemLater) {
356         
357         final DatasourceComboBoxModel model = (DatasourceComboBoxModel) combo.getModel();
358         final DatasourceCustomizer dsc = new DatasourceCustomizer(model.getDatasources());
359         boolean accept = dsc.showDialog();
360         Collection JavaDoc<Action> actions = new ArrayList JavaDoc<Action>();
361         final Datasource[] ds = new Datasource[1];
362         
363         // creating datasources asynchronously
364
if (accept) {
365             final String JavaDoc password = dsc.getPassword();
366             final String JavaDoc jndiName = dsc.getJndiName();
367             final String JavaDoc url = dsc.getUrl();
368             final String JavaDoc username = dsc.getUsername();
369             final String JavaDoc driverClassName = dsc.getDriverClassName();
370             actions.add(new AsynchronousAction() {
371                 public void run(Context actionContext) {
372                     String JavaDoc msg = NbBundle.getMessage(DatasourceUIHelper.class, "MSG_creatingDS");
373                     actionContext.getProgress().progress(msg);
374                     try {
375                         ds[0] = provider.createDatasource(jndiName, url, username, password, driverClassName);
376                     } catch (DatasourceAlreadyExistsException daee) { // it should not occur bcs it should be already handled in DatasourceCustomizer
377
StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
378                         for (Object JavaDoc conflict : daee.getDatasources()) {
379                             sb.append(conflict.toString() + "\n"); // NOI18N
380
}
381                         ErrorManager.getDefault().annotate(daee, NbBundle.getMessage(DatasourceUIHelper.class, "ERR_DsConflict", sb.toString()));
382                         ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, daee);
383                     }
384                 }
385                 
386                 public boolean isEnabled() {
387                     return password != null;
388                 }
389             });
390         }
391         // fetch datasources asynchronously
392
final List JavaDoc<Datasource> datasources = new ArrayList JavaDoc<Datasource>();
393         actions.add(new AsynchronousAction() {
394             public void run(Context actionContext) {
395                 String JavaDoc msg = NbBundle.getMessage(DatasourceUIHelper.class, "MSG_retrievingDS");
396                 actionContext.getProgress().progress(msg);
397                 datasources.addAll(getDatasources(provider));
398             }
399
400             public boolean isEnabled() {
401                 return ds[0] != null;
402             }
403         });
404         EventRequestProcessor eventRP = new EventRequestProcessor();
405         eventRP.invoke(actions);
406         
407         combo.setPopupVisible(false);
408         if (ds[0] == null) {
409             SwingUtilities.invokeLater(new Runnable JavaDoc() {
410                 public void run() {
411                     setSelectedItem(combo, model.getPreviousItem());
412                 }
413             });
414         } else {
415             populate(datasources, provider.isDatasourceCreationSupported(), combo, ds[0], selectItemLater);
416         }
417     }
418     
419     /**
420      * Returns a sorted list of all datasources (from the module and the server)
421      */

422     private static List JavaDoc<Datasource> getDatasources(final J2eeModuleProvider provider) {
423         
424         Set JavaDoc<Datasource> moduleDatasources = provider.getModuleDatasources();
425         Set JavaDoc<Datasource> serverDatasources = provider.getServerDatasources();
426         
427         int initSize = moduleDatasources.size() + serverDatasources.size();
428         
429         Set JavaDoc<Datasource> datasources = new HashSet JavaDoc<Datasource>(initSize);
430         datasources.addAll(moduleDatasources);
431         datasources.addAll(serverDatasources);
432         
433         ArrayList JavaDoc<Datasource> sortedDatasources = new ArrayList JavaDoc<Datasource>(datasources);
434         Collections.sort(sortedDatasources, new DatasourceComparator());
435         return sortedDatasources;
436     }
437     
438     private static List JavaDoc populate(List JavaDoc<Datasource> datasources, boolean creationSupported, final JComboBox JavaDoc combo, final Datasource selectedDatasource, boolean selectItemLater) {
439
440         
441         List JavaDoc<Object JavaDoc> items = (datasources == null ? new LinkedList JavaDoc<Object JavaDoc>() : new LinkedList JavaDoc<Object JavaDoc>(datasources));
442         
443         if (items.size() > 0) {
444             items.add(SEPARATOR_ITEM);
445         }
446         
447         if (creationSupported) {
448             items.add(NEW_ITEM);
449         }
450         
451         
452         DatasourceComboBoxModel model = new DatasourceComboBoxModel(datasources, items);
453
454         combo.setModel(model);
455         
456         if (selectedDatasource != null) {
457
458             // Ensure that the correct item is selected before listeners like FocusListener are called.
459
// ActionListener.actionPerformed() is not called if this method is already called from
460
// actionPerformed(), in that case selectItemLater should be set to true and setSelectedItem()
461
// below is called asynchronously so that the actionPerformed() is called
462
setSelectedItem(combo, selectedDatasource);
463
464             if (selectItemLater) {
465                 SwingUtilities.invokeLater(new Runnable JavaDoc() { // postpone item selection to enable event firing from JCombobox.setSelectedItem()
466
public void run() {
467                         setSelectedItem(combo, selectedDatasource);
468                     }
469                 });
470             }
471
472         }
473         
474         return datasources;
475     }
476
477     private static void setSelectedItem(final JComboBox JavaDoc combo, final Object JavaDoc item) {
478         combo.setSelectedItem(item);
479         if (combo.isEditable() && combo.getEditor() != null) {
480             // item must be set in the editor in case of editable combobox
481
combo.configureEditor(combo.getEditor(), combo.getSelectedItem());
482         }
483     }
484     
485 }
Popular Tags