1 19 20 package org.netbeans.modules.j2ee.earproject.ui.customizer; 21 22 import java.awt.Component ; 23 import java.awt.Dialog ; 24 import java.awt.event.ActionEvent ; 25 import java.awt.event.ActionListener ; 26 import java.io.File ; 27 import java.util.ArrayList ; 28 import java.util.Arrays ; 29 import java.util.Collection ; 30 import java.util.Collections ; 31 import java.util.HashSet ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import javax.swing.DefaultListSelectionModel ; 35 import javax.swing.JButton ; 36 import javax.swing.JFileChooser ; 37 import javax.swing.JTable ; 38 import javax.swing.ListSelectionModel ; 39 import javax.swing.event.ListSelectionEvent ; 40 import javax.swing.event.ListSelectionListener ; 41 import javax.swing.event.TableModelEvent ; 42 import javax.swing.event.TableModelListener ; 43 import javax.swing.filechooser.FileFilter ; 44 import javax.swing.table.AbstractTableModel ; 45 import javax.swing.table.DefaultTableCellRenderer ; 46 import javax.swing.table.TableCellRenderer ; 47 import org.netbeans.api.java.project.JavaProjectConstants; 48 import org.netbeans.api.project.Project; 49 import org.netbeans.api.project.ant.AntArtifact; 50 import org.netbeans.api.project.libraries.LibrariesCustomizer; 51 import org.netbeans.api.project.libraries.Library; 52 import org.netbeans.api.project.libraries.LibraryManager; 53 import org.netbeans.modules.j2ee.api.ejbjar.EjbProjectConstants; 54 import org.netbeans.modules.web.api.webmodule.WebProjectConstants; 55 import org.openide.DialogDescriptor; 56 import org.openide.DialogDisplayer; 57 import org.openide.util.NbBundle; 58 import org.openide.util.Utilities; 59 60 61 public final class VisualClasspathSupport { 62 63 final Project master; 64 String j2eePlatform; 65 final JTable classpathTable; 66 final JButton addJarButton; 67 final JButton addLibraryButton; 68 final JButton addArtifactButton; 69 final JButton editButton; 70 final JButton removeButton; 71 final JButton upButton; 72 final JButton downButton; 73 74 private final ClasspathTableModel classpathModel; 75 76 private final List <ActionListener > actionListeners = new ArrayList <ActionListener >(); 77 private static Collection baseLibrarySet = Collections.EMPTY_LIST; 79 public VisualClasspathSupport(Project master, 80 String j2eePlatform, 81 JTable classpathTable, 82 JButton addJarButton, 83 JButton addLibraryButton, 84 JButton addArtifactButton, 85 JButton editButton, 86 JButton removeButton, 87 JButton upButton, 88 JButton downButton) { 89 this(master,j2eePlatform,classpathTable,addJarButton,addLibraryButton, 90 addArtifactButton, editButton,removeButton,upButton,downButton, 91 false); 92 } 93 94 public VisualClasspathSupport(Project master, 95 String j2eePlatform, 96 JTable classpathTable, 97 JButton addJarButton, 98 JButton addLibraryButton, 99 JButton addArtifactButton, 100 JButton editButton, 101 JButton removeButton, 102 JButton upButton, 103 JButton downButton, 104 boolean singleColumn) { 105 this.classpathTable = classpathTable; 107 this.classpathTable.setGridColor(this.classpathTable.getBackground()); 108 this.classpathTable.setRowHeight(this.classpathTable.getRowHeight() + 4); 109 this.classpathModel = new ClasspathTableModel(singleColumn); 110 this.classpathTable.setModel(classpathModel); 111 this.classpathTable.setTableHeader(null); 112 this.classpathTable.getColumnModel().getColumn(0).setCellRenderer(new LibraryCellRenderer()); 113 if (!singleColumn) { 114 this.classpathTable.getColumnModel().getColumn(1).setCellRenderer(new BooleanCellRenderer(classpathTable)); 115 this.classpathTable.getColumnModel().getColumn(1).setMaxWidth(25); 116 } 117 this.classpathTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 118 119 this.addJarButton = addJarButton; 120 this.addLibraryButton = addLibraryButton; 121 this.addArtifactButton = addArtifactButton; 122 this.editButton = editButton; 123 this.removeButton = removeButton; 124 this.upButton = upButton; 125 this.downButton = downButton; 126 127 this.master = master; 128 this.j2eePlatform = j2eePlatform; 129 130 ClasspathSupportListener csl = new ClasspathSupportListener(); 132 133 addJarButton.addActionListener(csl); 135 addLibraryButton.addActionListener(csl); 136 addArtifactButton.addActionListener(csl); 137 editButton.addActionListener(csl); 138 removeButton.addActionListener(csl); 139 upButton.addActionListener(csl); 140 downButton.addActionListener(csl); 141 classpathTable.getSelectionModel().addListSelectionListener(csl); 143 144 classpathModel.addTableModelListener(csl); 145 146 csl.valueChanged(null); 148 } 149 150 public void setVisualClassPathItems(List <VisualClassPathItem> items) { 151 classpathModel.setItems(items); 152 } 153 154 public List <VisualClassPathItem> getVisualClassPathItems() { 155 return classpathModel.getItems(); 156 } 157 158 161 public void addActionListener( ActionListener listener ) { 162 actionListeners.add( listener ); 163 } 164 165 public void removeActionListener( ActionListener listener ) { 166 actionListeners.remove( listener ); 167 } 168 169 private void fireActionPerformed() { 170 List <ActionListener > listeners; 171 172 synchronized ( this ) { 173 listeners = new ArrayList <ActionListener >(actionListeners); 174 } 175 176 ActionEvent ae = new ActionEvent ( this, 0, null ); 177 for (ActionListener al : listeners) { 178 al.actionPerformed( ae ); 179 } 180 } 181 182 184 private Collection <Object > getLibraries () { 185 Collection <Object > libs = new HashSet <Object >(); 186 for (VisualClassPathItem vcpi : getVisualClassPathItems()) { 187 if (vcpi.getType() == VisualClassPathItem.Type.LIBRARY) { 188 libs.add (vcpi.getObject()); 189 } 190 } 191 return libs; 192 } 193 194 private void addLibraries(Library[] libraries) { 195 if (libraries.length > 0) { 196 List <Library> newLibList = new ArrayList <Library>(Arrays.asList(libraries)); 197 classpathTable.clearSelection(); 198 int n0 = classpathModel.size(); 199 for (int i = 0; i < n0; i++) { 200 VisualClassPathItem item = classpathModel.get(i); 201 if(item.getType() == VisualClassPathItem.Type.LIBRARY 202 && newLibList.remove(item.getObject())) { 203 classpathTable.addRowSelectionInterval(i, i); 204 } 205 } 206 int n = newLibList.size(); 207 if (n > 0) { 208 for (Library library : newLibList) { 209 VisualClassPathItem item = VisualClassPathItem.createLibrary(library, VisualClassPathItem.PATH_IN_WAR_LIB); 210 classpathModel.add(item); 211 } 212 rowsAdded(n0, n); 213 } 214 } 215 } 216 217 private void addJarFiles(File files[]) { 218 final int n = files.length; 219 if (n > 0) { 220 classpathTable.clearSelection(); 221 final int n0 = classpathModel.size(); 222 for (int i = 0; i < n; i++) { 223 String pathInEAR; 224 if (files[i].isDirectory()) { 225 pathInEAR = VisualClassPathItem.PATH_IN_EAR_NONE; 226 } else { 227 pathInEAR = VisualClassPathItem.PATH_IN_WAR_LIB; 228 } 229 classpathModel.add(VisualClassPathItem.createJAR(files[i], null, pathInEAR)); 230 } 231 rowsAdded(n0, n); 232 } 233 } 234 235 private void addArtifacts(AntArtifact artifacts[]) { 236 final int n = artifacts.length; 237 if (n > 0) { 238 classpathTable.clearSelection(); 239 final int n0 = classpathModel.size(); 240 for (int i = 0; i < n; i++) { 241 classpathModel.add(VisualClassPathItem.createArtifact(artifacts[i], null, VisualClassPathItem.PATH_IN_WAR_LIB)); 242 } 243 rowsAdded(n0, n); 244 } 245 } 246 247 private void rowsAdded(int n0, int n) { 248 classpathModel.fireTableRowsInserted(n0, n0 + n - 1); 249 classpathTable.addRowSelectionInterval(n0, n0 + n - 1); 250 fireActionPerformed(); 251 } 252 253 private void removeSelectedItems() { 254 ListSelectionModel sm = classpathTable.getSelectionModel(); 255 if (sm.isSelectionEmpty()) { 256 assert false : "Remove button should be disabled"; } 258 int index = sm.getMinSelectionIndex(); 259 Collection elements = new ArrayList (); 260 final int n0 = classpathModel.size(); 261 for (int i = n0 - 1; i >=0; i--) { 262 if (sm.isSelectedIndex(i) && !isBaseLibraryItem(classpathModel.get(i))) { 263 classpathModel.remove(i); 264 } 265 } 266 final int n = classpathModel.size(); 267 classpathModel.fireTableRowsDeleted(elements.size(), n0 - 1); 268 if (index >= n) { 269 index = n - 1; 270 } 271 sm.setSelectionInterval(index, index); 272 273 fireActionPerformed(); 274 } 275 276 private void moveUp() { 277 int[] si = classpathTable.getSelectedRows(); 278 279 if (si == null || si.length == 0 || si[0] == 0) { 280 assert false : "MoveUp button should be disabled"; } 282 283 classpathTable.clearSelection(); 285 for (int i = 0; i < si.length; i++) { 286 final int index = si[i] - 1; 287 classpathModel.add(index, classpathModel.remove(index + 1)); 288 classpathTable.addRowSelectionInterval(index, index); 289 } 290 291 fireActionPerformed(); 292 } 293 294 private void moveDown() { 295 int[] si = classpathTable.getSelectedRows(); 296 297 if (si == null || si.length == 0 || si[si.length - 1] >= (classpathModel.size() - 1)) { 298 assert false : "MoveUp button should be disabled"; } 300 301 classpathTable.clearSelection(); 303 for( int i = si.length - 1; i >= 0; i-- ) { 304 final int index = si[i] + 1; 305 classpathModel.add( index, classpathModel.remove( index - 1 ) ); 306 classpathTable.addRowSelectionInterval(index, index); 307 } 308 309 fireActionPerformed(); 310 } 311 312 private void editLibrary() { 313 DefaultListSelectionModel sm = (DefaultListSelectionModel ) classpathTable.getSelectionModel(); 314 int index = sm.getMinSelectionIndex(); 315 if (sm.isSelectionEmpty()) { 316 assert false : "EditLibrary button should be disabled"; } 318 319 VisualClassPathItem item = classpathModel.get(index); 320 if (item.getType() == VisualClassPathItem.Type.LIBRARY) { 321 LibrariesCustomizer.showCustomizer((Library) item.getObject()); 322 } 323 324 fireActionPerformed(); 325 } 326 327 static Collection <Library> getLibrarySet(final Collection <String > libraryNames) { 328 final Collection <Library> librarySet = new HashSet <Library>(); 329 for (String libName : libraryNames) { 330 librarySet.add(LibraryManager.getDefault().getLibrary(libName)); 331 } 332 return librarySet; 333 } 334 335 private static boolean isBaseLibraryItem(final VisualClassPathItem item) { 336 return baseLibrarySet.contains(item.getObject()); 337 } 338 339 public static String getLibraryString(Library lib) { 340 final List content = lib.getContent("classpath"); StringBuilder sb = new StringBuilder (); 342 for (Iterator it = content.iterator(); it.hasNext();) { 343 if (sb.length() > 0) { 344 sb.append(';'); 345 } 346 sb.append(it.next().toString()); 347 } 348 String s = sb.toString(); 349 return s; 350 } 351 352 private static String getBundleResource(final String resourceName) { 353 return NbBundle.getMessage(VisualClasspathSupport.class, resourceName); 354 } 355 356 358 private class ClasspathSupportListener implements ActionListener , ListSelectionListener , TableModelListener { 359 360 363 public void actionPerformed( ActionEvent e ) { 364 Object source = e.getSource(); 365 366 if (source == addJarButton) { 367 JFileChooser chooser = new JFileChooser (); 369 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 370 chooser.setMultiSelectionEnabled( true ); 371 chooser.setDialogTitle(getBundleResource("LBL_AddJar_DialogTitle")); chooser.setAcceptAllFileFilterUsed( false ); 374 chooser.setFileFilter(new SimpleFileFilter(getBundleResource("LBL_ZipJarFolderFilter"), new String [] {"ZIP","JAR"})); 377 int option = chooser.showOpenDialog( null ); if (option == JFileChooser.APPROVE_OPTION) { 379 File files[] = chooser.getSelectedFiles(); 380 addJarFiles(files); 381 } 382 } else if ( source == addLibraryButton ) { 383 final LibrariesChooser panel = new LibrariesChooser(getLibraries(), j2eePlatform); 384 final JButton btnAddLibrary = new JButton (getBundleResource("LBL_AddLibrary")); Object [] options = new Object []{btnAddLibrary, DialogDescriptor.CANCEL_OPTION}; 386 final DialogDescriptor desc = new DialogDescriptor(panel, 387 getBundleResource("LBL_CustomizeCompile_Classpath_AddLibrary"), true, options, options[0], DialogDescriptor.DEFAULT_ALIGN, null, null); 389 final Dialog dlg = DialogDisplayer.getDefault().createDialog(desc); 390 panel.addListSelectionListener(new ListSelectionListener () { 391 public void valueChanged(ListSelectionEvent e) { 392 btnAddLibrary.setEnabled(panel.isValidSelection()); 393 } 394 }); 395 btnAddLibrary.setEnabled(panel.isValidSelection()); 396 dlg.setVisible(true); 397 if (desc.getValue() == options[0]) { 398 addLibraries(panel.getSelectedLibraries()); 399 } 400 dlg.dispose(); 401 } else if ( source == addArtifactButton ) { 402 AntArtifact artifacts[] = AntArtifactChooser.showDialog(master, 405 new String [] { 406 EjbProjectConstants.ARTIFACT_TYPE_J2EE_MODULE_IN_EAR_ARCHIVE, 407 WebProjectConstants.ARTIFACT_TYPE_WAR_EAR_ARCHIVE, 408 JavaProjectConstants.ARTIFACT_TYPE_JAR }); 409 if ( artifacts != null ) { 410 addArtifacts( artifacts ); 411 } 412 } else if ( source == removeButton ) { 413 removeSelectedItems(); 414 } else if ( source == upButton ) { 415 moveUp(); 416 } else if ( source == downButton ) { 417 moveDown(); 418 } else if ( source == editButton ) { 419 editLibrary(); 420 } 421 } 422 423 426 public void valueChanged( ListSelectionEvent e ) { 427 428 int[] si = classpathTable.getSelectedRows(); 429 430 432 434 436 boolean edit = false; 438 if (si != null && si.length > 0) { 439 for (int i = 0; i < si.length; i++) { 440 int index = si[i]; 441 final VisualClassPathItem item = classpathModel.get(index); 442 if(item.getType() != VisualClassPathItem.Type.LIBRARY && !isBaseLibraryItem(item)) { 443 edit = true; 444 break; 445 } 446 } 447 } 448 449 boolean remove = si != null && si.length > 0; 451 if ( remove ) { 453 for ( int i = 0; i < si.length; i++ ) { 454 final int index = si[i]; 455 assert index < classpathModel.size() : 456 "The selected indices " + Arrays.asList (Utilities.toObjectArray (si)) + " at " + i + " must fit into size of classpathModel" + classpathModel.size() ; VisualClassPathItem item = classpathModel.get( index ); 460 if ( !item.canDelete() || isBaseLibraryItem(item)) { 461 remove = false; 462 break; 463 } 464 } 465 } 466 467 boolean up = si != null && si.length > 0 && si[0] != 0; 470 471 boolean down = si != null && si.length > 0 && si[si.length-1] != classpathModel.size() - 1; 474 475 editButton.setEnabled( edit ); 476 removeButton.setEnabled( remove ); 477 upButton.setEnabled( up ); 478 downButton.setEnabled( down ); 479 } 480 481 public void tableChanged(TableModelEvent e) { 483 if (e.getColumn() == 1) { 484 VisualClassPathItem item = classpathModel.get(e.getFirstRow()); 485 if (classpathModel.getValueAt(e.getFirstRow(), 1) == Boolean.TRUE) { 486 item.setPathInEAR(VisualClassPathItem.PATH_IN_WAR_LIB); 487 } else { 488 item.setPathInEAR(VisualClassPathItem.PATH_IN_EAR_NONE); 489 } 490 491 fireActionPerformed(); 492 } 493 } 494 } 495 496 private static class LibraryCellRenderer extends DefaultTableCellRenderer { 497 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, 498 boolean hasFocus, int row, int column) { 499 final Object o; 500 if (value instanceof VisualClassPathItem) { 501 final VisualClassPathItem item = (VisualClassPathItem) value; 502 setIcon(item.getIcon()); 503 setEnabled(!isBaseLibraryItem(item)); 504 final String toolTipText = item.getToolTipText(); 505 setToolTipText(toolTipText); 506 o = item.toString(); 507 } else { 508 o = value; 509 } 510 return super.getTableCellRendererComponent(table, o, isSelected, false, row, column); 511 } 512 } 513 514 private static class BooleanCellRenderer implements TableCellRenderer { 515 private final TableCellRenderer booleanRenderer; 516 private final TableCellRenderer defaultRenderer; 517 518 public BooleanCellRenderer(JTable table) { 519 booleanRenderer = table.getDefaultRenderer(Boolean .class); 520 defaultRenderer = new DefaultTableCellRenderer (); 521 } 522 523 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, 524 boolean hasFocus, int row, int column) { 525 TableCellRenderer renderer = value instanceof Boolean ? booleanRenderer : defaultRenderer; 526 return renderer.getTableCellRendererComponent(table, value, isSelected, false, row, column); 527 } 528 } 529 530 class ClasspathTableModel extends AbstractTableModel { 531 int columnCount = 2; 532 533 ClasspathTableModel(boolean singleColumn) { 534 if (singleColumn) { 535 columnCount = 1; 536 } 537 } 538 539 private List <VisualClassPathItem> cpItems; 540 541 public int getColumnCount() { 542 return columnCount; } 544 545 public int getRowCount() { 546 return cpItems == null ? 0 : cpItems.size(); 547 } 548 549 public Object getValueAt(int row, int col) { 550 final VisualClassPathItem item = cpItems.get(row); 551 if(col == 0) { 552 return item; 553 } else { 554 return isInWar(item); 555 } 556 } 557 558 public VisualClassPathItem get(int row) { 559 return (VisualClassPathItem) getValueAt(row, 0); 560 } 561 562 public void setItem (int row, VisualClassPathItem item) { 563 cpItems.set(row, item); 564 fireTableCellUpdated(row, 0); 565 fireTableCellUpdated(row, 1); 566 } 567 568 public void add (VisualClassPathItem item) { 569 cpItems.add(item); 570 } 571 572 public void add (int index, VisualClassPathItem item) { 573 cpItems.add(index, item); 574 } 575 576 public VisualClassPathItem remove(int index) { 577 return cpItems.remove(index); 578 } 579 580 private Boolean isInWar(VisualClassPathItem item) { 581 Boolean isInWar; 582 final String pathInWAR = item.getPathInEAR(); 583 if (pathInWAR == null || pathInWAR.equals(VisualClassPathItem.PATH_IN_EAR_NONE)) { 584 if(isBaseLibraryItem(item) || (item.getType() == VisualClassPathItem.Type.JAR && 585 ((File ) item.getObject()).isDirectory())) { 586 isInWar = null; 587 } else { 588 isInWar = Boolean.FALSE; 589 } 590 } else { 591 isInWar = Boolean.TRUE; 592 } 593 return isInWar; 594 } 595 596 602 public Class getColumnClass(int c) { 603 if(c == 1) { 604 return Boolean .class; 605 } else { 606 return VisualClassPathItem.class; 607 } 608 } 609 610 public boolean isCellEditable(int row, int col) { 611 if (col == 1) { 612 return isInWar(classpathModel.get(row)) instanceof Boolean ; 613 } else { 614 return false; 615 } 616 } 617 618 public void setValueAt(Object value, int row, int col) { 619 if(col == 0) { 620 setItem(row, (VisualClassPathItem) value); 621 } else { 622 if (value instanceof Boolean ) { 623 (cpItems.get(row)).setPathInEAR(value == Boolean.TRUE ? 624 VisualClassPathItem.PATH_IN_WAR_LIB : VisualClassPathItem.PATH_IN_EAR_NONE); 625 fireTableCellUpdated(row, col); 626 } 627 } 628 } 629 630 public void setItems(List <VisualClassPathItem> items) { 631 cpItems = new ArrayList <VisualClassPathItem>(items); 632 fireTableDataChanged(); 633 } 634 635 public List <VisualClassPathItem> getItems() { 636 return new ArrayList <VisualClassPathItem>(cpItems); 637 638 } 639 640 public int size() { 641 return getRowCount(); 642 } 643 } 644 645 private static class SimpleFileFilter extends FileFilter { 646 private final String description; 647 private final Collection extensions; 648 649 public SimpleFileFilter(String description, String [] extensions) { 650 this.description = description; 651 this.extensions = Arrays.asList(extensions); 652 } 653 654 public boolean accept(File f) { 655 if (f.isDirectory()) { 656 return true; 657 } 658 String name = f.getName(); 659 int index = name.lastIndexOf('.'); if (index <= 0 || index==name.length()-1) { 661 return false; 662 } 663 String extension = name.substring(index+1).toUpperCase(); 664 return this.extensions.contains(extension); 665 } 666 667 public String getDescription() { 668 return this.description; 669 } 670 } 671 672 } 673 | Popular Tags |