001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU General
007: * Public License Version 2 only ("GPL") or the Common Development and Distribution
008: * License("CDDL") (collectively, the "License"). You may not use this file except in
009: * compliance with the License. You can obtain a copy of the License at
010: * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
011: * License for the specific language governing permissions and limitations under the
012: * License. When distributing the software, include this License Header Notice in
013: * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun
014: * designates this particular file as subject to the "Classpath" exception as
015: * provided by Sun in the GPL Version 2 section of the License file that
016: * accompanied this code. If applicable, add the following below the License Header,
017: * with the fields enclosed by brackets [] replaced by your own identifying
018: * information: "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Contributor(s):
021: *
022: * The Original Software is NetBeans. The Initial Developer of the Original Software
023: * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
024: * Rights Reserved.
025: *
026: * If you wish your version of this file to be governed by only the CDDL or only the
027: * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
028: * this software in this distribution under the [CDDL or GPL Version 2] license." If
029: * you do not indicate a single choice of license, a recipient has the option to
030: * distribute your version of this file under either the CDDL, the GPL Version 2 or
031: * to extend the choice of license to its licensees as provided above. However, if
032: * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
033: * the option applies only if the new code is made subject to such option by the
034: * copyright holder.
035: */
036:
037: package org.netbeans.installer.wizard.components.panels;
038:
039: import java.io.File;
040: import java.util.LinkedList;
041: import java.util.List;
042: import org.netbeans.installer.product.Registry;
043: import org.netbeans.installer.product.components.Product;
044: import org.netbeans.installer.product.dependencies.InstallAfter;
045: import org.netbeans.installer.product.filters.OrFilter;
046: import org.netbeans.installer.product.filters.ProductFilter;
047: import org.netbeans.installer.product.filters.RegistryFilter;
048: import org.netbeans.installer.utils.LogManager;
049: import org.netbeans.installer.utils.ResourceUtils;
050: import org.netbeans.installer.utils.StringUtils;
051: import org.netbeans.installer.utils.SystemUtils;
052: import org.netbeans.installer.utils.applications.JavaUtils;
053: import org.netbeans.installer.utils.exceptions.InitializationException;
054: import org.netbeans.installer.utils.helper.Dependency;
055: import org.netbeans.installer.utils.helper.Status;
056: import org.netbeans.installer.utils.helper.Version;
057: import org.netbeans.installer.utils.helper.Version.VersionDistance;
058: import org.netbeans.installer.wizard.components.actions.SearchForJavaAction;
059:
060: /**
061: *
062: * @author Kirill Sorokin
063: */
064: public class JdkLocationPanel extends ApplicationLocationPanel {
065: /////////////////////////////////////////////////////////////////////////////////
066: // Instance
067: private Version minimumVersion;
068: private Version maximumVersion;
069: private Version preferredVersion;
070: private String vendorAllowed;
071: private List<File> jdkLocations;
072: private List<String> jdkLabels;
073: private static File lastSelectedJava = null;
074:
075: public JdkLocationPanel() {
076: setProperty(MINIMUM_JDK_VERSION_PROPERTY,
077: DEFAULT_MINIMUM_JDK_VERSION);
078: setProperty(MAXIMUM_JDK_VERSION_PROPERTY,
079: DEFAULT_MAXIMUM_JDK_VERSION);
080: setProperty(VENDOR_JDK_ALLOWED_PROPERTY,
081: DEFAULT_VENDOR_JDK_ALLOWED);
082:
083: setProperty(LOCATION_LABEL_TEXT_PROPERTY,
084: DEFAULT_LOCATION_LABEL_TEXT);
085: setProperty(LOCATION_BUTTON_TEXT_PROPERTY,
086: DEFAULT_LOCATION_BUTTON_TEXT);
087: setProperty(LIST_LABEL_TEXT_PROPERTY, DEFAULT_LIST_LABEL_TEXT);
088:
089: setProperty(ERROR_NULL_PROPERTY, DEFAULT_ERROR_NULL);
090: setProperty(ERROR_NOT_VALID_PATH_PROPERTY,
091: DEFAULT_ERROR_NOT_VALID_PATH);
092: setProperty(ERROR_PATH_NOT_EXISTS_PROPERTY,
093: DEFAULT_ERROR_PATH_NOT_EXISTS);
094: setProperty(ERROR_NOT_JAVAHOME_PROPERTY,
095: DEFAULT_ERROR_NOT_JAVAHOME);
096: setProperty(ERROR_NOT_JDK_PROPERTY, DEFAULT_ERROR_NOT_JDK);
097: setProperty(ERROR_WRONG_VERSION_OLDER_PROPERTY,
098: DEFAULT_ERROR_WRONG_VERSION_OLDER);
099: setProperty(ERROR_WRONG_VERSION_NEWER_PROPERTY,
100: DEFAULT_ERROR_WRONG_VERSION_NEWER);
101: setProperty(ERROR_WRONG_VENDOR_PROPERTY,
102: DEFAULT_ERROR_WRONG_VENDOR);
103: setProperty(ERROR_UNKNOWN_PROPERTY, DEFAULT_ERROR_UNKNOWN);
104: setProperty(ERROR_NOTHING_FOUND_PROPERTY,
105: DEFAULT_ERROR_NOTHING_FOUND);
106:
107: setProperty(USEDBY_LABEL_PROPERTY, DEFAULT_USEDBY_LABEL);
108: }
109:
110: @Override
111: public void initialize() {
112: minimumVersion = Version
113: .getVersion(getProperty(MINIMUM_JDK_VERSION_PROPERTY));
114: maximumVersion = Version
115: .getVersion(getProperty(MAXIMUM_JDK_VERSION_PROPERTY));
116: vendorAllowed = getProperty(VENDOR_JDK_ALLOWED_PROPERTY);
117:
118: if (getProperty(PREFERRED_JDK_VERSION_PROPERTY) != null) {
119: preferredVersion = Version
120: .getVersion(getProperty(PREFERRED_JDK_VERSION_PROPERTY));
121: }
122:
123: addJavaLocationsFromProductDependencies();
124:
125: jdkLocations = new LinkedList<File>();
126: jdkLabels = new LinkedList<String>();
127:
128: final Registry registry = Registry.getInstance();
129: for (int i = 0; i < SearchForJavaAction.getJavaLocations()
130: .size(); i++) {
131: final File location = SearchForJavaAction
132: .getJavaLocations().get(i);
133:
134: String label = SearchForJavaAction.getJavaLabels().get(i);
135: Version version = null;
136:
137: // initialize the version; if the location exists, it must be an
138: // already installed jdk and we should fetch the version in a
139: // "traditional" way; otherwise the jdk is only planned for
140: // installation and we should try to get its version from the
141: // registry
142: if (location.exists()) {
143: version = JavaUtils.getVersion(location);
144: } else {
145: for (Product jdk : registry
146: .getProducts(JDK_PRODUCT_UID)) {
147: if ((jdk.getStatus() == Status.TO_BE_INSTALLED)
148: && jdk.getInstallationLocation().equals(
149: location)) {
150: version = jdk.getVersion();
151: }
152: }
153: }
154:
155: // if we could not fetch the version, we should skip this jdk
156: // installation
157: if (version == null) {
158: continue;
159: }
160:
161: // run through the installed and to-be-installed products and check
162: // whether this location is already used somewhere
163: final RegistryFilter filter = new OrFilter(
164: new ProductFilter(Status.INSTALLED),
165: new ProductFilter(Status.TO_BE_INSTALLED));
166: final List<Product> products = new LinkedList<Product>();
167: for (Product product : registry.queryProducts(filter)) {
168: final String jdk = product
169: .getProperty(JDK_LOCATION_PROPERTY);
170:
171: if ((jdk != null)
172: && jdk.equals(location.getAbsolutePath())) {
173: products.add(product);
174: }
175: }
176:
177: final Product product = (Product) getWizard().getContext()
178: .get(Product.class);
179:
180: if (products.contains(product)) {
181: products.remove(product);
182: }
183: if (products.size() > 0) {
184: label = StringUtils.format(
185: getProperty(USEDBY_LABEL_PROPERTY), label,
186: StringUtils.asString(products));
187: }
188:
189: // if the location exists and is a jdk installation (or if the
190: // location does not exist - in this case we're positive that it
191: // WILL be a jdk) and if version satisfies the requirements - add
192: // the location to the list
193: if ((!location.exists() || JavaUtils.isJdk(location))) {
194: String vendor = JavaUtils.getInfo(location).getVendor();
195:
196: if (!version.olderThan(minimumVersion)
197: && !version.newerThan(maximumVersion)
198: && vendor.matches(vendorAllowed)) {
199: jdkLocations.add(location);
200: jdkLabels.add(label);
201: }
202:
203: }
204: }
205: }
206:
207: public List<File> getLocations() {
208: return jdkLocations;
209: }
210:
211: public List<String> getLabels() {
212: return jdkLabels;
213: }
214:
215: public File getSelectedLocation() {
216: // the first obvious choice is the jdk that has already been selected for
217: // this product; if it has not yet been set, there are still lots of
218: // choices:
219: // - reuse the location which was selected on another jdk location panel if
220: // it fits the requirements
221: // - use the location of the jdk if it is bundled and already installed
222: // - reuse the location which has been used for an installed product if
223: // it fits the requirements
224: // - choose the closest one to the preferred version if it is defined and
225: // a valid closest version exists
226: // - use the first item in the list
227: // - use an empty path
228: final String jdkLocation = getWizard().getProperty(
229: JDK_LOCATION_PROPERTY);
230: if (jdkLocation != null
231: && jdkLocations.contains(new File(jdkLocation))) {
232: return new File(jdkLocation);
233: }
234:
235: if ((lastSelectedJava != null)
236: && jdkLocations.contains(lastSelectedJava)) {
237: return lastSelectedJava;
238: }
239:
240: try {
241: Registry bundledRegistry = new Registry();
242: final String bundledRegistryUri = System
243: .getProperty(Registry.BUNDLED_PRODUCT_REGISTRY_URI_PROPERTY);
244:
245: bundledRegistry
246: .loadProductRegistry((bundledRegistryUri != null) ? bundledRegistryUri
247: : Registry.DEFAULT_BUNDLED_PRODUCT_REGISTRY_URI);
248:
249: // iterate over bundled JDKs to check whether they are already installed
250: for (Product bundledJdk : bundledRegistry
251: .getProducts(JDK_PRODUCT_UID)) {
252: Product globalJdk = Registry.getInstance().getProduct(
253: JDK_PRODUCT_UID, bundledJdk.getVersion());
254:
255: if (globalJdk != null) {
256: final File jdkLoc = globalJdk.getStatus().equals(
257: Status.INSTALLED) ? globalJdk
258: .getInstallationLocation() : JavaUtils
259: .findJDKHome(globalJdk.getVersion());
260:
261: if (jdkLoc != null && jdkLocations.contains(jdkLoc)) {
262: return jdkLoc;
263: }
264: }
265: }
266:
267: } catch (InitializationException e) {
268: LogManager.log("Cannot load bundled registry", e);
269: }
270:
271: for (Product product : Registry.getInstance().queryProducts(
272: new OrFilter(new ProductFilter(Status.INSTALLED),
273: new ProductFilter(Status.TO_BE_INSTALLED)))) {
274: final String jdk = product
275: .getProperty(JDK_LOCATION_PROPERTY);
276:
277: if (jdk != null) {
278: final File jdkFile = new File(jdk);
279:
280: if (jdkLocations.contains(jdkFile)) {
281: return jdkFile;
282: }
283: }
284: }
285:
286: if (preferredVersion != null) {
287: File closestLocation = null;
288: VersionDistance closestDistance = null;
289:
290: for (File location : jdkLocations) {
291: final Version currentVersion = JavaUtils
292: .getVersion(location);
293: final VersionDistance currentDistance = currentVersion
294: .getDistance(preferredVersion);
295:
296: if ((closestDistance == null)
297: || currentDistance.lessThan(closestDistance)) {
298: closestLocation = location;
299: closestDistance = currentDistance;
300: }
301: }
302:
303: if (closestLocation != null) {
304: return closestLocation;
305: }
306: }
307:
308: if (jdkLocations.size() != 0) {
309: return jdkLocations.get(0);
310: }
311:
312: return new File(StringUtils.EMPTY_STRING);
313: }
314:
315: public String validateLocation(final String path) {
316: final File file = new File(path);
317:
318: if (path.equals(StringUtils.EMPTY_STRING)) {
319: return StringUtils.format(getProperty(ERROR_NULL_PROPERTY));
320: }
321:
322: if (!SystemUtils.isPathValid(path)) {
323: return StringUtils.format(
324: getProperty(ERROR_NOT_VALID_PATH_PROPERTY), path);
325: }
326:
327: if (!file.exists()) {
328: if (JavaUtils.getInfo(file) == null) {
329: // JDK location does not exist and is not in the list of installable JDKs
330: return StringUtils.format(
331: getProperty(ERROR_PATH_NOT_EXISTS_PROPERTY),
332: path);
333: }
334: } else {
335: if (!JavaUtils.isJavaHome(file)) {
336: return StringUtils.format(
337: getProperty(ERROR_NOT_JAVAHOME_PROPERTY), path);
338: }
339:
340: if (!JavaUtils.isJdk(file)) {
341: return StringUtils.format(
342: getProperty(ERROR_NOT_JDK_PROPERTY), path);
343: }
344: }
345:
346: Version version = JavaUtils.getVersion(file);
347: if (version == null) {
348: for (Product jdk : Registry.getInstance().getProducts(
349: JDK_PRODUCT_UID)) {
350: if ((jdk.getStatus() == Status.TO_BE_INSTALLED)
351: && jdk.getInstallationLocation().equals(file)) {
352: version = jdk.getVersion();
353: }
354: }
355: }
356:
357: if (version == null) {
358: return StringUtils.format(
359: getProperty(ERROR_UNKNOWN_PROPERTY), path);
360: }
361:
362: if (version.olderThan(minimumVersion)) {
363: return StringUtils.format(
364: getProperty(ERROR_WRONG_VERSION_OLDER_PROPERTY),
365: path, version, minimumVersion);
366: }
367:
368: if (version.newerThan(maximumVersion)) {
369: return StringUtils.format(
370: getProperty(ERROR_WRONG_VERSION_NEWER_PROPERTY),
371: path, version, maximumVersion);
372: }
373: String vendor = JavaUtils.getInfo(file).getVendor();
374: if (!vendor.matches(vendorAllowed)) {
375: return StringUtils.format(
376: getProperty(ERROR_WRONG_VENDOR_PROPERTY), path,
377: vendor, vendorAllowed);
378: }
379:
380: return null;
381: }
382:
383: public void setLocation(final File location) {
384: lastSelectedJava = location;
385: SearchForJavaAction.addJavaLocation(location);
386: getWizard().setProperty(JDK_LOCATION_PROPERTY,
387: location.getAbsolutePath());
388: }
389:
390: private void addJavaLocationsFromProductDependencies() {
391: // finally we should scan the registry for jdks planned for installation, if
392: // the current product is scheduled to be installed after 'jdk', i.e. has
393: // an install-after dependency on 'jdk' uid
394:
395: final Object objectContext = getWizard().getContext().get(
396: Product.class);
397: boolean sort = false;
398: if (objectContext != null && objectContext instanceof Product) {
399: final Product product = (Product) objectContext;
400: for (Dependency dependency : product
401: .getDependencies(InstallAfter.class)) {
402: if (dependency.getUid().equals(JDK_PRODUCT_UID)) {
403: for (Product jdk : Registry.getInstance()
404: .getProducts(JDK_PRODUCT_UID)) {
405: if (jdk.getStatus() == Status.TO_BE_INSTALLED
406: && !SearchForJavaAction
407: .getJavaLocations()
408: .contains(
409: jdk
410: .getInstallationLocation())) {
411: SearchForJavaAction.addJavaLocation(jdk
412: .getInstallationLocation(), jdk
413: .getVersion(),
414: SUN_MICROSYSTEMS_VENDOR);
415: sort = true;
416: }
417: }
418:
419: break;
420: }
421: }
422: }
423: if (sort) {
424: SearchForJavaAction.sortJavaLocations();
425: }
426: }
427:
428: /////////////////////////////////////////////////////////////////////////////////
429: // Constants
430: public static final String JDK_LOCATION_PROPERTY = "jdk.location"; // NOI18N
431:
432: public static final String MINIMUM_JDK_VERSION_PROPERTY = "minimum.jdk.version"; // NOI18N
433: public static final String MAXIMUM_JDK_VERSION_PROPERTY = "maximum.jdk.version"; // NOI18N
434: public static final String PREFERRED_JDK_VERSION_PROPERTY = "preferred.jdk.version"; // NOI18N
435: public static final String VENDOR_JDK_ALLOWED_PROPERTY = "vendor.jdk.allowed.pattern"; // NOI18N
436:
437: public static final String DEFAULT_LOCATION_LABEL_TEXT = ResourceUtils
438: .getString(JdkLocationPanel.class,
439: "JLP.location.label.text"); // NOI18N
440: public static final String DEFAULT_LOCATION_BUTTON_TEXT = ResourceUtils
441: .getString(JdkLocationPanel.class,
442: "JLP.location.button.text"); // NOI18N
443: public static final String DEFAULT_LIST_LABEL_TEXT = ResourceUtils
444: .getString(JdkLocationPanel.class, "JLP.list.label.text"); // NOI18N
445:
446: public static final String ERROR_NULL_PROPERTY = "error.null"; // NOI18N
447: public static final String ERROR_NOT_VALID_PATH_PROPERTY = "error.not.valid.path"; // NOI18N
448: public static final String ERROR_PATH_NOT_EXISTS_PROPERTY = "error.path.not.exists"; // NOI18N
449: public static final String ERROR_NOT_JAVAHOME_PROPERTY = "error.not.javahome"; // NOI18N
450: public static final String ERROR_NOT_JDK_PROPERTY = "error.not.jdk"; // NOI18N
451: public static final String ERROR_WRONG_VERSION_OLDER_PROPERTY = "error.wrong.version.older"; // NOI18N
452: public static final String ERROR_WRONG_VERSION_NEWER_PROPERTY = "error.wrong.version.newer"; // NOI18N
453: public static final String ERROR_WRONG_VENDOR_PROPERTY = "error.wrong.vendor"; // NOI18N
454: public static final String ERROR_UNKNOWN_PROPERTY = "error.unknown"; // NOI18N
455:
456: public static final String DEFAULT_ERROR_NULL = ResourceUtils
457: .getString(JdkLocationPanel.class, "JLP.error.null"); // NOI18N
458: public static final String DEFAULT_ERROR_NOT_VALID_PATH = ResourceUtils
459: .getString(JdkLocationPanel.class,
460: "JLP.error.not.valid.path"); // NOI18N
461: public static final String DEFAULT_ERROR_PATH_NOT_EXISTS = ResourceUtils
462: .getString(JdkLocationPanel.class,
463: "JLP.error.path.not.exists"); // NOI18N
464: public static final String DEFAULT_ERROR_NOT_JAVAHOME = ResourceUtils
465: .getString(JdkLocationPanel.class, "JLP.error.not.javahome"); // NOI18N
466: public static final String DEFAULT_ERROR_NOT_JDK = ResourceUtils
467: .getString(JdkLocationPanel.class, "JLP.error.not.jdk"); // NOI18N
468: public static final String DEFAULT_ERROR_WRONG_VERSION_OLDER = ResourceUtils
469: .getString(JdkLocationPanel.class,
470: "JLP.error.wrong.version.older"); // NOI18N
471: public static final String DEFAULT_ERROR_WRONG_VERSION_NEWER = ResourceUtils
472: .getString(JdkLocationPanel.class,
473: "JLP.error.wrong.version.newer"); // NOI18N
474: public static final String DEFAULT_ERROR_WRONG_VENDOR = ResourceUtils
475: .getString(JdkLocationPanel.class, "JLP.error.wrong.vendor"); // NOI18N
476:
477: public static final String DEFAULT_ERROR_UNKNOWN = ResourceUtils
478: .getString(JdkLocationPanel.class, "JLP.error.unknown"); // NOI18N
479: public static final String DEFAULT_ERROR_NOTHING_FOUND = ResourceUtils
480: .getString(JdkLocationPanel.class,
481: "JLP.error.nothing.found"); // NOI18N
482:
483: public static final String DEFAULT_MINIMUM_JDK_VERSION = ResourceUtils
484: .getString(JdkLocationPanel.class,
485: "JLP.minimum.jdk.version"); // NOI18N
486: public static final String DEFAULT_MAXIMUM_JDK_VERSION = ResourceUtils
487: .getString(JdkLocationPanel.class,
488: "JLP.maximum.jdk.version"); // NOI18N
489: public static final String DEFAULT_VENDOR_JDK_ALLOWED = ResourceUtils
490: .getString(JdkLocationPanel.class, "JLP.vendor.jdk.allowed");
491:
492: public static final String DEFAULT_USEDBY_LABEL = ResourceUtils
493: .getString(JdkLocationPanel.class, "JLP.usedby.label"); //NOI18N
494: public static final String USEDBY_LABEL_PROPERTY = "usedby.label"; //NOI18N
495:
496: private static final String SUN_MICROSYSTEMS_VENDOR = "Sun Microsystems Inc."; //NOI18N
497:
498: private static final String JDK_PRODUCT_UID = "jdk"; //NOI18N
499: }
|