/******************************************************************************* * Copyright (c) 2012 Google, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.internal.product; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.PrintWriter; import java.io.StringWriter; import java.net.URL; import java.util.Calendar; import java.util.GregorianCalendar; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PluginVersionIdentifier; import org.eclipse.core.runtime.Status; import com.windowtester.internal.debug.Logger; import com.windowtester.internal.runtime.RuntimePlugin; import com.windowtester.runtime.util.PluginUtilities; /** * Central place for Platform information * <p> * * @author Dan Rubel */ public class PlatformInfo { /** * The name displayed for an unknown IDE */ public static final String UNKNOWN_IDE_NAME = "Unknown IDE"; /** * Constant representing unknown version of Eclipse or IDE */ public static final PluginVersionIdentifier UNKNOWN_VERSION = new PluginVersionIdentifier(100, 1, 4); /** * Constant representing unknown version string of Eclipse or IDE */ public static final String UNKNOWN_VERSION_STRING = UNKNOWN_VERSION.toString(); /** * The version displayed for an unknown IDE version */ public static final String UNKNOWN_BUILD_ID = "?BUILD-ID?"; /** * The NL value displayed for an unknown NL */ public static final String UNKNOWN_NL = "?NL?"; /** * The full name for the IDE */ private static String ideName; /** * The development environment version string or <code>null</code> if not * initialized yet by {@link #getIDEVersionString()} */ private static String ideVersionString; /** * The development environment's NL (not null, not empty, no leading or trailing * spaces) */ private static String ideNL; /** * The version of Eclipse upon which the development environment is based or * <code>null</code> if not initialized yet by {@link #getEclipseVersion()} */ private static PluginVersionIdentifier eclipseVersion; /** * The build identifier for Eclipse (e.g. "v20061503") or <code>null</code> if not * initialized yet by {@link #getEclipseBuildId()}. For Eclipse 3.2, this is the same * as the Eclipse version qualifier segment. For older versions of Eclipse, this is * read from the JDT plugin about.properties file. */ private static String eclipseBuildId; /** * The name for this particular Eclipse build (e.g. "M6", "M7", "RC1", "", etc) or * <code>null</code> if not initialized yet by {@link #getEclipseBuildName()}. This * may contain the same value as {@link #getEclipseBuildId()} if the build is not a * milestone, release candidate, or GA. */ private static String eclipseBuildName; /** * The build date for this particular instance of Eclipse as derived from * {@link #getEclipseBuildId()} or <code>null</code> if not initialized yet by * {@link #getEclipseBuildDate()}. */ private static GregorianCalendar eclipseBuildDate; private static String ideCompatibilityWarningMessage; /** * No instances */ private PlatformInfo() { } // ////////////////////////////////////////////////////////////////////////// // // Accessors // // ////////////////////////////////////////////////////////////////////////// /** * Answer the development environment full name * * @return the full name (not null, not empty, no leading or trailing spaces) */ public static String getIDEName() { if (ideName == null) { try { /* $codepro.preprocessor.if version >= 3.0 $ */ if (Platform.getProduct() != null) ideName = Platform.getProduct().getName(); /* $codepro.preprocessor.elseif version < 3.0 $ org.eclipse.core.runtime.IPluginDescriptor descriptor = Platform.getPluginRegistry() .getPluginDescriptor( org.eclipse.core.boot.BootLoader.getCurrentPlatformConfiguration() .getPrimaryFeatureIdentifier()); if (descriptor != null) ideName = descriptor.getLabel(); $codepro.preprocessor.endif $ */ if (ideName == null) ideName = UNKNOWN_IDE_NAME; else { ideName = ideName.trim(); if (ideName.length() == 0) ideName = UNKNOWN_IDE_NAME; else if (ideName.startsWith("Eclipse Pl")) ideName = "Eclipse"; else if (ideName.startsWith("Common OS-independent base of the Eclipse platform")) ideName = "Eclipse"; } } catch (Exception ex) { // Logger may not be open, so cannot log exception ideName = UNKNOWN_IDE_NAME; } } return ideName; } /** * Answer the development environment version string * * @return the version string (not null, not empty, no leading or trailing spaces) */ public static String getIDEVersionString() { if (ideVersionString == null) { try { String pluginId = null; /* $codepro.preprocessor.if version >= 3.0 $ */ if (Platform.getProduct() != null) pluginId = Platform.getProduct().getDefiningBundle().getSymbolicName(); /* $codepro.preprocessor.elseif version < 3.0 $ pluginId = org.eclipse.core.boot.BootLoader.getCurrentPlatformConfiguration().getPrimaryFeatureIdentifier(); $codepro.preprocessor.endif $ */ ideVersionString = PluginUtilities.getVersionString(pluginId); } catch (Exception ex) { // Logger may not be open, so cannot log exception } if (ideVersionString == null || ideVersionString.length() == 0) ideVersionString = UNKNOWN_VERSION_STRING; } return ideVersionString; } /** * Returns the string name of the current locale for use in finding files whose path * starts with <code>$nl$</code>. * * @return the national language being used (not null, not empty, no leading or * trailing spaces) */ public static String getIDENL() { if (ideNL == null) { /* $codepro.preprocessor.if version >= 3.0 $ */ try { ideNL = Platform.getNL(); } catch (Exception e) { // Logger may not be open, so cannot log exception } /* $codepro.preprocessor.endif $ */ if (ideNL == null) ideNL = UNKNOWN_NL; } return ideNL; } /** * Answer the version of Eclipse upon which the development environment is based. * * @return the version (not <code>null</code>) */ public static PluginVersionIdentifier getEclipseVersion() { if (eclipseVersion == null) { try { eclipseVersion = PluginUtilities.getVersion("org.eclipse.core.runtime"); // Use org.eclipse.jdt.ui to tell the difference between E-3.5 and E-3.6 M# if (eclipseVersion.getMajorComponent() == 3 && eclipseVersion.getMinorComponent() == 5) { PluginVersionIdentifier version = PluginUtilities.getVersion("org.eclipse.jdt.ui"); if (version.getMajorComponent() == 3 && version.getMinorComponent() == 6) eclipseVersion = version; } // For older versions of Eclipse, read the build from the JDT if (eclipseVersion.getQualifierComponent().length() == 0) eclipseVersion = new PluginVersionIdentifier( eclipseVersion.getMajorComponent(), eclipseVersion.getMinorComponent(), eclipseVersion.getServiceComponent(), "v" + readBuildId("org.eclipse.jdt", "about.mappings")); } catch (Exception e) { // Logger may not be open, so cannot log exception } if (eclipseVersion == null) eclipseVersion = new PluginVersionIdentifier(0, 0, 0); } return eclipseVersion; } /** * Answer the build identifier for Eclipse (e.g. "200408122000"). This is read from * the JDT plugin about.properties file. * * @return the build id or {@link #UNKNOWN_BUILD_ID} if it cannot be deteremined */ public static String getEclipseBuildId() { if (eclipseBuildId == null) { try { eclipseBuildId = readBuildId("org.eclipse.jdt", "about.mappings"); } catch (Exception e) { // Logger may not be open, so cannot log exception } if (eclipseBuildId == null) eclipseBuildId = UNKNOWN_BUILD_ID; } return eclipseBuildId; } /** * Answer the name for this particular Eclipse build (e.g. "M6", "M7", "RC1", "", etc). * This may return the same value as {@link #getEclipseBuildId()} if the build is not a milestone, release candidate, or GA. * * @return the build name (not <code>null</code>, but may be empty if it is a GA) */ public static String getEclipseBuildName() { if (eclipseBuildName == null) { // HashMap buildIdMap = new HashMap(); // // // Eclipse 3.0 Milestones // buildIdMap.put("200312182000", "M6"); // buildIdMap.put("200402122000", "M7"); // buildIdMap.put("200403261517", "M8"); // buildIdMap.put("200405211200", "M9"); // buildIdMap.put("200405290105", "RC1"); // buildIdMap.put("200406111814", "RC2"); // buildIdMap.put("200406192000", "RC3"); // // // Eclipse 3.0 GA // buildIdMap.put("200406251208", ""); // // // Eclipse 3.0.1 GA // buildIdMap.put("200409161125", ""); // // // Eclipse 3.0.2 GA // buildIdMap.put("200503110845", ""); // // // Eclipse 3.1 Milestones // buildIdMap.put("200408122000", "M1"); // M1 // buildIdMap.put("200409240800", "M2"); // M2 // buildIdMap.put("200411050810", "M3"); // M3 // buildIdMap.put("200412162000", "M4"); // M4 // buildIdMap.put("I20050218-1600", "M5"); // M5 // buildIdMap.put("200502181600", "M5"); // M5 // buildIdMap.put("I20050219-1500", "M5a"); // M5a // buildIdMap.put("200502191500", "M5a"); // M5a // buildIdMap.put("I20050401-1645", "M6"); // M6 // buildIdMap.put("200504011645", "M6"); // M6 // buildIdMap.put("I20050513-1415", "M7"); // M7 // buildIdMap.put("200505131415", "M7"); // M7 // buildIdMap.put("I20050527-1300", "RC1"); // RC1 // buildIdMap.put("200505271300", "RC1"); // RC1 // buildIdMap.put("I20050610-1757", "RC2"); // RC2 // buildIdMap.put("200506101757", "RC2"); // RC2 // buildIdMap.put("I20050617-1618", "RC3"); // RC3 // buildIdMap.put("200506171618", "RC3"); // RC3 // buildIdMap.put("I20050624-1300", "RC4"); // RC4 // buildIdMap.put("200506241300", "RC4"); // RC4 // // // Eclipse 3.1 GA // buildIdMap.put("I20050627-1435", ""); // 3.1 // buildIdMap.put("200506271435", ""); // 3.1 // // // Eclipse 3.1.1 GA // buildIdMap.put("M20050929-0840", ""); // 3.1.1 // buildIdMap.put("200509290840", ""); // 3.1.1 // // // Eclipse 3.1.2 GA // buildIdMap.put("M20060118-1600", ""); // 3.1.2 // buildIdMap.put("200601181600", ""); // 3.1.2 // // // Eclipse 3.2 Milestones // buildIdMap.put("I20050811-1530", "M1"); // M1 // buildIdMap.put("200508111530", "M1"); // M1 // buildIdMap.put("I20050923-1000", "M2"); // M2 // buildIdMap.put("200509231000", "M2"); // M2 // buildIdMap.put("I20051102-1600", "M3"); // M3 // buildIdMap.put("200511021600", "M3"); // M3 // buildIdMap.put("I20051215-1506", "M4"); // M4 // buildIdMap.put("200512151506", "M4"); // M4 // buildIdMap.put("I20060217-1115", "M5"); // M5 // buildIdMap.put("200602171115", "M5"); // M5 // buildIdMap.put("I20060223-1656", "M5a"); // M5a // buildIdMap.put("200602231656", "M5a"); // M5a // buildIdMap.put("I20060331-2000", "M6"); // M6 // buildIdMap.put("200603312000", "M6"); // M6 // buildIdMap.put("I20060413-1718", ""); // RC1 // buildIdMap.put("200604131718", ""); // RC1 // buildIdMap.put("I20060419-1640", "RC1a"); // RC1a // buildIdMap.put("200604191640", "RC1a"); // RC1a // buildIdMap.put("I20060428-1315", "RC2"); // RC2 // buildIdMap.put("200604281315", "RC2"); // RC2 // buildIdMap.put("I20060505-1306", "RC3"); // RC3 // buildIdMap.put("200605051306", "RC3"); // RC3 // buildIdMap.put("I20060512-1600", "RC4"); // RC4 // buildIdMap.put("200605121600", "RC4"); // RC4 // buildIdMap.put("I20060519-1206", "RC5"); // RC5 // buildIdMap.put("200605191206", "RC5"); // RC5 // buildIdMap.put("I20060526-0010", "RC6"); // RC6 // buildIdMap.put("200605260010", "RC6"); // RC6 // buildIdMap.put("I20060602-1317", ""); // RC7 // buildIdMap.put("200606021317", ""); // RC7 // // // Eclipse 3.2 GA // buildIdMap.put("M20060629-1905", ""); // 3.2 // buildIdMap.put("200606291905", ""); // 3.2 // // eclipseBuildName = (String) buildIdMap.get(getEclipseBuildId()); // [author=Dan] Don't bother with the build name and simply focus on // whether or not this was compiled for a major/minor version of Eclipse eclipseBuildName = ""; if (eclipseBuildName == null) eclipseBuildName = getEclipseBuildId(); } return eclipseBuildName; } /** * Answer the build date for this particular instance of Eclipse as derived from * {@link #getEclipseBuildId()} or Jan 1, 2003 if it cannot be determined. * * @return the build date (not <code>null</code>) */ public static Calendar getEclipseBuildDate() { if (eclipseBuildDate == null) { try { String ymd = getEclipseBuildId(); if (Character.isLetter(ymd.charAt(0))) ymd = ymd.substring(1); int y = Integer.parseInt(ymd.substring(0, 4)); int m = Integer.parseInt(ymd.substring(4, 6)) - 1; int d = Integer.parseInt(ymd.substring(6, 8)); eclipseBuildDate = new GregorianCalendar(y, m, d); } catch (Exception e) { // Logger may not be open, so cannot log exception } if (eclipseBuildDate == null) eclipseBuildDate = new GregorianCalendar(2003, 0, 1); } return eclipseBuildDate; } /** * Read the build identifier from the specified plugin file. * * @param pluginId the plugin's unique identifier * @param fileName the name of the file containing the build id * @return the build identifier or <code>null</code> if it cannot be determined */ private static String readBuildId(String pluginId, String fileName) { InputStream stream = null; try { URL url = PluginUtilities.getUrl(pluginId, fileName); stream = url.openStream(); LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream)); while (true) { String line = reader.readLine(); if (line == null) return null; if (line.startsWith("0=")) return line.substring(2).trim(); } } catch (Exception e) { // Logger may not be open, so cannot log exception } finally { try { if (stream != null) stream.close(); } catch (IOException e) { // Logger may not be open, so cannot log exception } } return null; } /** * Check the compatibility of the currently installed products with the currently * executing version of Eclipse. */ public static void checkCompatibility() { String text = getIDECompatibilityWarningMessage(); if (text != null && text.length() > 0) Logger.log(new Status(IStatus.WARNING, RuntimePlugin.PLUGIN_ID, 0, text, null)); } /** * Determine if any of the currently installed products is incompatible with the IDE * in which they are currently executing. Typically this is accessed on a background * thread and the result pumped to the log or to a dialog presenting the information * to the user. * * @return a message used to warn the user about potential incompatibilities or an * empty string if no incompatibilities are detected (not <code>null</code>) */ public static String getIDECompatibilityWarningMessage() { if (ideCompatibilityWarningMessage == null) { StringWriter stringWriter = new StringWriter(); boolean suppressWarnings = "true".equalsIgnoreCase(System .getProperty("suppressCompatibilityWarningMessage")); if (!suppressWarnings) { PrintWriter writer = new PrintWriter(stringWriter); IProduct[] allProducts = Products.getAllProducts(); for (int i = 0; i < allProducts.length; i++) { IProduct product = allProducts[i]; // if (product.isInstalled() && !product.isCompatibleWithIDE()) if (!product.isCompatibleWithIDE()) product.printIDECompatibilityWarningMessage(writer); } } ideCompatibilityWarningMessage = stringWriter.toString(); } return ideCompatibilityWarningMessage; } }