Line 0
Link Here
|
|
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. |
5 |
* |
6 |
* The contents of this file are subject to the terms of either the GNU |
7 |
* General Public License Version 2 only ("GPL") or the Common |
8 |
* Development and Distribution License("CDDL") (collectively, the |
9 |
* "License"). You may not use this file except in compliance with the |
10 |
* License. You can obtain a copy of the License at |
11 |
* http://www.netbeans.org/cddl-gplv2.html |
12 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
13 |
* specific language governing permissions and limitations under the |
14 |
* License. When distributing the software, include this License Header |
15 |
* Notice in each file and include the License file at |
16 |
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this |
17 |
* particular file as subject to the "Classpath" exception as provided |
18 |
* by Sun in the GPL Version 2 section of the License file that |
19 |
* accompanied this code. If applicable, add the following below the |
20 |
* License Header, with the fields enclosed by brackets [] replaced by |
21 |
* your own identifying information: |
22 |
* "Portions Copyrighted [year] [name of copyright owner]" |
23 |
* |
24 |
* Contributor(s): |
25 |
* |
26 |
* The Original Software is NetBeans. The Initial Developer of the Original |
27 |
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun |
28 |
* Microsystems, Inc. All Rights Reserved. |
29 |
* |
30 |
* If you wish your version of this file to be governed by only the CDDL |
31 |
* or only the GPL Version 2, indicate your decision by adding |
32 |
* "[Contributor] elects to include this software in this distribution |
33 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
34 |
* single choice of license, a recipient has the option to distribute |
35 |
* your version of this file under either the CDDL, the GPL Version 2 or |
36 |
* to extend the choice of license to its licensees as provided above. |
37 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
38 |
* Version 2 license, then the option applies only if the new code is |
39 |
* made subject to such option by the copyright holder. |
40 |
*/ |
41 |
|
42 |
package org.netbeans.modules.java.api.common.ui; |
43 |
|
44 |
import java.awt.Component; |
45 |
import java.beans.PropertyChangeEvent; |
46 |
import java.beans.PropertyChangeListener; |
47 |
import java.text.MessageFormat; |
48 |
import java.util.ArrayList; |
49 |
import java.util.List; |
50 |
import java.util.Set; |
51 |
import java.util.TreeSet; |
52 |
import java.util.logging.Logger; |
53 |
import javax.swing.AbstractListModel; |
54 |
import javax.swing.ComboBoxModel; |
55 |
import javax.swing.JButton; |
56 |
import javax.swing.JList; |
57 |
import javax.swing.ListCellRenderer; |
58 |
import javax.swing.event.ListDataEvent; |
59 |
import javax.swing.event.ListDataListener; |
60 |
import org.netbeans.api.java.platform.JavaPlatform; |
61 |
import org.netbeans.api.java.platform.JavaPlatformManager; |
62 |
import org.netbeans.api.java.platform.Specification; |
63 |
import org.netbeans.modules.java.api.common.ant.UpdateHelper; |
64 |
import org.netbeans.spi.project.support.ant.EditableProperties; |
65 |
import org.openide.DialogDisplayer; |
66 |
import org.openide.NotifyDescriptor; |
67 |
import org.openide.awt.HtmlRenderer; |
68 |
import org.openide.modules.SpecificationVersion; |
69 |
import org.openide.util.NbBundle; |
70 |
import org.openide.util.Parameters; |
71 |
import org.openide.util.WeakListeners; |
72 |
import org.w3c.dom.Element; |
73 |
import org.w3c.dom.NodeList; |
74 |
|
75 |
/** |
76 |
* Support class for {@link JavaPlatform} manipulation in project customizer. |
77 |
* @author Tomas Zezula, Tomas Mysik |
78 |
*/ |
79 |
public final class PlatformUiSupport { |
80 |
|
81 |
/** |
82 |
* Enum used for specifying minimal version of the source level. Currently, only JDK 5 is supported. |
83 |
* @see PlatformUiSupport#createSourceLevelComboBoxModel(ComboBoxModel, String, String, String) |
84 |
*/ |
85 |
public enum JDK { VERSION_5 } |
86 |
|
87 |
private static final SpecificationVersion JDK_1_5 = new SpecificationVersion("1.5"); //NOI18N |
88 |
private static final SpecificationVersion JDK_1_6 = new SpecificationVersion("1.6"); //NOI18N |
89 |
private static final Logger LOGGER = Logger.getLogger(PlatformUiSupport.class.getName()); |
90 |
|
91 |
private PlatformUiSupport() { |
92 |
} |
93 |
|
94 |
/** |
95 |
* Create a {@link ComboBoxModel} of Java platforms. |
96 |
* The model listens on the {@link JavaPlatformManager} and update its |
97 |
* state according to the changes. |
98 |
* @param activePlatform the active project's platform, can be <code>null</code>. |
99 |
* @return {@link ComboBoxModel}. |
100 |
*/ |
101 |
public static ComboBoxModel createPlatformComboBoxModel(String activePlatform) { |
102 |
return new PlatformComboBoxModel(activePlatform); |
103 |
} |
104 |
|
105 |
|
106 |
/** |
107 |
* Create a {@link ListCellRenderer} for rendering items of the {@link ComboBoxModel} |
108 |
* created by the {@link PlatformUiSupport#createPlatformComboBoxModel(String)} method. |
109 |
* @return {@link ListCellRenderer}. |
110 |
*/ |
111 |
public static ListCellRenderer createPlatformListCellRenderer() { |
112 |
return new PlatformListCellRenderer(); |
113 |
} |
114 |
|
115 |
/** |
116 |
* Like {@link #storePlatform(EditableProperties, UpdateHelper, Object, Object)}, but platform name may be |
117 |
* <code>null</code> (in such case the default platform is used). |
118 |
* @param props project's shared properties. |
119 |
* @param helper {@link UpdateHelper} that is capable to upgrade project metadata if needed. |
120 |
* @param projectConfigurationNamespace project configuration namespace. |
121 |
* @param platformName platform name to store, can be <code>null</code>. |
122 |
* @param sourceLevel specification version to store. |
123 |
*/ |
124 |
public static void storePlatform(EditableProperties props, UpdateHelper helper, |
125 |
String projectConfigurationNamespace, String platformName, SpecificationVersion sourceLevel) { |
126 |
Parameters.notNull("props", props); //NOI18N |
127 |
Parameters.notNull("helper", helper); //NOI18N |
128 |
Parameters.notNull("projectConfigurationNamespace", projectConfigurationNamespace); //NOI18N |
129 |
Parameters.notNull("sourceLevel", sourceLevel); //NOI18N |
130 |
|
131 |
PlatformKey platformKey; |
132 |
if (platformName != null) { |
133 |
platformKey = new PlatformKey(PlatformUiSupport.findPlatform(platformName)); |
134 |
} else { |
135 |
platformKey = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform()); |
136 |
} |
137 |
storePlatform(props, helper, projectConfigurationNamespace, platformKey, new SourceLevelKey(sourceLevel)); |
138 |
} |
139 |
|
140 |
/** |
141 |
* Stores active platform, <i>javac.source</i> and <i>javac.target</i> into the project's metadata. |
142 |
* @param props project's shared properties |
143 |
* @param helper {@link UpdateHelper} that is capable to upgrade project metadata if needed. |
144 |
* @param projectConfigurationNamespace project configuration namespace. |
145 |
* @param platformKey the {@link PlatformKey} got from the platform model. |
146 |
* @param sourceLevelKey {@link SourceLevelKey} representing source level; can be <code>null</code>. |
147 |
*/ |
148 |
public static void storePlatform(EditableProperties props, UpdateHelper helper, |
149 |
String projectConfigurationNamespace, Object platformKey, Object sourceLevelKey) { |
150 |
Parameters.notNull("props", props); //NOI18N |
151 |
Parameters.notNull("helper", helper); //NOI18N |
152 |
Parameters.notNull("projectConfigurationNamespace", projectConfigurationNamespace); //NOI18N |
153 |
Parameters.notNull("platformKey", platformKey); //NOI18N |
154 |
|
155 |
assert platformKey instanceof PlatformKey; |
156 |
|
157 |
final String javaPlatformKey = "platform.active"; //NOI18N |
158 |
final String javacSourceKey = "javac.source"; //NOI18N |
159 |
final String javacTargetKey = "javac.target"; //NOI18N |
160 |
|
161 |
PlatformKey pk = (PlatformKey) platformKey; |
162 |
JavaPlatform platform = getPlatform(pk); |
163 |
// null means active broken (unresolved) platform, no need to do anything |
164 |
if (platform == null) { |
165 |
return; |
166 |
} |
167 |
|
168 |
SpecificationVersion jdk13 = new SpecificationVersion("1.3"); //NOI18N |
169 |
String platformAntName = platform.getProperties().get("platform.ant.name"); //NOI18N |
170 |
assert platformAntName != null; |
171 |
props.put(javaPlatformKey, platformAntName); |
172 |
Element root = helper.getPrimaryConfigurationData(true); |
173 |
boolean changed = false; |
174 |
NodeList explicitPlatformNodes = |
175 |
root.getElementsByTagNameNS(projectConfigurationNamespace, "explicit-platform"); //NOI18N |
176 |
|
177 |
if (pk.isDefaultPlatform()) { |
178 |
if (explicitPlatformNodes.getLength() == 1) { |
179 |
root.removeChild(explicitPlatformNodes.item(0)); |
180 |
changed = true; |
181 |
} |
182 |
} else { |
183 |
Element explicitPlatform; |
184 |
switch (explicitPlatformNodes.getLength()) { |
185 |
case 0: |
186 |
explicitPlatform = root.getOwnerDocument().createElementNS( |
187 |
projectConfigurationNamespace, "explicit-platform"); //NOI18N |
188 |
NodeList sourceRootNodes = root.getElementsByTagNameNS( |
189 |
projectConfigurationNamespace, "source-roots"); //NOI18N |
190 |
assert sourceRootNodes.getLength() == 1 : "Broken project.xml file"; |
191 |
|
192 |
root.insertBefore(explicitPlatform, sourceRootNodes.item(0)); |
193 |
changed = true; |
194 |
break; |
195 |
case 1: |
196 |
explicitPlatform = (Element) explicitPlatformNodes.item(0); |
197 |
break; |
198 |
default: |
199 |
throw new AssertionError("Broken project.xml file"); |
200 |
} |
201 |
String explicitSourceAttrValue = explicitPlatform.getAttribute("explicit-source-supported"); //NOI18N |
202 |
if (jdk13.compareTo(platform.getSpecification().getVersion()) >= 0 |
203 |
&& !"false".equals(explicitSourceAttrValue)) { //NOI18N |
204 |
explicitPlatform.setAttribute("explicit-source-supported", "false"); //NOI18N |
205 |
changed = true; |
206 |
} else if (jdk13.compareTo(platform.getSpecification().getVersion()) < 0 |
207 |
&& !"true".equals(explicitSourceAttrValue)) { //NOI18N |
208 |
explicitPlatform.setAttribute("explicit-source-supported", "true"); //NOI18N |
209 |
changed = true; |
210 |
} |
211 |
} |
212 |
|
213 |
SpecificationVersion sourceLevel; |
214 |
if (sourceLevelKey == null) { |
215 |
sourceLevel = platform.getSpecification().getVersion(); |
216 |
} else { |
217 |
assert sourceLevelKey instanceof SourceLevelKey; |
218 |
sourceLevel = ((SourceLevelKey) sourceLevelKey).getSourceLevel(); |
219 |
} |
220 |
String javacSource = sourceLevel.toString(); |
221 |
String javacTarget = javacSource; |
222 |
|
223 |
//Issue #116490 |
224 |
// Customizer value | -source | -target |
225 |
// JDK 1.2 1.2 1.1 |
226 |
// JDK 1.3 1.3 1.1 |
227 |
// JDK 1.4 1.4 1.4 |
228 |
// JDK 5 1.5 1.5 |
229 |
// JDK 6 1.5 1.6 |
230 |
// JDK 7 1.7 1.7 - should bring a new language features |
231 |
if (jdk13.compareTo(sourceLevel) >= 0) { |
232 |
javacTarget = "1.1"; //NOI18N |
233 |
} else if (JDK_1_6.equals(sourceLevel)) { |
234 |
javacSource = JDK_1_5.toString(); |
235 |
} |
236 |
|
237 |
if (!javacSource.equals(props.getProperty(javacSourceKey))) { |
238 |
props.setProperty(javacSourceKey, javacSource); |
239 |
} |
240 |
if (!javacTarget.equals(props.getProperty(javacTargetKey))) { |
241 |
props.setProperty(javacTargetKey, javacTarget); |
242 |
} |
243 |
|
244 |
if (changed) { |
245 |
helper.putPrimaryConfigurationData(root, true); |
246 |
} |
247 |
} |
248 |
|
249 |
|
250 |
/** |
251 |
* Return a {@link JavaPlatform} for an item obtained from the ComboBoxModel created by |
252 |
* the {@link PlatformUiSupport#createPlatformComboBoxModel(String)} method. This method |
253 |
* can return <code>null</code> if the platform is broken. |
254 |
* @param platformKey an item obtained from {@link ComboBoxModel} created by |
255 |
* {@link PlatformUiSupport#createPlatformComboBoxModel(String)}. |
256 |
* @return {@link JavaPlatform} or <code>null</code> in case when platform is broken. |
257 |
* @throws IllegalArgumentException if the input parameter is not an object created by platform combobox model. |
258 |
*/ |
259 |
public static JavaPlatform getPlatform(Object platformKey) { |
260 |
Parameters.notNull("platformKey", platformKey); //NOI18N |
261 |
|
262 |
if (platformKey instanceof PlatformKey) { |
263 |
return getPlatform((PlatformKey) platformKey); |
264 |
} |
265 |
throw new IllegalArgumentException(); |
266 |
} |
267 |
|
268 |
/** |
269 |
* Create {@link ComboBoxModel} of source levels for active platform. |
270 |
* The model listens on the platform's {@link ComboBoxModel} and update its |
271 |
* state according to the changes. It is possible to define minimal JDK version. |
272 |
* @param platformComboBoxModel the platform's model used for listenning. |
273 |
* @param initialSourceLevel initial source level value. |
274 |
* @param initialTargetLevel initial target level value. |
275 |
* @param minimalJDKVersion minimal JDK version to be displayed. It can be <code>null</code> if all the JDK versions |
276 |
* should be displayed (typically for Java SE project). |
277 |
* @return {@link ComboBoxModel} of {@link SourceLevelKey}. |
278 |
* @see #createSourceLevelComboBoxModel(ComboBoxModel, String, String) |
279 |
*/ |
280 |
public static ComboBoxModel createSourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, |
281 |
String initialSourceLevel, String initialTargetLevel, JDK minimalJDKVersion) { |
282 |
Parameters.notNull("platformComboBoxModel", platformComboBoxModel); // NOI18N |
283 |
Parameters.notNull("initialSourceLevel", initialSourceLevel); // NOI18N |
284 |
Parameters.notNull("initialTargetLevel", initialTargetLevel); // NOI18N |
285 |
|
286 |
return new SourceLevelComboBoxModel(platformComboBoxModel, initialSourceLevel, initialTargetLevel, |
287 |
minimalJDKVersion); |
288 |
} |
289 |
|
290 |
/** |
291 |
* Exactly like {@link #createSourceLevelComboBoxModel(ComboBoxModel, String, String, JDK)} |
292 |
* but without any minimal JDK version. |
293 |
* @param platformComboBoxModel the platform's model used for listenning. |
294 |
* @param initialSourceLevel initial source level value. |
295 |
* @param initialTargetLevel initial target level value. |
296 |
* @return {@link ComboBoxModel} of {@link SourceLevelKey}. |
297 |
* @see #createSourceLevelComboBoxModel(ComboBoxModel, String, String, JDK) |
298 |
*/ |
299 |
public static ComboBoxModel createSourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, |
300 |
String initialSourceLevel, String initialTargetLevel) { |
301 |
Parameters.notNull("platformComboBoxModel", platformComboBoxModel); // NOI18N |
302 |
Parameters.notNull("initialSourceLevel", initialSourceLevel); // NOI18N |
303 |
Parameters.notNull("initialTargetLevel", initialTargetLevel); // NOI18N |
304 |
|
305 |
return new SourceLevelComboBoxModel(platformComboBoxModel, initialSourceLevel, initialTargetLevel, null); |
306 |
} |
307 |
|
308 |
/** |
309 |
* Create {@link ListCellRenderer} for source levels. This method could be used when highlighting |
310 |
* of illegal source levels is needed. |
311 |
* @return {@link ListCellRenderer} for source levels. |
312 |
*/ |
313 |
public static ListCellRenderer createSourceLevelListCellRenderer() { |
314 |
return new SourceLevelListCellRenderer(); |
315 |
} |
316 |
|
317 |
/** |
318 |
* This class represents a JavaPlatform in the {@link ListModel} |
319 |
* created by the {@link PlatformUiSupport#createPlatformComboBoxModel(String)} method. |
320 |
*/ |
321 |
private static final class PlatformKey implements Comparable { |
322 |
|
323 |
private String name; |
324 |
private JavaPlatform platform; |
325 |
|
326 |
/** |
327 |
* Create a PlatformKey for a broken platform. |
328 |
* @param name the ant name of the broken platform. |
329 |
*/ |
330 |
public PlatformKey(String name) { |
331 |
assert name != null; |
332 |
this.name = name; |
333 |
} |
334 |
|
335 |
/** |
336 |
* Create a PlatformKey for a platform. |
337 |
* @param platform the {@link JavaPlatform}. |
338 |
*/ |
339 |
public PlatformKey(JavaPlatform platform) { |
340 |
assert platform != null; |
341 |
this.platform = platform; |
342 |
} |
343 |
|
344 |
public int compareTo(Object o) { |
345 |
return this.getDisplayName().compareTo(((PlatformKey) o).getDisplayName()); |
346 |
} |
347 |
|
348 |
@Override |
349 |
public boolean equals(Object other) { |
350 |
if (other instanceof PlatformKey) { |
351 |
PlatformKey otherKey = (PlatformKey) other; |
352 |
boolean equals; |
353 |
if (this.platform == null) { |
354 |
equals = otherKey.platform == null; |
355 |
} else { |
356 |
equals = this.platform.equals(otherKey.platform); |
357 |
} |
358 |
return equals && otherKey.getDisplayName().equals(this.getDisplayName()); |
359 |
} |
360 |
return false; |
361 |
} |
362 |
|
363 |
@Override |
364 |
public int hashCode() { |
365 |
return getDisplayName().hashCode(); |
366 |
} |
367 |
|
368 |
@Override |
369 |
public String toString() { |
370 |
return getDisplayName(); |
371 |
} |
372 |
|
373 |
public synchronized String getDisplayName() { |
374 |
if (this.name == null) { |
375 |
this.name = this.platform.getDisplayName(); |
376 |
} |
377 |
return this.name; |
378 |
} |
379 |
|
380 |
public boolean isDefaultPlatform() { |
381 |
if (this.platform == null) { |
382 |
return false; |
383 |
} |
384 |
return this.platform.equals(JavaPlatformManager.getDefault().getDefaultPlatform()); |
385 |
} |
386 |
|
387 |
public boolean isBroken() { |
388 |
return this.platform == null; |
389 |
} |
390 |
} |
391 |
|
392 |
private static final class SourceLevelKey implements Comparable { |
393 |
|
394 |
private final SpecificationVersion sourceLevel; |
395 |
private final boolean broken; |
396 |
|
397 |
public SourceLevelKey(final SpecificationVersion sourceLevel) { |
398 |
this(sourceLevel, false); |
399 |
} |
400 |
|
401 |
public SourceLevelKey(final SpecificationVersion sourceLevel, final boolean broken) { |
402 |
assert sourceLevel != null : "Source level cannot be null"; |
403 |
this.sourceLevel = sourceLevel; |
404 |
this.broken = broken; |
405 |
} |
406 |
|
407 |
public SpecificationVersion getSourceLevel() { |
408 |
return this.sourceLevel; |
409 |
} |
410 |
|
411 |
public boolean isBroken() { |
412 |
return this.broken; |
413 |
} |
414 |
|
415 |
public int compareTo(final Object other) { |
416 |
assert other instanceof SourceLevelKey : "Illegal argument of SourceLevelKey.compareTo()"; |
417 |
SourceLevelKey otherKey = (SourceLevelKey) other; |
418 |
return this.sourceLevel.compareTo(otherKey.sourceLevel); |
419 |
} |
420 |
|
421 |
@Override |
422 |
public boolean equals(final Object other) { |
423 |
return (other instanceof SourceLevelKey) |
424 |
&& ((SourceLevelKey) other).sourceLevel.equals(this.sourceLevel); |
425 |
} |
426 |
|
427 |
@Override |
428 |
public int hashCode() { |
429 |
return this.sourceLevel.hashCode(); |
430 |
} |
431 |
|
432 |
@Override |
433 |
public String toString() { |
434 |
StringBuilder buffer = new StringBuilder(); |
435 |
if (this.broken) { |
436 |
buffer.append("Broken: "); //NOI18N |
437 |
} |
438 |
buffer.append(this.sourceLevel.toString()); |
439 |
return buffer.toString(); |
440 |
} |
441 |
|
442 |
public String getDisplayName() { |
443 |
String tmp = sourceLevel.toString(); |
444 |
if (JDK_1_5.compareTo(sourceLevel) <= 0) { |
445 |
tmp = tmp.replaceFirst("^1\\.([5-9]|\\d\\d+)$", "$1"); //NOI18N |
446 |
} |
447 |
return NbBundle.getMessage(PlatformUiSupport.class, "LBL_JDK", tmp); |
448 |
} |
449 |
} |
450 |
|
451 |
private static final class PlatformComboBoxModel extends AbstractListModel |
452 |
implements ComboBoxModel, PropertyChangeListener { |
453 |
private static final long serialVersionUID = 1L; |
454 |
|
455 |
private final JavaPlatformManager pm; |
456 |
private PlatformKey[] platformNamesCache; |
457 |
private String initialPlatform; |
458 |
private PlatformKey selectedPlatform; |
459 |
|
460 |
public PlatformComboBoxModel(String initialPlatform) { |
461 |
this.pm = JavaPlatformManager.getDefault(); |
462 |
this.pm.addPropertyChangeListener(WeakListeners.propertyChange(this, this.pm)); |
463 |
this.initialPlatform = initialPlatform; |
464 |
} |
465 |
|
466 |
public int getSize() { |
467 |
PlatformKey[] platformNames = getPlatformNames(); |
468 |
return platformNames.length; |
469 |
} |
470 |
|
471 |
public Object getElementAt(int index) { |
472 |
PlatformKey[] platformNames = getPlatformNames(); |
473 |
assert index >= 0 && index < platformNames.length; |
474 |
return platformNames[index]; |
475 |
} |
476 |
|
477 |
public Object getSelectedItem() { |
478 |
getPlatformNames(); // force setting of selectedPlatform if it is not already done |
479 |
return selectedPlatform; |
480 |
} |
481 |
|
482 |
public void setSelectedItem(Object obj) { |
483 |
selectedPlatform = (PlatformKey) obj; |
484 |
fireContentsChanged(this, -1, -1); |
485 |
} |
486 |
|
487 |
public void propertyChange(PropertyChangeEvent event) { |
488 |
if (JavaPlatformManager.PROP_INSTALLED_PLATFORMS.equals(event.getPropertyName())) { |
489 |
synchronized (this) { |
490 |
platformNamesCache = null; |
491 |
} |
492 |
fireContentsChanged(this, -1, -1); |
493 |
} |
494 |
} |
495 |
|
496 |
private synchronized PlatformKey[] getPlatformNames() { |
497 |
if (platformNamesCache == null) { |
498 |
JavaPlatform[] platforms = pm.getPlatforms(null, new Specification("j2se", null)); //NOI18N |
499 |
Set<PlatformKey> orderedNames = new TreeSet<PlatformKey>(); |
500 |
boolean activeFound = false; |
501 |
for (JavaPlatform platform : platforms) { |
502 |
if (platform.getInstallFolders().size() > 0) { |
503 |
PlatformKey pk = new PlatformKey(platform); |
504 |
orderedNames.add(pk); |
505 |
if (!activeFound && initialPlatform != null) { |
506 |
String antName = platform.getProperties().get("platform.ant.name"); //NOI18N |
507 |
if (initialPlatform.equals(antName)) { |
508 |
if (selectedPlatform == null) { |
509 |
selectedPlatform = pk; |
510 |
initialPlatform = null; |
511 |
} |
512 |
activeFound = true; |
513 |
} |
514 |
} |
515 |
} |
516 |
} |
517 |
if (!activeFound) { |
518 |
if (initialPlatform == null) { |
519 |
if (selectedPlatform == null || !orderedNames.contains(selectedPlatform)) { |
520 |
selectedPlatform = new PlatformKey(JavaPlatformManager.getDefault().getDefaultPlatform()); |
521 |
} |
522 |
} else { |
523 |
PlatformKey pk = new PlatformKey(initialPlatform); |
524 |
orderedNames.add(pk); |
525 |
if (selectedPlatform == null) { |
526 |
selectedPlatform = pk; |
527 |
} |
528 |
} |
529 |
} |
530 |
platformNamesCache = orderedNames.toArray(new PlatformKey[0]); |
531 |
} |
532 |
return platformNamesCache; |
533 |
} |
534 |
|
535 |
} |
536 |
|
537 |
private static final class PlatformListCellRenderer implements ListCellRenderer { |
538 |
|
539 |
private final ListCellRenderer delegate; |
540 |
|
541 |
public PlatformListCellRenderer() { |
542 |
delegate = HtmlRenderer.createRenderer(); |
543 |
} |
544 |
|
545 |
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, |
546 |
boolean cellHasFocus) { |
547 |
String name; |
548 |
if (value == null) { |
549 |
name = ""; //NOI18N |
550 |
} else { |
551 |
assert value instanceof PlatformKey : "Wrong model"; |
552 |
PlatformKey key = (PlatformKey) value; |
553 |
if (key.isBroken()) { |
554 |
name = "<html><font color=\"#A40000\">" //NOI18N |
555 |
+ NbBundle.getMessage( |
556 |
PlatformUiSupport.class, "TXT_BrokenPlatformFmt", key.getDisplayName()); |
557 |
} else { |
558 |
name = key.getDisplayName(); |
559 |
} |
560 |
} |
561 |
return delegate.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus); |
562 |
} |
563 |
} |
564 |
|
565 |
private static final class SourceLevelComboBoxModel extends AbstractListModel |
566 |
implements ComboBoxModel, ListDataListener { |
567 |
private static final long serialVersionUID = 1L; |
568 |
|
569 |
private static final String VERSION_PREFIX = "1."; // the version prefix // NOI18N |
570 |
private static final int INITIAL_VERSION_MINOR = 2; // 1.2 |
571 |
// if project is JAVA EE 5 show only 1.5 and higher |
572 |
private static final int INITIAL_VERSION_MINOR_JAVA_EE_5 = 5; // 1.5 |
573 |
|
574 |
private final ComboBoxModel platformComboBoxModel; |
575 |
private final JDK minimalJDKVersion; |
576 |
private SpecificationVersion selectedSourceLevel; |
577 |
private SpecificationVersion originalSourceLevel; |
578 |
private SourceLevelKey[] sourceLevelCache; |
579 |
private PlatformKey activePlatform; |
580 |
|
581 |
public SourceLevelComboBoxModel(ComboBoxModel platformComboBoxModel, String initialSourceLevel, |
582 |
String initialTargetLevel, JDK minimalJDKVersion) { |
583 |
this.platformComboBoxModel = platformComboBoxModel; |
584 |
activePlatform = (PlatformKey) this.platformComboBoxModel.getSelectedItem(); |
585 |
this.platformComboBoxModel.addListDataListener(this); |
586 |
if (initialSourceLevel != null && initialSourceLevel.length() > 0) { |
587 |
try { |
588 |
originalSourceLevel = new SpecificationVersion(initialSourceLevel); |
589 |
} catch (NumberFormatException nfe) { |
590 |
// if the javac.source has invalid value, do not preselect and log it. |
591 |
LOGGER.warning("Invalid javac.source: " + initialSourceLevel); |
592 |
} |
593 |
} |
594 |
if (initialTargetLevel != null && initialTargetLevel.length() > 0) { |
595 |
try { |
596 |
SpecificationVersion originalTargetLevel = new SpecificationVersion(initialTargetLevel); |
597 |
if (originalSourceLevel == null || originalSourceLevel.compareTo(originalTargetLevel)<0) { |
598 |
originalSourceLevel = originalTargetLevel; |
599 |
} |
600 |
} catch (NumberFormatException nfe) { |
601 |
// if the javac.target has invalid value, do not preselect and log it |
602 |
LOGGER.warning("Invalid javac.target: "+initialTargetLevel); |
603 |
} |
604 |
} |
605 |
selectedSourceLevel = originalSourceLevel; |
606 |
this.minimalJDKVersion = minimalJDKVersion; |
607 |
} |
608 |
|
609 |
public int getSize() { |
610 |
SourceLevelKey[] sLevels = getSourceLevels(); |
611 |
return sLevels.length; |
612 |
} |
613 |
|
614 |
public Object getElementAt(int index) { |
615 |
SourceLevelKey[] sLevels = getSourceLevels(); |
616 |
assert index >= 0 && index < sLevels.length; |
617 |
return sLevels[index]; |
618 |
} |
619 |
|
620 |
public Object getSelectedItem() { |
621 |
for (SourceLevelKey key : getSourceLevels()) { |
622 |
if (key.getSourceLevel().equals(selectedSourceLevel)) { |
623 |
return key; |
624 |
} |
625 |
} |
626 |
return null; |
627 |
} |
628 |
|
629 |
public void setSelectedItem(Object obj) { |
630 |
selectedSourceLevel = (obj == null ? null : ((SourceLevelKey) obj).getSourceLevel()); |
631 |
fireContentsChanged(this, -1, -1); |
632 |
} |
633 |
|
634 |
public void intervalAdded(ListDataEvent e) { |
635 |
} |
636 |
|
637 |
public void intervalRemoved(ListDataEvent e) { |
638 |
} |
639 |
|
640 |
public void contentsChanged(ListDataEvent e) { |
641 |
PlatformKey selectedPlatform = (PlatformKey) platformComboBoxModel.getSelectedItem(); |
642 |
JavaPlatform platform = getPlatform(selectedPlatform); |
643 |
if (platform != null) { |
644 |
SpecificationVersion version = platform.getSpecification().getVersion(); |
645 |
if (selectedSourceLevel != null |
646 |
&& selectedSourceLevel.compareTo(version) > 0 |
647 |
&& !shouldChangePlatform(selectedSourceLevel, version)) { |
648 |
// restore original |
649 |
platformComboBoxModel.setSelectedItem(activePlatform); |
650 |
return; |
651 |
} else { |
652 |
originalSourceLevel = null; |
653 |
} |
654 |
} |
655 |
activePlatform = selectedPlatform; |
656 |
resetCache(); |
657 |
} |
658 |
|
659 |
private void resetCache() { |
660 |
synchronized (this) { |
661 |
sourceLevelCache = null; |
662 |
} |
663 |
fireContentsChanged(this, -1, -1); |
664 |
} |
665 |
|
666 |
private SourceLevelKey[] getSourceLevels() { |
667 |
if (sourceLevelCache == null) { |
668 |
PlatformKey selectedPlatform = (PlatformKey) platformComboBoxModel.getSelectedItem(); |
669 |
JavaPlatform platform = getPlatform(selectedPlatform); |
670 |
List<SourceLevelKey> sLevels = new ArrayList<SourceLevelKey>(); |
671 |
// if platform == null => broken platform, the source level range is unknown |
672 |
// the source level combo box should be empty and disabled |
673 |
boolean selSourceLevelValid = false; |
674 |
if (platform != null) { |
675 |
SpecificationVersion version = platform.getSpecification().getVersion(); |
676 |
int index = INITIAL_VERSION_MINOR; |
677 |
// #71619 - source level lower than 1.5 won't be shown for Java EE 5 project |
678 |
if (minimalJDKVersion != null) { |
679 |
switch (minimalJDKVersion) { |
680 |
case VERSION_5: |
681 |
index = INITIAL_VERSION_MINOR_JAVA_EE_5; |
682 |
break; |
683 |
default: |
684 |
break; |
685 |
} |
686 |
} |
687 |
SpecificationVersion template = |
688 |
new SpecificationVersion(VERSION_PREFIX + Integer.toString(index++)); |
689 |
boolean origSourceLevelValid = false; |
690 |
|
691 |
while (template.compareTo(version) <= 0) { |
692 |
if (template.equals(originalSourceLevel)) { |
693 |
origSourceLevelValid = true; |
694 |
} |
695 |
if (template.equals(selectedSourceLevel)) { |
696 |
selSourceLevelValid = true; |
697 |
} |
698 |
sLevels.add(new SourceLevelKey(template)); |
699 |
template = new SpecificationVersion(VERSION_PREFIX + Integer.toString(index++)); |
700 |
} |
701 |
if (originalSourceLevel != null && !origSourceLevelValid) { |
702 |
if (originalSourceLevel.equals(selectedSourceLevel)) { |
703 |
selSourceLevelValid = true; |
704 |
} |
705 |
sLevels.add(new SourceLevelKey(originalSourceLevel, true)); |
706 |
} |
707 |
} |
708 |
sourceLevelCache = sLevels.toArray(new SourceLevelKey[sLevels.size()]); |
709 |
if (!selSourceLevelValid) { |
710 |
selectedSourceLevel = sourceLevelCache.length == 0 |
711 |
? null : sourceLevelCache[sourceLevelCache.length - 1].getSourceLevel(); |
712 |
} |
713 |
} |
714 |
return sourceLevelCache; |
715 |
} |
716 |
|
717 |
private boolean shouldChangePlatform(SpecificationVersion selectedSourceLevel, |
718 |
SpecificationVersion platformSourceLevel) { |
719 |
JButton changeOption = new JButton(NbBundle.getMessage(PlatformUiSupport.class, "CTL_ChangePlatform")); |
720 |
changeOption.getAccessibleContext().setAccessibleDescription( |
721 |
NbBundle.getMessage(PlatformUiSupport.class, "AD_ChangePlatform")); |
722 |
String message = MessageFormat.format( |
723 |
NbBundle.getMessage(PlatformUiSupport.class, "TXT_ChangePlatform"), |
724 |
new Object[] {selectedSourceLevel.toString(), platformSourceLevel.toString()}); |
725 |
return DialogDisplayer.getDefault().notify(new NotifyDescriptor( |
726 |
message, |
727 |
NbBundle.getMessage(PlatformUiSupport.class, "TXT_ChangePlatformTitle"), |
728 |
NotifyDescriptor.DEFAULT_OPTION, |
729 |
NotifyDescriptor.WARNING_MESSAGE, |
730 |
new Object[] { |
731 |
changeOption, |
732 |
NotifyDescriptor.CANCEL_OPTION |
733 |
}, |
734 |
changeOption)) == changeOption; |
735 |
} |
736 |
} |
737 |
|
738 |
private static final class SourceLevelListCellRenderer implements ListCellRenderer { |
739 |
|
740 |
private ListCellRenderer delegate; |
741 |
|
742 |
public SourceLevelListCellRenderer() { |
743 |
delegate = HtmlRenderer.createRenderer(); |
744 |
} |
745 |
|
746 |
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, |
747 |
boolean cellHasFocus) { |
748 |
String message; |
749 |
if (value == null) { |
750 |
message = ""; //NOI18N |
751 |
} else { |
752 |
assert value instanceof SourceLevelKey; |
753 |
SourceLevelKey key = (SourceLevelKey) value; |
754 |
if (key.isBroken()) { |
755 |
message = "<html><font color=\"#A40000\">" //NOI18N |
756 |
+ NbBundle.getMessage( |
757 |
PlatformUiSupport.class, "TXT_InvalidSourceLevel", key.getDisplayName()); |
758 |
} else { |
759 |
message = key.getDisplayName(); |
760 |
} |
761 |
} |
762 |
return delegate.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus); |
763 |
} |
764 |
} |
765 |
|
766 |
private static JavaPlatform getPlatform(PlatformKey platformKey) { |
767 |
return platformKey.platform; |
768 |
} |
769 |
|
770 |
private static JavaPlatform findPlatform(String displayName) { |
771 |
JavaPlatform[] platforms = JavaPlatformManager.getDefault().getPlatforms( |
772 |
displayName, new Specification("j2se", null)); //NOI18N |
773 |
if (platforms.length == 0) { |
774 |
return null; |
775 |
} |
776 |
return platforms[0]; |
777 |
} |
778 |
} |