1 19 20 package org.netbeans.modules.j2ee.common; 21 22 import java.awt.Color ; 23 import java.awt.Component ; 24 import java.awt.Dimension ; 25 import java.awt.event.ActionEvent ; 26 import java.awt.event.ActionListener ; 27 import java.awt.event.InputEvent ; 28 import java.awt.event.KeyAdapter ; 29 import java.awt.event.KeyEvent ; 30 import java.lang.reflect.Method ; 31 import java.util.ArrayList ; 32 import java.util.Collection ; 33 import java.util.Collections ; 34 import java.util.Comparator ; 35 import java.util.HashSet ; 36 import java.util.LinkedList ; 37 import java.util.List ; 38 import java.util.Set ; 39 import javax.swing.AbstractListModel ; 40 import javax.swing.ComboBoxEditor ; 41 import javax.swing.ComboBoxModel ; 42 import javax.swing.DefaultListCellRenderer ; 43 import javax.swing.JComboBox ; 44 import javax.swing.JList ; 45 import javax.swing.JSeparator ; 46 import javax.swing.MutableComboBoxModel ; 47 import javax.swing.SwingUtilities ; 48 import javax.swing.text.JTextComponent ; 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 66 public final class DatasourceUIHelper { 67 68 private static final class Separator extends JSeparator { 69 Separator() { 70 setPreferredSize(new Dimension (getWidth(), 1)); 71 setForeground(Color.BLACK); 72 } 73 } 74 75 static final Separator SEPARATOR_ITEM = new Separator (); 76 static final Object NEW_ITEM = new Object () { 77 public String toString() { 78 return NbBundle.getMessage(DatasourceUIHelper.class, "LBL_NEW_DATASOURCE"); } 80 }; 81 82 private static class DatasourceComboBoxModel extends AbstractListModel implements MutableComboBoxModel { 83 84 private List <Object > items; 85 private Object selectedItem; 86 private List <Datasource> datasources; 87 private Object previousItem; 88 89 private DatasourceComboBoxModel(List <Datasource> datasources, List <Object > items) { 90 this.datasources = datasources; 91 this.items = items; 92 } 93 94 public void setSelectedItem(Object 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 getSelectedItem() { 106 return selectedItem; 107 } 108 109 public Object getElementAt(int index) { 110 return items.get(index); 111 } 112 113 public int getSize() { 114 return items.size(); 115 } 116 117 Object getPreviousItem() { 118 return previousItem; 119 } 120 121 List <Datasource> getDatasources() { 122 return datasources; 123 } 124 125 public void addElement(Object elem) { 126 items.add(elem); 127 } 128 129 public void removeElement(Object elem) { 130 items.remove(elem); 131 } 132 133 public void insertElementAt(Object 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 { 144 145 public Component getListCellRendererComponent(JList list, Object 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() : ""); setToolTipText(ds.toString()); 159 } 160 else 161 if (value == SEPARATOR_ITEM) { 162 return SEPARATOR_ITEM; 163 } 164 else { 165 setText(value != null ? value.toString() : ""); setToolTipText(""); } 168 169 return this; 170 } 171 172 } 173 174 private static class DatasourceComparator implements Comparator <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 dispName1 = ds1.getDisplayName(); 187 String 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 { 200 201 private ComboBoxEditor delegate; 202 private Object oldValue; 203 204 DatasourceComboBoxEditor(ComboBoxEditor delegate) { 205 this.delegate = delegate; 206 } 207 208 public Component getEditorComponent() { 209 return delegate.getEditorComponent(); 210 } 211 212 public void setItem(Object anObject) { 213 214 JTextComponent editor = getEditor(); 215 216 if (anObject != null) { 217 String 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 public Object getItem() { 229 230 JTextComponent editor = getEditor(); 231 232 Object newValue = editor.getText(); 233 234 if (oldValue != null && !(oldValue instanceof String )) { 235 if (newValue.equals(oldValue.toString())) { 238 return oldValue; 239 } else { 240 Class <?> cls = oldValue.getClass(); 242 try { 243 Method method = cls.getMethod("valueOf", String .class); newValue = method.invoke(oldValue, new Object [] { editor.getText() }); 245 } catch (Exception ex) { 246 } 248 } 249 } 250 return newValue; 251 } 252 253 public void selectAll() { 254 delegate.selectAll(); 255 } 256 257 public void addActionListener(ActionListener l) { 258 delegate.addActionListener(l); 259 } 260 261 public void removeActionListener(ActionListener l) { 262 delegate.removeActionListener(l); 263 } 264 265 private JTextComponent getEditor() { 266 267 Component comp = getEditorComponent(); 268 assert (comp instanceof JTextComponent ); 269 270 return (JTextComponent )comp; 271 } 272 273 } 274 275 private DatasourceUIHelper() { 276 } 277 278 284 public static void connect(J2eeModuleProvider provider, JComboBox combo) { 285 connect(provider, combo, null); 286 } 287 288 private static final void connect(final J2eeModuleProvider provider, final JComboBox 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 Collection <Action> actions = new ArrayList <Action>(); 298 final List <Datasource> datasources = new ArrayList <Datasource>(); 299 actions.add(new AsynchronousAction() { 300 public void run(Context actionContext) { 301 String 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 toListenOn = (combo.isEditable() ? combo.getEditor().getEditorComponent() : combo); 311 312 toListenOn.addKeyListener(new KeyAdapter () { 313 public void keyPressed(final KeyEvent e) { 314 int keyCode = e.getKeyCode(); 315 if (KeyEvent.VK_ENTER == keyCode) { 316 Object 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 () { 326 327 Object previousItem; 328 int previousIndex = combo.getSelectedIndex(); 329 330 public void actionPerformed(ActionEvent e) { 331 332 Object selectedItem = combo.getSelectedItem(); 333 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 } 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 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 <Action> actions = new ArrayList <Action>(); 361 final Datasource[] ds = new Datasource[1]; 362 363 if (accept) { 365 final String password = dsc.getPassword(); 366 final String jndiName = dsc.getJndiName(); 367 final String url = dsc.getUrl(); 368 final String username = dsc.getUsername(); 369 final String driverClassName = dsc.getDriverClassName(); 370 actions.add(new AsynchronousAction() { 371 public void run(Context actionContext) { 372 String 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) { StringBuilder sb = new StringBuilder (); 378 for (Object conflict : daee.getDatasources()) { 379 sb.append(conflict.toString() + "\n"); } 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 final List <Datasource> datasources = new ArrayList <Datasource>(); 393 actions.add(new AsynchronousAction() { 394 public void run(Context actionContext) { 395 String 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 () { 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 422 private static List <Datasource> getDatasources(final J2eeModuleProvider provider) { 423 424 Set <Datasource> moduleDatasources = provider.getModuleDatasources(); 425 Set <Datasource> serverDatasources = provider.getServerDatasources(); 426 427 int initSize = moduleDatasources.size() + serverDatasources.size(); 428 429 Set <Datasource> datasources = new HashSet <Datasource>(initSize); 430 datasources.addAll(moduleDatasources); 431 datasources.addAll(serverDatasources); 432 433 ArrayList <Datasource> sortedDatasources = new ArrayList <Datasource>(datasources); 434 Collections.sort(sortedDatasources, new DatasourceComparator()); 435 return sortedDatasources; 436 } 437 438 private static List populate(List <Datasource> datasources, boolean creationSupported, final JComboBox combo, final Datasource selectedDatasource, boolean selectItemLater) { 439 440 441 List <Object > items = (datasources == null ? new LinkedList <Object >() : new LinkedList <Object >(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 setSelectedItem(combo, selectedDatasource); 463 464 if (selectItemLater) { 465 SwingUtilities.invokeLater(new Runnable () { 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 combo, final Object item) { 478 combo.setSelectedItem(item); 479 if (combo.isEditable() && combo.getEditor() != null) { 480 combo.configureEditor(combo.getEditor(), combo.getSelectedItem()); 482 } 483 } 484 485 } | Popular Tags |