1 19 20 package org.netbeans.modules.web.project.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.beans.BeanInfo ; 27 import java.io.File ; 28 import java.text.MessageFormat ; 29 import java.util.Arrays ; 30 import java.util.Collection ; 31 import java.util.HashMap ; 32 import java.util.HashSet ; 33 import java.util.Map ; 34 import java.util.Set ; 35 36 import javax.swing.ButtonModel ; 37 import javax.swing.DefaultListCellRenderer ; 38 import javax.swing.DefaultListModel ; 39 import javax.swing.Icon ; 40 import javax.swing.ImageIcon ; 41 import javax.swing.JButton ; 42 import javax.swing.JFileChooser ; 43 import javax.swing.JList ; 44 import javax.swing.JTable ; 45 import javax.swing.ListSelectionModel ; 46 import javax.swing.SwingUtilities ; 47 import javax.swing.event.ListSelectionEvent ; 48 import javax.swing.event.ListSelectionListener ; 49 import javax.swing.filechooser.FileFilter ; 50 import javax.swing.table.DefaultTableCellRenderer ; 51 import javax.swing.table.TableCellRenderer ; 52 import org.netbeans.api.project.ProjectUtils; 53 54 import org.openide.DialogDescriptor; 55 import org.openide.DialogDisplayer; 56 import org.openide.filesystems.FileObject; 57 import org.openide.filesystems.FileUtil; 58 import org.openide.filesystems.Repository; 59 import org.openide.loaders.DataFolder; 60 import org.openide.util.NbBundle; 61 import org.openide.util.Utilities; 62 63 import org.netbeans.api.java.project.JavaProjectConstants; 64 import org.netbeans.api.project.Project; 65 import org.netbeans.api.project.ProjectInformation; 66 import org.netbeans.modules.web.api.webmodule.WebModule; 67 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 68 69 import org.netbeans.modules.web.project.classpath.ClassPathSupport; 70 import org.netbeans.modules.web.project.ui.FoldersListSettings; 71 72 76 public class WebClassPathUi { 77 78 private WebClassPathUi() {} 79 80 82 84 public static class ClassPathListCellRenderer extends DefaultListCellRenderer { 85 86 private static String RESOURCE_ICON_JAR = "org/netbeans/modules/web/project/ui/resources/jar.gif"; private static String RESOURCE_ICON_LIBRARY = "org/netbeans/modules/web/project/ui/resources/libraries.gif"; private static String RESOURCE_ICON_ARTIFACT = "org/netbeans/modules/web/project/ui/resources/projectDependencies.gif"; private static String RESOURCE_ICON_CLASSPATH = "org/netbeans/modules/web/project/ui/resources/referencedClasspath.gif"; private static String RESOURCE_ICON_BROKEN_BADGE = "org/netbeans/modules/web/project/ui/resources/brokenProjectBadge.gif"; 92 93 private static ImageIcon ICON_JAR = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_JAR ) ); 94 private static ImageIcon ICON_FOLDER = null; 95 private static ImageIcon ICON_LIBRARY = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_LIBRARY ) ); 96 private static ImageIcon ICON_ARTIFACT = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_ARTIFACT ) ); 97 private static ImageIcon ICON_CLASSPATH = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_CLASSPATH ) ); 98 private static ImageIcon ICON_BROKEN_BADGE = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_BROKEN_BADGE ) ); 99 100 private static ImageIcon ICON_BROKEN_JAR; 101 private static ImageIcon ICON_BROKEN_LIBRARY; 102 private static ImageIcon ICON_BROKEN_ARTIFACT; 103 104 private PropertyEvaluator evaluator; 105 106 private static final Map WELL_KNOWN_PATHS_NAMES = new HashMap (); 108 static { 109 WELL_KNOWN_PATHS_NAMES.put( WebProjectProperties.JAVAC_CLASSPATH, NbBundle.getMessage( WebClassPathUi.class, "LBL_JavacClasspath_DisplayName" ) ); 110 WELL_KNOWN_PATHS_NAMES.put( WebProjectProperties.JAVAC_TEST_CLASSPATH, NbBundle.getMessage( WebClassPathUi.class,"LBL_JavacTestClasspath_DisplayName") ); 111 WELL_KNOWN_PATHS_NAMES.put( WebProjectProperties.RUN_TEST_CLASSPATH, NbBundle.getMessage( WebClassPathUi.class, "LBL_RunTestClasspath_DisplayName" ) ); 112 WELL_KNOWN_PATHS_NAMES.put( WebProjectProperties.BUILD_CLASSES_DIR, NbBundle.getMessage( WebClassPathUi.class, "LBL_BuildClassesDir_DisplayName" ) ); 113 WELL_KNOWN_PATHS_NAMES.put( WebProjectProperties.BUILD_TEST_CLASSES_DIR, NbBundle.getMessage (WebClassPathUi.class,"LBL_BuildTestClassesDir_DisplayName") ); 114 }; 115 116 public ClassPathListCellRenderer( PropertyEvaluator evaluator ) { 117 super(); 118 this.evaluator = evaluator; 119 } 120 121 public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 122 123 ClassPathSupport.Item item = (ClassPathSupport.Item)value; 124 125 super.getListCellRendererComponent( list, getDisplayName( item ), index, isSelected, cellHasFocus ); 126 setIcon( getIcon( item ) ); 127 setToolTipText( getToolTipText( item ) ); 128 129 return this; 130 } 131 132 133 private String getDisplayName( ClassPathSupport.Item item ) { 134 135 switch ( item.getType() ) { 136 137 case ClassPathSupport.Item.TYPE_LIBRARY: 138 if ( item.isBroken() ) { 139 return NbBundle.getMessage( WebClassPathUi.class, "LBL_MISSING_LIBRARY", getLibraryName( item ) ); 140 } 141 else { 142 return item.getLibrary().getDisplayName(); 143 } 144 case ClassPathSupport.Item.TYPE_CLASSPATH: 145 String name = (String )WELL_KNOWN_PATHS_NAMES.get( WebProjectProperties.getAntPropertyName( item.getReference() ) ); 146 return name == null ? item.getReference() : name; 147 case ClassPathSupport.Item.TYPE_ARTIFACT: 148 if ( item.isBroken() ) { 149 return NbBundle.getMessage( WebClassPathUi.class, "LBL_MISSING_PROJECT", getProjectName( item ) ); 150 } else { 151 Project p = item.getArtifact().getProject(); 152 String projectName; 153 ProjectInformation pi = ProjectUtils.getInformation(p); 154 projectName = pi.getDisplayName(); 155 return MessageFormat.format(NbBundle.getMessage(WebClassPathUi.class,"MSG_ProjectArtifactFormat"), new Object [] { 156 projectName, 157 item.getArtifactURI().toString() 158 }); 159 } 160 case ClassPathSupport.Item.TYPE_JAR: 161 if ( item.isBroken() ) { 162 return NbBundle.getMessage( WebClassPathUi.class, "LBL_MISSING_FILE", getFileRefName( item ) ); 163 } 164 else { 165 return item.getFile().getPath(); 166 } 167 } 168 169 return item.getReference(); } 171 172 static Icon getIcon( ClassPathSupport.Item item ) { 173 174 switch ( item.getType() ) { 175 176 case ClassPathSupport.Item.TYPE_LIBRARY: 177 if ( item.isBroken() ) { 178 if ( ICON_BROKEN_LIBRARY == null ) { 179 ICON_BROKEN_LIBRARY = new ImageIcon ( Utilities.mergeImages( ICON_LIBRARY.getImage(), ICON_BROKEN_BADGE.getImage(), 7, 7 ) ); 180 } 181 return ICON_BROKEN_LIBRARY; 182 } 183 else { 184 return ICON_LIBRARY; 185 } 186 case ClassPathSupport.Item.TYPE_ARTIFACT: 187 if ( item.isBroken() ) { 188 if ( ICON_BROKEN_ARTIFACT == null ) { 189 ICON_BROKEN_ARTIFACT = new ImageIcon ( Utilities.mergeImages( ICON_ARTIFACT.getImage(), ICON_BROKEN_BADGE.getImage(), 7, 7 ) ); 190 } 191 return ICON_BROKEN_ARTIFACT; 192 } 193 else { 194 Project p = item.getArtifact().getProject(); 195 if (p != null) { 196 ProjectInformation pi = ProjectUtils.getInformation(p); 197 return pi.getIcon(); 198 } 199 return ICON_ARTIFACT; 200 } 201 case ClassPathSupport.Item.TYPE_JAR: 202 if ( item.isBroken() ) { 203 if ( ICON_BROKEN_JAR == null ) { 204 ICON_BROKEN_JAR = new ImageIcon ( Utilities.mergeImages( ICON_JAR.getImage(), ICON_BROKEN_BADGE.getImage(), 7, 7 ) ); 205 } 206 return ICON_BROKEN_JAR; 207 } 208 else { 209 File file = item.getFile(); 210 return file.isDirectory() ? getFolderIcon() : ICON_JAR; 211 } 212 case ClassPathSupport.Item.TYPE_CLASSPATH: 213 return ICON_CLASSPATH; 214 215 } 216 217 return null; } 219 220 private String getToolTipText( ClassPathSupport.Item item ) { 221 if ( item.isBroken() && 222 ( item.getType() == ClassPathSupport.Item.TYPE_JAR || 223 item.getType() == ClassPathSupport.Item.TYPE_ARTIFACT ) ) { 224 return evaluator.evaluate( item.getReference() ); 225 } 226 227 return getDisplayName( item ); } 229 230 private static ImageIcon getFolderIcon() { 231 232 if ( ICON_FOLDER == null ) { 233 FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot(); 234 DataFolder dataFolder = DataFolder.findFolder( root ); 235 ICON_FOLDER = new ImageIcon ( dataFolder.getNodeDelegate().getIcon( BeanInfo.ICON_COLOR_16x16 ) ); 236 } 237 238 return ICON_FOLDER; 239 } 240 241 private String getProjectName( ClassPathSupport.Item item ) { 242 String ID = item.getReference(); 243 return ID.substring(12, ID.indexOf('.', 12)); } 246 247 private String getLibraryName( ClassPathSupport.Item item ) { 248 String ID = item.getReference(); 249 return ID.substring(7, ID.indexOf(".classpath")); } 252 253 private String getFileRefName( ClassPathSupport.Item item ) { 254 String ID = item.getReference(); 255 return ID.substring(17, ID.length()-1); 257 } 258 259 260 261 } 262 263 public static class ClassPathTableCellItemRenderer extends DefaultTableCellRenderer { 264 265 private ClassPathListCellRenderer renderer; 266 private TableCellRenderer booleanRenderer; 267 268 public ClassPathTableCellItemRenderer(PropertyEvaluator evaluator) { 269 renderer = new ClassPathListCellRenderer(evaluator); 270 } 271 272 public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) { 273 274 if (value instanceof ClassPathSupport.Item) { 275 ClassPathSupport.Item item = (ClassPathSupport.Item)value; 276 setIcon( renderer.getIcon( item ) ); 277 setToolTipText( renderer.getToolTipText( item ) ); 278 return super.getTableCellRendererComponent(table, renderer.getDisplayName( item ), isSelected, false, row, column); 279 } else { 280 if (value instanceof Boolean && booleanRenderer != null) 281 return booleanRenderer.getTableCellRendererComponent( table, value, isSelected, false, row, column ); 282 else { 283 setIcon( null ); 284 return super.getTableCellRendererComponent( table, value, isSelected, false, row, column ); 285 } 286 } 287 } 288 289 public void setBooleanRenderer(TableCellRenderer booleanRenderer) { 290 this.booleanRenderer = booleanRenderer; 291 } 292 } 293 294 public static class EditMediator implements ActionListener , ListSelectionListener { 295 296 private final Project project; 297 private final ListComponent list; 298 private final DefaultListModel listModel; 299 private final ListSelectionModel selectionModel; 300 private final ButtonModel addJar; 301 private final ButtonModel addLibrary; 302 private final ButtonModel addAntArtifact; 303 private final ButtonModel remove; 304 private final ButtonModel moveUp; 305 private final ButtonModel moveDown; 306 307 public EditMediator( Project project, 308 ListComponent list, 309 ButtonModel addJar, 310 ButtonModel addLibrary, 311 ButtonModel addAntArtifact, 312 ButtonModel remove, 313 ButtonModel moveUp, 314 ButtonModel moveDown, 315 boolean includeNewFilesInDeployment) { 316 317 319 this.list = list; 320 321 if ( !( list.getModel() instanceof DefaultListModel ) ) { 322 throw new IllegalArgumentException ( "The list's model has to be of class DefaultListModel" ); } 324 325 this.listModel = (DefaultListModel )list.getModel(); 326 this.selectionModel = list.getSelectionModel(); 327 328 this.addJar = addJar; 329 this.addLibrary = addLibrary; 330 this.addAntArtifact = addAntArtifact; 331 this.remove = remove; 332 this.moveUp = moveUp; 333 this.moveDown = moveDown; 334 335 this.project = project; 336 } 337 338 public static void register(Project project, 339 ListComponent list, 340 ButtonModel addJar, 341 ButtonModel addLibrary, 342 ButtonModel addAntArtifact, 343 ButtonModel remove, 344 ButtonModel moveUp, 345 ButtonModel moveDown, 346 boolean includeNewFilesInDeployment) { 347 348 EditMediator em = new EditMediator( project, 349 list, 350 addJar, 351 addLibrary, 352 addAntArtifact, 353 remove, 354 moveUp, 355 moveDown, 356 includeNewFilesInDeployment ); 357 358 addJar.addActionListener( em ); 360 addLibrary.addActionListener( em ); 361 addAntArtifact.addActionListener( em ); 362 remove.addActionListener( em ); 363 moveUp.addActionListener( em ); 364 moveDown.addActionListener( em ); 365 em.selectionModel.addListSelectionListener( em ); 367 em.valueChanged( null ); 369 } 370 371 373 375 public void actionPerformed( ActionEvent e ) { 376 377 Object source = e.getSource(); 378 379 if ( source == addJar ) { 380 JFileChooser chooser = new JFileChooser (); 382 FileUtil.preventFileChooserSymlinkTraversal(chooser, null); 383 chooser.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES ); 384 chooser.setMultiSelectionEnabled( true ); 385 chooser.setDialogTitle( NbBundle.getMessage( WebClassPathUi.class, "LBL_AddJar_DialogTitle" ) ); chooser.setAcceptAllFileFilterUsed( false ); 388 chooser.setFileFilter( new SimpleFileFilter( 389 NbBundle.getMessage( WebClassPathUi.class, "LBL_ZipJarFolderFilter" ), new String [] {"ZIP","JAR"} ) ); File curDir = FoldersListSettings.getDefault().getLastUsedClassPathFolder(); 392 chooser.setCurrentDirectory (curDir); 393 int option = chooser.showOpenDialog( SwingUtilities.getWindowAncestor( list.getComponent() ) ); 395 if ( option == JFileChooser.APPROVE_OPTION ) { 396 397 File files[] = chooser.getSelectedFiles(); 398 int[] newSelection = ClassPathUiSupport.addJarFiles( listModel, list.getSelectedIndices(), files); 399 list.setSelectedIndices( newSelection ); 400 curDir = FileUtil.normalizeFile(chooser.getCurrentDirectory()); 401 FoldersListSettings.getDefault().setLastUsedClassPathFolder(curDir); 402 } 403 } 404 else if ( source == addLibrary ) { 405 Set includedLibraries = new HashSet (); 406 for (int i=0; i< listModel.getSize(); i++) { 407 ClassPathSupport.Item item = (ClassPathSupport.Item) listModel.get(i); 408 if (item.getType() == ClassPathSupport.Item.TYPE_LIBRARY && !item.isBroken() ) { 409 includedLibraries.add( item.getLibrary() ); 410 } 411 } 412 Object [] options = new Object [] { 413 new JButton (NbBundle.getMessage (WebClassPathUi.class,"LBL_AddLibrary")), 414 DialogDescriptor.CANCEL_OPTION 415 }; 416 ((JButton )options[0]).setEnabled(false); 417 ((JButton )options[0]).getAccessibleContext().setAccessibleDescription (NbBundle.getMessage (WebClassPathUi.class,"AD_AddLibrary")); 418 419 WebModule wm = WebModule.getWebModule(project.getProjectDirectory()); 420 String j2eeVersion = wm.getJ2eePlatformVersion(); 421 LibrariesChooser panel = new LibrariesChooser ((JButton )options[0], j2eeVersion); 422 DialogDescriptor desc = new DialogDescriptor(panel,NbBundle.getMessage( WebClassPathUi.class, "LBL_CustomizeCompile_Classpath_AddLibrary" ), 423 true, options, options[0], DialogDescriptor.DEFAULT_ALIGN,null,null); 424 Dialog dlg = DialogDisplayer.getDefault().createDialog(desc); 425 dlg.setVisible(true); 426 if (desc.getValue() == options[0]) { 427 int[] newSelection = ClassPathUiSupport.addLibraries( listModel, list.getSelectedIndices(), panel.getSelectedLibraries(), includedLibraries); 428 list.setSelectedIndices( newSelection ); 429 } 430 dlg.dispose(); 431 } 432 else if ( source == addAntArtifact ) { 433 AntArtifactChooser.ArtifactItem artifactItems[] = AntArtifactChooser.showDialog(JavaProjectConstants.ARTIFACT_TYPE_JAR, project, list.getComponent().getParent()); 434 if (artifactItems != null) { 435 int[] newSelection = ClassPathUiSupport.addArtifacts( listModel, list.getSelectedIndices(), artifactItems); 436 list.setSelectedIndices( newSelection ); 437 } 438 } 439 else if ( source == remove ) { 440 int[] newSelection = ClassPathUiSupport.remove( listModel, list.getSelectedIndices() ); 441 list.setSelectedIndices( newSelection ); 442 } 443 else if ( source == moveUp ) { 444 int[] newSelection = ClassPathUiSupport.moveUp( listModel, list.getSelectedIndices() ); 445 list.setSelectedIndices( newSelection ); 446 } 447 else if ( source == moveDown ) { 448 int[] newSelection = ClassPathUiSupport.moveDown( listModel, list.getSelectedIndices() ); 449 list.setSelectedIndices( newSelection ); 450 } 451 } 452 453 454 456 public void valueChanged( ListSelectionEvent e ) { 457 458 boolean canRemove = false; 460 if ( selectionModel.getMinSelectionIndex() != -1 ) { 462 canRemove = true; 463 int iMin = selectionModel.getMinSelectionIndex(); 464 int iMax = selectionModel.getMinSelectionIndex(); 465 for ( int i = iMin; i <= iMax; i++ ) { 466 467 if ( selectionModel.isSelectedIndex( i ) ) { 468 ClassPathSupport.Item item = (ClassPathSupport.Item)listModel.get( i ); 469 if ( item.getType() == ClassPathSupport.Item.TYPE_CLASSPATH ) { 470 canRemove = false; 471 break; 472 } 473 } 474 } 475 } 476 477 remove.setEnabled( canRemove ); 482 moveUp.setEnabled( ClassPathUiSupport.canMoveUp( selectionModel ) ); 483 moveDown.setEnabled( ClassPathUiSupport.canMoveDown( selectionModel, listModel.getSize() ) ); 484 485 } 486 487 public interface ListComponent { 488 public Component getComponent(); 489 public int[] getSelectedIndices(); 490 public void setSelectedIndices(int[] indices); 491 public DefaultListModel getModel(); 492 public ListSelectionModel getSelectionModel(); 493 } 494 495 private static final class JListListComponent implements ListComponent { 496 private JList list; 497 498 public JListListComponent(JList list) { 499 this.list = list; 500 } 501 502 public Component getComponent() { 503 return list; 504 } 505 506 public int[] getSelectedIndices() { 507 return list.getSelectedIndices(); 508 } 509 510 public void setSelectedIndices(int[] indices) { 511 list.setSelectedIndices(indices); 512 } 513 514 public DefaultListModel getModel() { 515 return (DefaultListModel )list.getModel(); 516 } 517 518 public ListSelectionModel getSelectionModel() { 519 return list.getSelectionModel(); 520 } 521 } 522 523 private static final class JTableListComponent implements ListComponent { 524 private JTable table; 525 private DefaultListModel model; 526 527 public JTableListComponent(JTable table, DefaultListModel model) { 528 this.table = table; 529 this.model = model; 530 } 531 532 public Component getComponent() { 533 return table; 534 } 535 536 public int[] getSelectedIndices() { 537 return table.getSelectedRows(); 538 } 539 540 public void setSelectedIndices(int[] indices) { 541 table.clearSelection(); 542 for (int i = 0; i < indices.length; i++) { 543 table.addRowSelectionInterval(indices[i], indices[i]); 544 } 545 } 546 547 public DefaultListModel getModel() { 548 return model; 549 } 550 551 public ListSelectionModel getSelectionModel() { 552 return table.getSelectionModel(); 553 } 554 } 555 556 public static ListComponent createListComponent(JList list) { 557 return new JListListComponent(list); 558 } 559 560 public static ListComponent createListComponent(JTable table, DefaultListModel model) { 561 return new JTableListComponent(table, model); 562 } 563 } 564 565 private static class SimpleFileFilter extends FileFilter { 566 567 private String description; 568 private Collection extensions; 569 570 571 public SimpleFileFilter (String description, String [] extensions) { 572 this.description = description; 573 this.extensions = Arrays.asList(extensions); 574 } 575 576 public boolean accept(File f) { 577 if (f.isDirectory()) 578 return true; 579 String name = f.getName(); 580 int index = name.lastIndexOf('.'); if (index <= 0 || index==name.length()-1) 582 return false; 583 String extension = name.substring (index+1).toUpperCase(); 584 return this.extensions.contains(extension); 585 } 586 587 public String getDescription() { 588 return this.description; 589 } 590 } 591 592 } 593 | Popular Tags |