/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.internal; import java.io.IOException; import java.io.InputStream; import java.net.URL; import com.ibm.icu.text.MessageFormat; import java.util.ArrayList; import java.util.MissingResourceException; import java.util.PropertyResourceBundle; import org.eclipse.core.runtime.IProduct; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.branding.IProductConstants; /** * A class that converts the strings returned by * <code>org.eclipse.core.runtime.IProduct.getProperty</code> to the * appropriate class. This implementation is tightly bound to the properties * provided in IProductConstants. Clients adding their own properties could * choose to subclass this. * * @see org.eclipse.ui.branding.IProductConstants * @since 3.0 */ public class ProductProperties extends BrandingProperties implements IProductConstants { private final IProduct product; private String appName; private String aboutText; private ImageDescriptor aboutImageDescriptor; private ImageDescriptor[] windowImageDescriptors; private URL welcomePageUrl; private String productName; private String productId; private static final String ABOUT_MAPPINGS = "$nl$/about.mappings"; //$NON-NLS-1$ private static String[] systemPropertiesKeys = new String[0]; private static String[] mappings = loadMappings(); private static String[] loadMappings() { IProduct product = Platform.getProduct(); if (product == null) { return new String[0]; } URL location = Platform.find(product.getDefiningBundle(), new Path( ABOUT_MAPPINGS)); PropertyResourceBundle bundle = null; InputStream is; if (location != null) { is = null; try { is = location.openStream(); bundle = new PropertyResourceBundle(is); } catch (IOException e) { bundle = null; } finally { try { if (is != null) { is.close(); } } catch (IOException e) { // do nothing if we fail to close } } } ArrayList mappingsList = new ArrayList(); if (bundle != null) { boolean found = true; int i = 0; ArrayList systemPropertiesKeysList = new ArrayList(); while (found) { try { String nextString = bundle.getString(Integer.toString(i)); int length = nextString.length(); /* * Check if the mapping value is a system property, specified * by '$' at the beginning and end of the string. If so, add * the key to the systemPropertiesKeys array and insert array * indices "{i}" to allow the string to be formatted again with * the new system property values. */ if (length > 2 && nextString.indexOf('$') == 0 && nextString.lastIndexOf('$') == length - 1) { int newIndex = systemPropertiesKeysList.size(); systemPropertiesKeysList.add(nextString.substring(1, length-1)); nextString = "{" + newIndex + "}"; //$NON-NLS-1$ //$NON-NLS-2$ } mappingsList.add(nextString); } catch (MissingResourceException e) { found = false; } i++; } systemPropertiesKeys = (String[]) systemPropertiesKeysList.toArray(new String[systemPropertiesKeysList.size()]) ; } return (String[]) mappingsList.toArray(new String[mappingsList.size()]); } /** * This instance will return properties from the given product. The properties are * retrieved in a lazy fashion and cached for later retrieval. * @param product must not be null */ public ProductProperties(IProduct product) { if (product == null) { throw new IllegalArgumentException(); } this.product = product; } /** * The application name, used to initialize the SWT Display. This * value is distinct from the string displayed in the application * title bar. * <p> * E.g., On motif, this can be used to set the name used for * resource lookup. * </p> * @see org.eclipse.swt.widgets.Display#setAppName */ public String getAppName() { if (appName == null) { appName = getAppName(product); } return appName; } /** * The text to show in an "about" dialog for this product. * Products designed to run "headless" typically would not * have such text. */ public String getAboutText() { if (aboutText == null) { aboutText = getAboutText(product); } return aboutText; } /** * An image which can be shown in an "about" dialog for this * product. Products designed to run "headless" typically would not * have such an image. * <p> * A full-sized product image (no larger than 500x330 pixels) is * shown without the "aboutText" blurb. A half-sized product image * (no larger than 250x330 pixels) is shown with the "aboutText" * blurb beside it. */ public ImageDescriptor getAboutImage() { if (aboutImageDescriptor == null) { aboutImageDescriptor = getAboutImage(product); } return aboutImageDescriptor; } /** * An array of one or more images to be used for this product. The * expectation is that the array will contain the same image rendered * at different sizes (16x16 and 32x32). * Products designed to run "headless" typically would not have such images. * <p> * If this property is given, then it supercedes <code>WINDOW_IMAGE</code>. * </p> */ public ImageDescriptor[] getWindowImages() { if (windowImageDescriptors == null) { windowImageDescriptors = getWindowImages(product); } return windowImageDescriptors; } /** * Location of the product's welcome page (special XML-based format), either * a fully qualified valid URL or a path relative to the product's defining * bundle. Products designed to run "headless" typically would not have such * a page. Use of this property is discouraged in 3.0, the new * org.eclipse.ui.intro extension point should be used instead. */ public URL getWelcomePageUrl() { if (welcomePageUrl == null) { welcomePageUrl = getWelcomePageUrl(product); } return welcomePageUrl; } /** * Returns the product name or <code>null</code>. * This is shown in the window title and the About action. */ public String getProductName() { if (productName == null) { productName = getProductName(product); } return productName; } /** * Returns the id for the product or <code>null</code> if none. */ public String getProductId() { if (productId == null) { productId = getProductId(product); } return productId; } /** * The application name, used to initialize the SWT Display. This * value is distinct from the string displayed in the application * title bar. * <p> * E.g., On motif, this can be used to set the name used for * resource lookup. * </p> * <p> * The returned value will have {n} values substituted based on the * current product's mappings regardless of the given product argument. * </p> * @see org.eclipse.swt.widgets.Display#setAppName */ public static String getAppName(IProduct product) { String property = product.getProperty(APP_NAME); if (property == null) { return ""; //$NON-NLS-1$ } if (property.indexOf('{') == -1) { return property; } return MessageFormat.format(property, mappings); } /** * The text to show in an "about" dialog for this product. * Products designed to run "headless" typically would not * have such text. * <p> * The returned value will have {n} values substituted based on the * current product's mappings regardless of the given product argument. * </p> */ public static String getAboutText(IProduct product) { String property = product.getProperty(ABOUT_TEXT); if (property == null) { return ""; //$NON-NLS-1$ } if (property.indexOf('{') == -1) { return property; } property = MessageFormat.format(property, mappings); /* * If there is still a "{" character, check if there are * System properties in the systemPropertiesKeys array that * need to be loaded. */ if (property.indexOf('{') == -1) { return property; } if (systemPropertiesKeys.length == 0) return property; /* * Create a String array of the actual values to be mapped * to the system properties keys. */ String[] systemPropertiesMappings = new String[systemPropertiesKeys.length]; for (int i=0; i < systemPropertiesKeys.length; i++){ String systemProperty = systemPropertiesKeys[i]; // If system property is not set, insert an empty String systemPropertiesMappings[i] = System.getProperty(systemProperty, ""); //$NON-NLS-1$ } /* * Format string with the system properties values. */ return MessageFormat.format(property, systemPropertiesMappings); } /** * An image which can be shown in an "about" dialog for this * product. Products designed to run "headless" typically would not * have such an image. * <p> * A full-sized product image (no larger than 500x330 pixels) is * shown without the "aboutText" blurb. A half-sized product image * (no larger than 250x330 pixels) is shown with the "aboutText" * blurb beside it. */ public static ImageDescriptor getAboutImage(IProduct product) { return getImage(product.getProperty(ABOUT_IMAGE), product .getDefiningBundle()); } /** * An array of one or more images to be used for this product. The * expectation is that the array will contain the same image rendered * at different sizes (16x16 and 32x32). * Products designed to run "headless" typically would not have such images. * <p> * If this property is given, then it supercedes <code>WINDOW_IMAGE</code>. * </p> */ public static ImageDescriptor[] getWindowImages(IProduct product) { String property = product.getProperty(WINDOW_IMAGES); // for compatibility with pre-3.0 plugins that may still use WINDOW_IMAGE if (property == null) { property = product.getProperty(WINDOW_IMAGE); } return getImages(property, product.getDefiningBundle()); } /** * Location of the product's welcome page (special XML-based format), either * a fully qualified valid URL or a path relative to the product's defining * bundle. Products designed to run "headless" typically would not have such * a page. Use of this property is discouraged in 3.0, the new * org.eclipse.ui.intro extension point should be used instead. */ public static URL getWelcomePageUrl(IProduct product) { return getUrl(product.getProperty(WELCOME_PAGE), product .getDefiningBundle()); } /** * Returns the product name or <code>null</code>. * This is shown in the window title and the About action. */ public static String getProductName(IProduct product) { return product.getName(); } /** * Returns the id for the product. */ public static String getProductId(IProduct product) { return product.getId(); } }