1 19 20 package org.netbeans.modules.java.j2seproject.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.Collections ; 32 import java.util.HashMap ; 33 import java.util.HashSet ; 34 import java.util.Iterator ; 35 import java.util.Map ; 36 import java.util.Set ; 37 import java.util.regex.Matcher ; 38 import java.util.regex.Pattern ; 39 import javax.swing.ButtonModel ; 40 import javax.swing.DefaultListCellRenderer ; 41 import javax.swing.DefaultListModel ; 42 import javax.swing.Icon ; 43 import javax.swing.ImageIcon ; 44 import javax.swing.JButton ; 45 import javax.swing.JFileChooser ; 46 import javax.swing.JList ; 47 import javax.swing.ListCellRenderer ; 48 import javax.swing.ListSelectionModel ; 49 import javax.swing.SwingUtilities ; 50 import javax.swing.event.ListSelectionEvent ; 51 import javax.swing.event.ListSelectionListener ; 52 import javax.swing.filechooser.FileFilter ; 53 import org.netbeans.api.java.project.JavaProjectConstants; 54 import org.netbeans.api.project.Project; 55 import org.netbeans.api.project.ProjectInformation; 56 import org.netbeans.api.project.ProjectUtils; 57 import org.netbeans.api.project.libraries.Library; 58 import org.netbeans.modules.java.j2seproject.classpath.ClassPathSupport; 59 import org.netbeans.modules.java.j2seproject.ui.FoldersListSettings; 60 import org.netbeans.spi.project.support.ant.AntProjectHelper; 61 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 62 import org.netbeans.spi.project.support.ant.ReferenceHelper; 63 import org.openide.DialogDescriptor; 64 import org.openide.DialogDisplayer; 65 import org.openide.filesystems.FileObject; 66 import org.openide.filesystems.FileUtil; 67 import org.openide.filesystems.Repository; 68 import org.openide.loaders.DataFolder; 69 import org.openide.util.NbBundle; 70 import org.openide.util.Utilities; 71 72 76 public class J2SEClassPathUi { 77 78 private J2SEClassPathUi() {} 79 80 82 84 public static class ClassPathListCellRenderer extends DefaultListCellRenderer { 85 86 private static final Pattern FOREIGN_PLAIN_FILE_REFERENCE = Pattern.compile("\\$\\{file\\.reference\\.([^${}]+)\\}"); private static final Pattern UNKNOWN_FILE_REFERENCE = Pattern.compile("\\$\\{([^${}]+)\\}"); 89 private static String RESOURCE_ICON_JAR = "org/netbeans/modules/java/j2seproject/ui/resources/jar.gif"; private static String RESOURCE_ICON_LIBRARY = "org/netbeans/modules/java/j2seproject/ui/resources/libraries.gif"; private static String RESOURCE_ICON_ARTIFACT = "org/netbeans/modules/java/j2seproject/ui/resources/projectDependencies.gif"; private static String RESOURCE_ICON_CLASSPATH = "org/netbeans/modules/java/j2seproject/ui/resources/referencedClasspath.gif"; private static String RESOURCE_ICON_BROKEN_BADGE = "org/netbeans/modules/java/j2seproject/ui/resources/brokenProjectBadge.gif"; 95 96 private static ImageIcon ICON_JAR = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_JAR ) ); 97 private static ImageIcon ICON_FOLDER = null; 98 private static ImageIcon ICON_LIBRARY = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_LIBRARY ) ); 99 private static ImageIcon ICON_ARTIFACT = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_ARTIFACT ) ); 100 private static ImageIcon ICON_CLASSPATH = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_CLASSPATH ) ); 101 private static ImageIcon ICON_BROKEN_BADGE = new ImageIcon ( Utilities.loadImage( RESOURCE_ICON_BROKEN_BADGE ) ); 102 103 private static ImageIcon ICON_BROKEN_JAR; 104 private static ImageIcon ICON_BROKEN_LIBRARY; 105 private static ImageIcon ICON_BROKEN_ARTIFACT; 106 107 private PropertyEvaluator evaluator; 108 109 private static final Map WELL_KNOWN_PATHS_NAMES = new HashMap (); 111 static { 112 WELL_KNOWN_PATHS_NAMES.put( J2SEProjectProperties.JAVAC_CLASSPATH, NbBundle.getMessage( J2SEProjectProperties.class, "LBL_JavacClasspath_DisplayName" ) ); 113 WELL_KNOWN_PATHS_NAMES.put( J2SEProjectProperties.JAVAC_TEST_CLASSPATH, NbBundle.getMessage( J2SEProjectProperties.class,"LBL_JavacTestClasspath_DisplayName") ); 114 WELL_KNOWN_PATHS_NAMES.put( J2SEProjectProperties.RUN_CLASSPATH, NbBundle.getMessage( J2SEProjectProperties.class, "LBL_RunClasspath_DisplayName" ) ); 115 WELL_KNOWN_PATHS_NAMES.put( J2SEProjectProperties.RUN_TEST_CLASSPATH, NbBundle.getMessage( J2SEProjectProperties.class, "LBL_RunTestClasspath_DisplayName" ) ); 116 WELL_KNOWN_PATHS_NAMES.put( J2SEProjectProperties.BUILD_CLASSES_DIR, NbBundle.getMessage( J2SEProjectProperties.class, "LBL_BuildClassesDir_DisplayName" ) ); 117 WELL_KNOWN_PATHS_NAMES.put( J2SEProjectProperties.BUILD_TEST_CLASSES_DIR, NbBundle.getMessage (J2SEProjectProperties.class,"LBL_BuildTestClassesDir_DisplayName") ); 118 }; 119 120 public ClassPathListCellRenderer( PropertyEvaluator evaluator ) { 121 super(); 122 this.evaluator = evaluator; 123 } 124 125 public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 126 127 ClassPathSupport.Item item = (ClassPathSupport.Item)value; 128 129 super.getListCellRendererComponent( list, getDisplayName( item ), index, isSelected, cellHasFocus ); 130 setIcon( getIcon( item ) ); 131 setToolTipText( getToolTipText( item ) ); 132 133 return this; 134 } 135 136 137 private String getDisplayName( ClassPathSupport.Item item ) { 138 139 switch ( item.getType() ) { 140 141 case ClassPathSupport.Item.TYPE_LIBRARY: 142 if ( item.isBroken() ) { 143 return NbBundle.getMessage( J2SEClassPathUi.class, "LBL_MISSING_LIBRARY", getLibraryName( item ) ); 144 } 145 else { 146 return item.getLibrary().getDisplayName(); 147 } 148 case ClassPathSupport.Item.TYPE_CLASSPATH: 149 String name = (String )WELL_KNOWN_PATHS_NAMES.get( ClassPathSupport.getAntPropertyName( item.getReference() ) ); 150 return name == null ? item.getReference() : name; 151 case ClassPathSupport.Item.TYPE_ARTIFACT: 152 if ( item.isBroken() ) { 153 return NbBundle.getMessage( J2SEClassPathUi.class, "LBL_MISSING_PROJECT", getProjectName( item ) ); 154 } 155 else { 156 Project p = item.getArtifact().getProject(); 157 ProjectInformation pi = ProjectUtils.getInformation(p); 158 String projectName = pi.getDisplayName(); 159 return MessageFormat.format (NbBundle.getMessage(J2SEClassPathUi.class,"MSG_ProjectArtifactFormat"), new Object [] { 160 projectName, 161 item.getArtifactURI().toString() 162 }); 163 } 164 case ClassPathSupport.Item.TYPE_JAR: 165 if ( item.isBroken() ) { 166 return NbBundle.getMessage( J2SEClassPathUi.class, "LBL_MISSING_FILE", getFileRefName( item ) ); 167 } 168 else { 169 return item.getFile().getPath(); 170 } 171 } 172 173 return item.getReference(); } 175 176 static Icon getIcon( ClassPathSupport.Item item ) { 177 178 switch ( item.getType() ) { 179 180 case ClassPathSupport.Item.TYPE_LIBRARY: 181 if ( item.isBroken() ) { 182 if ( ICON_BROKEN_LIBRARY == null ) { 183 ICON_BROKEN_LIBRARY = new ImageIcon ( Utilities.mergeImages( ICON_LIBRARY.getImage(), ICON_BROKEN_BADGE.getImage(), 7, 7 ) ); 184 } 185 return ICON_BROKEN_LIBRARY; 186 } 187 else { 188 return ICON_LIBRARY; 189 } 190 case ClassPathSupport.Item.TYPE_ARTIFACT: 191 if ( item.isBroken() ) { 192 if ( ICON_BROKEN_ARTIFACT == null ) { 193 ICON_BROKEN_ARTIFACT = new ImageIcon ( Utilities.mergeImages( ICON_ARTIFACT.getImage(), ICON_BROKEN_BADGE.getImage(), 7, 7 ) ); 194 } 195 return ICON_BROKEN_ARTIFACT; 196 } 197 else { 198 Project p = item.getArtifact().getProject(); 199 if (p != null) { 200 ProjectInformation pi = ProjectUtils.getInformation(p); 201 return pi.getIcon(); 202 } 203 return ICON_ARTIFACT; 204 } 205 case ClassPathSupport.Item.TYPE_JAR: 206 if ( item.isBroken() ) { 207 if ( ICON_BROKEN_JAR == null ) { 208 ICON_BROKEN_JAR = new ImageIcon ( Utilities.mergeImages( ICON_JAR.getImage(), ICON_BROKEN_BADGE.getImage(), 7, 7 ) ); 209 } 210 return ICON_BROKEN_JAR; 211 } 212 else { 213 File file = item.getFile(); 214 return file.isDirectory() ? getFolderIcon() : ICON_JAR; 215 } 216 case ClassPathSupport.Item.TYPE_CLASSPATH: 217 return ICON_CLASSPATH; 218 219 } 220 221 return null; } 223 224 private String getToolTipText( ClassPathSupport.Item item ) { 225 if ( item.isBroken() && 226 ( item.getType() == ClassPathSupport.Item.TYPE_JAR || 227 item.getType() == ClassPathSupport.Item.TYPE_ARTIFACT ) ) { 228 return evaluator.evaluate( item.getReference() ); 229 } 230 231 return getDisplayName( item ); } 233 234 private static ImageIcon getFolderIcon() { 235 236 if ( ICON_FOLDER == null ) { 237 FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot(); 238 DataFolder dataFolder = DataFolder.findFolder( root ); 239 ICON_FOLDER = new ImageIcon ( dataFolder.getNodeDelegate().getIcon( BeanInfo.ICON_COLOR_16x16 ) ); 240 } 241 242 return ICON_FOLDER; 243 } 244 245 private String getProjectName( ClassPathSupport.Item item ) { 246 String ID = item.getReference(); 247 return ID.substring(12, ID.indexOf(".", 12)); } 250 251 private String getLibraryName( ClassPathSupport.Item item ) { 252 String ID = item.getReference(); 253 return ID.substring(7, ID.indexOf(".classpath")); } 256 257 private String getFileRefName( ClassPathSupport.Item item ) { 258 String ID = item.getReference(); 259 Matcher m = FOREIGN_PLAIN_FILE_REFERENCE.matcher(ID); 261 if (m.matches()) { 262 return m.group(1); 263 } 264 m = UNKNOWN_FILE_REFERENCE.matcher(ID); 265 if (m.matches()) { 266 return m.group(1); 267 } 268 return ID; 269 } 270 271 272 273 } 274 275 276 public static class EditMediator implements ActionListener , ListSelectionListener { 277 278 private final Project project; 279 private final JList list; 280 private final DefaultListModel listModel; 281 private final ListSelectionModel selectionModel; 282 private final ButtonModel addJar; 283 private final ButtonModel addLibrary; 284 private final ButtonModel addAntArtifact; 285 private final ButtonModel remove; 286 private final ButtonModel moveUp; 287 private final ButtonModel moveDown; 288 289 public EditMediator( Project project, 290 JList list, 291 DefaultListModel listModel, 292 ButtonModel addJar, 293 ButtonModel addLibrary, 294 ButtonModel addAntArtifact, 295 ButtonModel remove, 296 ButtonModel moveUp, 297 ButtonModel moveDown ) { 298 299 301 this.list = list; 302 303 if ( !( list.getModel() instanceof DefaultListModel ) ) { 304 throw new IllegalArgumentException ( "The list's model has to be of class DefaultListModel" ); } 306 307 this.listModel = (DefaultListModel )list.getModel(); 308 this.selectionModel = list.getSelectionModel(); 309 310 this.addJar = addJar; 311 this.addLibrary = addLibrary; 312 this.addAntArtifact = addAntArtifact; 313 this.remove = remove; 314 this.moveUp = moveUp; 315 this.moveDown = moveDown; 316 317 this.project = project; 318 } 319 320 public static void register(Project project, 321 JList list, 322 DefaultListModel listModel, 323 ButtonModel addJar, 324 ButtonModel addLibrary, 325 ButtonModel addAntArtifact, 326 ButtonModel remove, 327 ButtonModel moveUp, 328 ButtonModel moveDown ) { 329 330 EditMediator em = new EditMediator( project, 331 list, 332 listModel, 333 addJar, 334 addLibrary, 335 addAntArtifact, 336 remove, 337 moveUp, 338 moveDown ); 339 340 addJar.addActionListener( em ); 342 addLibrary.addActionListener( em ); 343 addAntArtifact.addActionListener( em ); 344 remove.addActionListener( em ); 345 moveUp.addActionListener( em ); 346 moveDown.addActionListener( em ); 347 em.selectionModel.addListSelectionListener( em ); 349 em.valueChanged( null ); 351 } 352 353 355 357 public void actionPerformed( ActionEvent e ) { 358 359 Object source = e.getSource(); 360 361 if ( source == addJar ) { 362 JFileChooser chooser = new JFileChooser (); 364 FileUtil.preventFileChooserSymlinkTraversal(chooser, null); 365 chooser.setFileSelectionMode( JFileChooser.FILES_AND_DIRECTORIES ); 366 chooser.setMultiSelectionEnabled( true ); 367 chooser.setDialogTitle( NbBundle.getMessage( J2SEClassPathUi.class, "LBL_AddJar_DialogTitle" ) ); chooser.setAcceptAllFileFilterUsed( false ); 370 chooser.setFileFilter( new SimpleFileFilter( 371 NbBundle.getMessage( J2SEClassPathUi.class, "LBL_ZipJarFolderFilter" ), new String [] {"ZIP","JAR"} ) ); File curDir = FoldersListSettings.getDefault().getLastUsedClassPathFolder(); 374 chooser.setCurrentDirectory (curDir); 375 int option = chooser.showOpenDialog( SwingUtilities.getWindowAncestor( list ) ); 377 if ( option == JFileChooser.APPROVE_OPTION ) { 378 379 File files[] = chooser.getSelectedFiles(); 380 int[] newSelection = ClassPathUiSupport.addJarFiles( listModel, list.getSelectedIndices(), files ); 381 list.setSelectedIndices( newSelection ); 382 curDir = FileUtil.normalizeFile(chooser.getCurrentDirectory()); 383 FoldersListSettings.getDefault().setLastUsedClassPathFolder(curDir); 384 } 385 } 386 else if ( source == addLibrary ) { 387 Set includedLibraries = new HashSet (); 388 for (int i=0; i< listModel.getSize(); i++) { 389 ClassPathSupport.Item item = (ClassPathSupport.Item) listModel.get(i); 390 if (item.getType() == ClassPathSupport.Item.TYPE_LIBRARY && !item.isBroken() ) { 391 includedLibraries.add( item.getLibrary() ); 392 } 393 } 394 Object [] options = new Object [] { 395 new JButton (NbBundle.getMessage (J2SEClassPathUi.class,"LBL_AddLibrary")), 396 DialogDescriptor.CANCEL_OPTION 397 }; 398 ((JButton )options[0]).setEnabled(false); 399 ((JButton )options[0]).getAccessibleContext().setAccessibleDescription (NbBundle.getMessage (J2SEClassPathUi.class,"AD_AddLibrary")); 400 LibrariesChooser panel = new LibrariesChooser ((JButton )options[0], includedLibraries); 401 DialogDescriptor desc = new DialogDescriptor(panel,NbBundle.getMessage( J2SEClassPathUi.class, "LBL_CustomizeCompile_Classpath_AddLibrary" ), 402 true, options, options[0], DialogDescriptor.DEFAULT_ALIGN,null,null); 403 Dialog dlg = DialogDisplayer.getDefault().createDialog(desc); 404 dlg.setVisible(true); 405 if (desc.getValue() == options[0]) { 406 int[] newSelection = ClassPathUiSupport.addLibraries( listModel, list.getSelectedIndices(), panel.getSelectedLibraries(), includedLibraries ); 407 list.setSelectedIndices( newSelection ); 408 } 409 dlg.dispose(); 410 } 411 else if ( source == addAntArtifact ) { 412 AntArtifactChooser.ArtifactItem artifactItems[] = AntArtifactChooser.showDialog( 413 new String [] { JavaProjectConstants.ARTIFACT_TYPE_JAR, JavaProjectConstants.ARTIFACT_TYPE_FOLDER}, 414 project, list.getParent() ); 415 if (artifactItems != null) { 416 int[] newSelection = ClassPathUiSupport.addArtifacts( listModel, list.getSelectedIndices(), artifactItems); 417 list.setSelectedIndices( newSelection ); 418 } 419 } 420 else if ( source == remove ) { 421 int[] newSelection = ClassPathUiSupport.remove( listModel, list.getSelectedIndices() ); 422 list.setSelectedIndices( newSelection ); 423 } 424 else if ( source == moveUp ) { 425 int[] newSelection = ClassPathUiSupport.moveUp( listModel, list.getSelectedIndices() ); 426 list.setSelectedIndices( newSelection ); 427 } 428 else if ( source == moveDown ) { 429 int[] newSelection = ClassPathUiSupport.moveDown( listModel, list.getSelectedIndices() ); 430 list.setSelectedIndices( newSelection ); 431 } 432 } 433 434 435 437 public void valueChanged( ListSelectionEvent e ) { 438 439 boolean canRemove = false; 441 if ( selectionModel.getMinSelectionIndex() != -1 ) { 443 canRemove = true; 444 int iMin = selectionModel.getMinSelectionIndex(); 445 int iMax = selectionModel.getMinSelectionIndex(); 446 for ( int i = iMin; i <= iMax; i++ ) { 447 448 if ( selectionModel.isSelectedIndex( i ) ) { 449 ClassPathSupport.Item item = (ClassPathSupport.Item)listModel.get( i ); 450 if ( item.getType() == ClassPathSupport.Item.TYPE_CLASSPATH ) { 451 canRemove = false; 452 break; 453 } 454 } 455 } 456 } 457 458 remove.setEnabled( canRemove ); 463 moveUp.setEnabled( ClassPathUiSupport.canMoveUp( selectionModel ) ); 464 moveDown.setEnabled( ClassPathUiSupport.canMoveDown( selectionModel, listModel.getSize() ) ); 465 466 } 467 } 468 469 private static class SimpleFileFilter extends FileFilter { 470 471 private String description; 472 private Collection extensions; 473 474 475 public SimpleFileFilter (String description, String [] extensions) { 476 this.description = description; 477 this.extensions = Arrays.asList(extensions); 478 } 479 480 public boolean accept(File f) { 481 if (f.isDirectory()) 482 return true; 483 String name = f.getName(); 484 int index = name.lastIndexOf('.'); if (index <= 0 || index==name.length()-1) 486 return false; 487 String extension = name.substring (index+1).toUpperCase(); 488 return this.extensions.contains(extension); 489 } 490 491 public String getDescription() { 492 return this.description; 493 } 494 } 495 496 } 497 | Popular Tags |