blob: f7284019fd14e1da51a5077c09428622a658e21a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2008 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 java.util.ArrayList;
import java.util.HashMap;
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;
import org.osgi.framework.Bundle;
import com.ibm.icu.text.MessageFormat;
/**
* 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 HashMap mappingsMap = new HashMap(4);
private static String[] loadMappings(Bundle definingBundle) {
URL location = Platform.find(definingBundle, 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;
while (found) {
try {
mappingsList.add(bundle.getString(Integer.toString(i)));
} catch (MissingResourceException e) {
found = false;
}
i++;
}
}
String[] mappings = (String[]) mappingsList.toArray(new String[mappingsList.size()]);
mappingsMap.put(definingBundle, mappings);
return mappings;
}
private static String[] getMappings(Bundle definingBundle) {
String[] mappings = (String[]) mappingsMap.get(definingBundle);
if (mappings == null) {
mappings = loadMappings(definingBundle);
}
if (mappings == null) {
mappings = new String[0];
}
return mappings;
}
/**
* 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;
}
String[] mappings = getMappings(product.getDefiningBundle());
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;
}
String[] tempMappings = getMappings(product.getDefiningBundle());
/*
* Check if the mapping value is a system property, specified
* by '$' at the beginning and end of the string. If so, update
* the mappings array with the system property value.
*/
for (int i=0; i<tempMappings.length; i++) {
String nextString = tempMappings[i];
int length = nextString.length();
if (length > 2 && nextString.charAt(0) == '$' && nextString.charAt(length-1) == '$') {
String systemPropertyKey = nextString.substring(1, length-1);
// If system property is not set, insert an empty String
tempMappings[i] = System.getProperty(systemPropertyKey, ""); //$NON-NLS-1$;
}
}
return MessageFormat.format(property, tempMappings);
}
/**
* 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();
}
}