1 19 20 package org.netbeans.modules.java.j2seproject.ui.customizer; 21 22 import java.awt.Color ; 23 import java.awt.Component ; 24 import java.beans.PropertyChangeEvent ; 25 import java.beans.PropertyChangeListener ; 26 import java.text.MessageFormat ; 27 import java.util.ArrayList ; 28 import java.util.Arrays ; 29 import java.util.List ; 30 import java.util.Set ; 31 import java.util.TreeSet ; 32 import javax.swing.AbstractListModel ; 33 import javax.swing.ComboBoxModel ; 34 import javax.swing.DefaultComboBoxModel ; 35 import javax.swing.JButton ; 36 import javax.swing.JList ; 37 import javax.swing.ListCellRenderer ; 38 import javax.swing.event.ListDataEvent ; 39 import javax.swing.event.ListDataListener ; 40 import org.netbeans.api.java.platform.JavaPlatform; 41 import org.netbeans.api.java.platform.JavaPlatformManager; 42 import org.netbeans.api.java.platform.Specification; 43 import org.netbeans.modules.java.j2seproject.J2SEProjectType; 44 import org.netbeans.modules.java.j2seproject.UpdateHelper; 45 import org.netbeans.spi.project.support.ant.EditableProperties; 46 import org.openide.DialogDisplayer; 47 import org.openide.ErrorManager; 48 import org.openide.NotifyDescriptor; 49 import org.openide.awt.HtmlRenderer; 50 import org.openide.modules.SpecificationVersion; 51 import org.openide.util.NbBundle; 52 import org.openide.util.WeakListeners; 53 import org.w3c.dom.Element ; 54 import org.w3c.dom.NodeList ; 55 56 60 public class PlatformUiSupport { 61 62 63 private PlatformUiSupport() { 64 } 65 66 73 public static ComboBoxModel createPlatformComboBoxModel (String activePlatform) { 74 return new PlatformComboBoxModel (activePlatform); 75 } 76 77 78 83 public static ListCellRenderer createPlatformListCellRenderer () { 84 return new PlatformListCellRenderer (); 85 } 86 87 94 public static void storePlatform (EditableProperties props, UpdateHelper helper, Object platformKey, Object sourceLevelKey) { 95 assert platformKey instanceof PlatformKey; 96 PlatformKey pk = (PlatformKey) platformKey; 97 JavaPlatform platform = getPlatform(pk); 98 if (platform != null) { 100 SpecificationVersion jdk13 = new SpecificationVersion ("1.3"); String platformAntName = (String ) platform.getProperties().get("platform.ant.name"); assert platformAntName != null; 103 props.put(J2SEProjectProperties.JAVA_PLATFORM, platformAntName); 104 Element root = helper.getPrimaryConfigurationData(true); 105 boolean defaultPlatform = pk.isDefaultPlatform(); 106 boolean changed = false; 107 NodeList explicitPlatformNodes = root.getElementsByTagNameNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"explicit-platform"); if (defaultPlatform) { 109 if (explicitPlatformNodes.getLength()==1) { 110 root.removeChild(explicitPlatformNodes.item(0)); 111 changed = true; 112 } 113 } 114 else { 115 Element explicitPlatform; 116 switch (explicitPlatformNodes.getLength()) { 117 case 0: 118 explicitPlatform = root.getOwnerDocument().createElementNS(J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE, "explicit-platform"); NodeList sourceRootNodes = root.getElementsByTagNameNS (J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,"source-roots"); assert sourceRootNodes.getLength() == 1 : "Broken project.xml file"; root.insertBefore(explicitPlatform, sourceRootNodes.item(0)); 122 changed = true; 123 break; 124 case 1: 125 explicitPlatform = (Element )explicitPlatformNodes.item(0); 126 break; 127 default: 128 throw new AssertionError ("Broken project.xml file"); } 130 String explicitSourceAttrValue = explicitPlatform.getAttribute("explicit-source-supported"); if (jdk13.compareTo(platform.getSpecification().getVersion())>=0 && 132 !"false".equals(explicitSourceAttrValue)) { explicitPlatform.setAttribute("explicit-source-supported","false"); changed = true; 135 } 136 else if (jdk13.compareTo(platform.getSpecification().getVersion())<0 && 137 !"true".equals(explicitSourceAttrValue)) { explicitPlatform.setAttribute("explicit-source-supported","true"); changed = true; 140 } 141 } 142 143 SpecificationVersion sourceLevel; 144 if (sourceLevelKey == null) { 145 sourceLevel = platform.getSpecification().getVersion(); 146 } 147 else { 148 assert sourceLevelKey instanceof SourceLevelKey; 149 sourceLevel = ((SourceLevelKey)sourceLevelKey).getSourceLevel(); 150 } 151 String javacSource = sourceLevel.toString(); 152 String javacTarget = jdk13.compareTo(sourceLevel)>=0 ? "1.1" : javacSource; if (!javacSource.equals(props.getProperty(J2SEProjectProperties.JAVAC_SOURCE))) { 154 props.setProperty (J2SEProjectProperties.JAVAC_SOURCE, javacSource); 155 } 156 if (!javacTarget.equals(props.getProperty(J2SEProjectProperties.JAVAC_TARGET))) { 157 props.setProperty (J2SEProjectProperties.JAVAC_TARGET, javacTarget); 158 } 159 160 if (changed) { 161 helper.putPrimaryConfigurationData(root, true); 162 } 163 } 164 } 165 166 167 175 public static JavaPlatform getPlatform (Object platformKey) { 176 if (platformKey instanceof PlatformKey) { 177 return getPlatform ((PlatformKey)platformKey); 178 } 179 else { 180 throw new IllegalArgumentException (); 181 } 182 } 183 184 192 public static ComboBoxModel createSourceLevelComboBoxModel (ComboBoxModel platformComboBoxModel, String initialValue) { 193 return new SourceLevelComboBoxModel (platformComboBoxModel, initialValue); 194 } 195 196 197 public static ListCellRenderer createSourceLevelListCellRenderer () { 198 return new SourceLevelListCellRenderer (); 199 } 200 201 202 private static JavaPlatform getPlatform (PlatformKey platformKey) { 203 return platformKey.platform; 204 } 205 206 207 212 private static class PlatformKey implements Comparable { 213 214 private String name; 215 private JavaPlatform platform; 216 217 221 public PlatformKey (String name) { 222 assert name != null; 223 this.name = name; 224 } 225 226 230 public PlatformKey (JavaPlatform platform) { 231 assert platform != null; 232 this.platform = platform; 233 } 234 235 public int compareTo(Object o) { 236 return this.getDisplayName().compareTo(((PlatformKey)o).getDisplayName()); 237 } 238 239 public boolean equals (Object other) { 240 if (other instanceof PlatformKey) { 241 PlatformKey otherKey = (PlatformKey)other; 242 return (this.platform == null ? otherKey.platform == null : this.platform.equals(otherKey.platform)) && 243 otherKey.getDisplayName().equals (this.getDisplayName()); 244 } 245 else { 246 return false; 247 } 248 } 249 250 public int hashCode () { 251 return getDisplayName ().hashCode (); 252 } 253 254 public String toString () { 255 return getDisplayName (); 256 } 257 258 public synchronized String getDisplayName () { 259 if (this.name == null) { 260 this.name = this.platform.getDisplayName(); 261 } 262 return this.name; 263 } 264 265 public boolean isDefaultPlatform () { 266 if (this.platform == null) { 267 return false; 268 } 269 return this.platform.equals(JavaPlatformManager.getDefault().getDefaultPlatform()); 270 } 271 272 public boolean isBroken () { 273 return this.platform == null; 274 } 275 276 } 277 278 private static final class SourceLevelKey implements Comparable { 279 280 final SpecificationVersion sourceLevel; 281 final boolean broken; 282 283 public SourceLevelKey (final SpecificationVersion sourceLevel) { 284 this (sourceLevel, false); 285 } 286 287 public SourceLevelKey (final SpecificationVersion sourceLevel, final boolean broken) { 288 assert sourceLevel != null : "Source level cannot be null"; this.sourceLevel = sourceLevel; 290 this.broken = broken; 291 } 292 293 public SpecificationVersion getSourceLevel () { 294 return this.sourceLevel; 295 } 296 297 public boolean isBroken () { 298 return this.broken; 299 } 300 301 public int compareTo (final Object other) { 302 assert other instanceof SourceLevelKey : "Illegal argument of SourceLevelKey.compareTo()"; SourceLevelKey otherKey = (SourceLevelKey) other; 304 return this.sourceLevel.compareTo(otherKey.sourceLevel); 305 } 306 307 public boolean equals (final Object other) { 308 return (other instanceof SourceLevelKey) && 309 ((SourceLevelKey)other).sourceLevel.equals(this.sourceLevel); 310 } 311 312 public int hashCode () { 313 return this.sourceLevel.hashCode(); 314 } 315 316 public String toString () { 317 StringBuffer buffer = new StringBuffer (); 318 if (this.broken) { 319 buffer.append("Broken: "); } 321 buffer.append(this.sourceLevel.toString()); 322 return buffer.toString(); 323 } 324 325 } 326 327 private static class PlatformComboBoxModel extends AbstractListModel implements ComboBoxModel , PropertyChangeListener { 328 329 private JavaPlatformManager pm; 330 private PlatformKey[] platformNamesCache; 331 private String initialPlatform; 332 private PlatformKey selectedPlatform; 333 334 public PlatformComboBoxModel (String initialPlatform) { 335 this.pm = JavaPlatformManager.getDefault(); 336 this.pm.addPropertyChangeListener(WeakListeners.propertyChange(this, this.pm)); 337 this.initialPlatform = initialPlatform; 338 } 339 340 public int getSize () { 341 PlatformKey[] platformNames = getPlatformNames (); 342 return platformNames.length; 343 } 344 345 public Object getElementAt (int index) { 346 PlatformKey[] platformNames = getPlatformNames (); 347 assert index >=0 && index< platformNames.length; 348 return platformNames[index]; 349 } 350 351 public Object getSelectedItem () { 352 this.getPlatformNames(); return this.selectedPlatform; 354 } 355 356 public void setSelectedItem (Object obj) { 357 this.selectedPlatform = (PlatformKey) obj; 358 this.fireContentsChanged(this, -1, -1); 359 } 360 361 public void propertyChange (PropertyChangeEvent event) { 362 if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(event.getPropertyName())) { 363 synchronized (this) { 364 this.platformNamesCache = null; 365 } 366 this.fireContentsChanged(this, -1, -1); 367 } 368 } 369 370 private synchronized PlatformKey[] getPlatformNames () { 371 if (this.platformNamesCache == null) { 372 JavaPlatform[] platforms = pm.getPlatforms (null, new Specification("j2se",null)); JavaPlatform defaultPlatform = pm.getDefaultPlatform (); 374 Set orderedNames = new TreeSet (); 375 boolean activeFound = false; 376 for (int i=0; i< platforms.length; i++) { 377 if (platforms[i].getInstallFolders().size()>0) { 378 PlatformKey pk = new PlatformKey(platforms[i]); 379 orderedNames.add (pk); 380 if (!activeFound && initialPlatform != null) { 381 String antName = (String ) platforms[i].getProperties().get("platform.ant.name"); if (initialPlatform.equals(antName)) { 383 if (this.selectedPlatform == null) { 384 this.selectedPlatform = pk; 385 initialPlatform = null; 386 } 387 activeFound = true; 388 } 389 } 390 } 391 } 392 if (!activeFound) { 393 if (initialPlatform == null) { 394 if (this.selectedPlatform == null || !orderedNames.contains(this.selectedPlatform)) { 395 this.selectedPlatform = new PlatformKey (JavaPlatformManager.getDefault().getDefaultPlatform()); 396 } 397 } 398 else { 399 PlatformKey pk = new PlatformKey (this.initialPlatform); 400 orderedNames.add (pk); 401 if (this.selectedPlatform == null) { 402 this.selectedPlatform = pk; 403 } 404 } 405 } 406 this.platformNamesCache = (PlatformKey[]) orderedNames.toArray(new PlatformKey[orderedNames.size()]); 407 } 408 return this.platformNamesCache; 409 } 410 411 } 412 413 private static class PlatformListCellRenderer implements ListCellRenderer { 414 415 private ListCellRenderer delegate; 416 417 public PlatformListCellRenderer () { 418 this.delegate = HtmlRenderer.createRenderer (); 419 } 420 421 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 422 String name; 423 if (value == null) { 424 name = ""; } 426 else { 427 assert value instanceof PlatformKey : "Wrong model"; PlatformKey key = (PlatformKey) value; 429 if (key.isBroken()) { 430 name = "<html><font color=\"#A40000\">" + NbBundle.getMessage (PlatformUiSupport.class,"TXT_BrokenPlatformFmt", key.getDisplayName()); 432 } 433 else { 434 name = key.getDisplayName(); 435 } 436 } 437 return this.delegate.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus); 438 } 439 } 440 441 private static class SourceLevelComboBoxModel extends AbstractListModel implements ComboBoxModel , ListDataListener { 442 443 private static final String VERSION_PREFIX = "1."; private static final int INITIAL_VERSION_MINOR = 2; 446 private SpecificationVersion selectedSourceLevel; 447 private SpecificationVersion originalSourceLevel; 448 private SourceLevelKey[] sourceLevelCache; 449 private final ComboBoxModel platformComboBoxModel; 450 private PlatformKey activePlatform; 451 452 public SourceLevelComboBoxModel (ComboBoxModel platformComboBoxModel, String initialValue) { 453 this.platformComboBoxModel = platformComboBoxModel; 454 this.activePlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem(); 455 this.platformComboBoxModel.addListDataListener (this); 456 if (initialValue != null && initialValue.length()>0) { 457 try { 458 this.originalSourceLevel = this.selectedSourceLevel = new SpecificationVersion (initialValue); 459 } catch (NumberFormatException nfe) { 460 ErrorManager.getDefault().log("Invalid javac.source: "+initialValue); 462 } 463 } 464 } 465 466 public int getSize () { 467 SourceLevelKey[] sLevels = getSourceLevels (); 468 return sLevels.length; 469 } 470 471 public Object getElementAt (int index) { 472 SourceLevelKey[] sLevels = getSourceLevels (); 473 assert index >=0 && index< sLevels.length; 474 return sLevels[index]; 475 } 476 477 public Object getSelectedItem () { 478 SourceLevelKey[] keys = getSourceLevels (); 479 for (int i=0; i<keys.length; i++) { 480 if (keys[i].getSourceLevel().equals(this.selectedSourceLevel)) { 481 return keys[i]; 482 } 483 } 484 return null; 485 } 486 487 public void setSelectedItem (Object obj) { 488 this.selectedSourceLevel = (obj == null ? null : ((SourceLevelKey)obj).getSourceLevel()); 489 this.fireContentsChanged(this, -1, -1); 490 } 491 492 public void intervalAdded(ListDataEvent e) { 493 } 494 495 public void intervalRemoved(ListDataEvent e) { 496 } 497 498 public void contentsChanged(ListDataEvent e) { 499 PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem(); 500 JavaPlatform platform = getPlatform(selectedPlatform); 501 if (platform != null) { 502 SpecificationVersion version = platform.getSpecification().getVersion(); 503 if (this.selectedSourceLevel != null && this.selectedSourceLevel.compareTo(version)>0 && 504 !shouldChangePlatform (selectedSourceLevel, version)) { 505 this.platformComboBoxModel.setSelectedItem(this.activePlatform); 507 return; 508 } 509 else { 510 this.originalSourceLevel = null; 511 } 512 } 513 this.activePlatform = selectedPlatform; 514 resetCache (); 515 } 516 517 private void resetCache () { 518 synchronized (this) { 519 this.sourceLevelCache = null; 520 } 521 this.fireContentsChanged(this, -1, -1); 522 } 523 524 private SourceLevelKey[] getSourceLevels () { 525 if (this.sourceLevelCache == null) { 526 PlatformKey selectedPlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem(); 527 JavaPlatform platform = getPlatform(selectedPlatform); 528 List sLevels = new ArrayList (); 529 boolean selSourceLevelValid = false; 532 if (platform != null) { 533 SpecificationVersion version = platform.getSpecification().getVersion(); 534 int index = INITIAL_VERSION_MINOR; 535 SpecificationVersion template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++)); 536 boolean origSourceLevelValid = false; 537 538 while (template.compareTo(version)<=0) { 539 if (template.equals(this.originalSourceLevel)) { 540 origSourceLevelValid = true; 541 } 542 if (template.equals(this.selectedSourceLevel)) { 543 selSourceLevelValid = true; 544 } 545 sLevels.add (new SourceLevelKey (template)); 546 template = new SpecificationVersion (VERSION_PREFIX + Integer.toString (index++)); 547 } 548 if (this.originalSourceLevel != null && !origSourceLevelValid) { 549 if (originalSourceLevel.equals(this.selectedSourceLevel)) { 550 selSourceLevelValid = true; 551 } 552 sLevels.add (new SourceLevelKey(this.originalSourceLevel,true)); 553 } 554 } 555 this.sourceLevelCache = (SourceLevelKey[]) sLevels.toArray(new SourceLevelKey[sLevels.size()]); 556 if (!selSourceLevelValid) { 557 this.selectedSourceLevel = this.sourceLevelCache.length == 0 ? 558 null : this.sourceLevelCache[this.sourceLevelCache.length-1].getSourceLevel(); 559 } 560 } 561 return this.sourceLevelCache; 562 } 563 564 private static boolean shouldChangePlatform (SpecificationVersion selectedSourceLevel, SpecificationVersion platformSourceLevel) { 565 JButton changeOption = new JButton (NbBundle.getMessage(PlatformUiSupport.class, "CTL_ChangePlatform")); 566 changeOption.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(PlatformUiSupport.class, "AD_ChangePlatform")); 567 String message = MessageFormat.format (NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatform"),new Object [] { 568 selectedSourceLevel.toString(), 569 platformSourceLevel.toString(), 570 }); 571 return DialogDisplayer.getDefault().notify( 572 new NotifyDescriptor (message, 573 NbBundle.getMessage(PlatformUiSupport.class,"TXT_ChangePlatformTitle"), 574 NotifyDescriptor.DEFAULT_OPTION, 575 NotifyDescriptor.WARNING_MESSAGE, 576 new Object [] { 577 changeOption, 578 NotifyDescriptor.CANCEL_OPTION 579 }, 580 changeOption)) == changeOption; 581 } 582 } 583 584 private static class SourceLevelListCellRenderer implements ListCellRenderer { 585 586 ListCellRenderer delegate; 587 588 public SourceLevelListCellRenderer () { 589 this.delegate = HtmlRenderer.createRenderer(); 590 } 591 592 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 593 String message; 594 if (value == null) { 595 message = ""; } 597 else { 598 assert value instanceof SourceLevelKey; 599 SourceLevelKey key = (SourceLevelKey) value; 600 if (key.isBroken()) { 601 message = "<html><font color=\"#A40000\">" + NbBundle.getMessage(PlatformUiSupport.class,"TXT_InvalidSourceLevel",key.getSourceLevel().toString()); 603 } 604 else { 605 message = key.getSourceLevel().toString(); 606 } 607 } 608 return this.delegate.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus); 609 } 610 } 611 612 } 613 | Popular Tags |