blob: 546ae5e7d43a8ae2eda65f597334cf429183b502 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.common.plugin;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.common.serviceability.Logger;
import org.eclipse.epf.common.serviceability.MsgDialog;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.I18nUtil;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
/**
* The abstract base class for all EPF plug-ins.
*
* @author Kelvin Low
* @author Jinhua Xi
* @since 1.0
*/
public abstract class AbstractPlugin extends AbstractUIPlugin {
// The relative path to the icons.
private static final String ICON_PATH = "icons/"; //$NON-NLS-1$;
// The resource bundle for this plug-in.
private ResourceBundle resourceBundle;
// This plug-in ID.
private String pluginId;
// The plug-in install URL.
private URL installURL;
// The plug-in install path.
private String installPath;
// The plug-in icon URL.
private URL iconURL;
// The logger hash map.
private static Map<String, Logger> loggers = new HashMap<String, Logger>();
// The message dialog hash map.
private static Map<String, MsgDialog> msgDialogs = new HashMap<String, MsgDialog>();
// The shared image hash map.
private static Map<String, Image> sharedImages = new HashMap<String, Image>();
/**
* Default constructor.
*/
public AbstractPlugin() {
super();
}
/**
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
init(context);
if (isDebugging()) {
getLogger().logInfo("Started " + pluginId); //$NON-NLS-1$
}
}
/**
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(BundleContext)
*/
public void stop(BundleContext context) throws Exception {
// Free the shared images.
for (Iterator images = sharedImages.values().iterator(); images
.hasNext();) {
Image image = (Image) images.next();
if (image != null && !image.isDisposed()) {
image.dispose();
}
}
super.stop(context);
if (isDebugging()) {
getLogger().logInfo("Stopped " + pluginId); //$NON-NLS-1$
}
}
/**
* Initializes this plug-in.
*
* @param context
* The bundle context.
*/
protected void init(BundleContext context) throws Exception {
// Get the bundle for this plug-in.
Bundle bundle = getBundle();
// Get the resouce bundle for this plug-in.
resourceBundle = Platform.getResourceBundle(bundle);
// Get the ID for this plug-in.
pluginId = bundle.getSymbolicName();
if (isDebugging()) {
getLogger().logInfo("Initializing " + pluginId); //$NON-NLS-1$
}
// Get the install path of this plug-in.
installURL = bundle.getEntry("/"); //$NON-NLS-1$
try {
installPath = FileLocator.resolve(installURL).getPath();
} catch (IOException e) {
installPath = Platform.getInstallLocation().getURL().getPath();
}
try {
iconURL = new URL(installURL, ICON_PATH);
} catch (IOException e) {
}
if (isDebugging()) {
getLogger().logInfo(
"Initialized " + pluginId + ", installPath=" + installPath); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* Returns the ID of this plug-in.
*
* @return The ID of this plug-in.
*/
public String getId() {
return pluginId;
}
/**
* Returns the install URL of this plug-in.
*
* @param The
* install URL of this plug-in.
*/
public URL getInstallURL() {
return installURL;
}
/**
* Returns the install path of this plug-in.
*
* @param The
* install path of this plug-in.
*/
public String getInstallPath() {
return installPath;
}
/**
* Loads and returns the localized properties of a Java properties file.
* <p>
*
* @param path
* The properties file path relative to the plug-in root.
* @return A <code>Properties</code> object.
*/
public Properties getProperties(String path) throws IOException {
Properties props = new Properties();
if (path == null) {
return props;
}
String filePath = getLocalizedFile(path, true);
// String filePath = null;
// String fileName = FileUtil.getFileName(path);
// int index = path.lastIndexOf(fileName);
// String pathName = path.substring(0, index);
//
// Locale locale = Locale.getDefault();
// Bundle bundle = getBundle();
// Bundle[] bundles = Platform.getFragments(bundle);
// if (bundles != null) {
// for (int i = 0; i < bundles.length; i++) {
// URL entry = bundles[i].getEntry(pathName);
// if (entry != null) {
// URL url = Platform.resolve(entry);
// filePath = I18nUtil.getLocalizedFile(url.getPath() + fileName,
// locale); //$NON-NLS-1$
// if (filePath != null) {
// break;
// }
// }
// }
// }
//
// if (filePath == null) {
// URL entry = bundle.getEntry(path);
// if (entry != null) {
// URL url = Platform.resolve(entry);
// filePath = I18nUtil.getLocalizedFile(url.getPath(), locale);
// if (filePath == null) {
// filePath = url.getPath();
// }
// }
// }
if (filePath != null) {
props.load(new FileInputStream(filePath));
}
return props;
}
/**
* get the locale specific absolute file path name of the given file in the
* plugin.
*
* @param path
* The properties file path relative to the plug-in root.
* @return String the locale specific absolute file path name of the given
* file.
* @throws IOException
*/
public String getLocalizedFile(String path, boolean useDefault)
throws IOException {
String filePath = null;
String fileName = FileUtil.getFileName(path);
int index = path.lastIndexOf(fileName);
String pathName = path.substring(0, index);
Locale locale = Locale.getDefault();
Bundle bundle = getBundle();
Bundle[] bundles = Platform.getFragments(bundle);
if (bundles != null) {
for (int i = 0; i < bundles.length; i++) {
URL entry = bundles[i].getEntry(pathName);
if (entry != null) {
URL url = FileLocator.resolve(entry);
filePath = I18nUtil.getLocalizedFile(url.getPath()
+ fileName, locale); //$NON-NLS-1$
if (filePath != null) {
break;
}
}
}
}
if (filePath == null) {
URL entry = bundle.getEntry(path);
if (entry != null) {
URL url = FileLocator.resolve(entry);
filePath = I18nUtil.getLocalizedFile(url.getPath(), locale);
if (filePath == null && useDefault) {
filePath = url.getPath();
}
}
}
return filePath;
}
// /**
// * get the localized files for the files in the specified folder. The
// folder is a relative path to the plugin.
// * returns a map of the files (in ralitive path to the plugin) to their
// localized files in absolute path.
// * @param folder String path relative to the current plugin
// * @param recursive boolean if true recurisely get all files in sub
// folders
// * @return Map a map of the files (in ralitive path to the plugin) to
// their localized files in absolute path.
// * @throws IOException
// */
// public Map getLocalizedFiles(String folder, boolean recursive) throws
// IOException
// {
// Map fileMap = new HashMap();
//
// String pluginPath = getInstallPath();
//
// List files = new ArrayList();
// File f = new File(pluginPath, folder);
// FileUtil.getAllFiles(f, files, true);
//
// // for each file found in the specified folder, get the localized file
// // put an antry of the original file and the localized file
// URI pluginUri = new File(pluginPath).toURI();
//
// for ( Iterator it = files.iterator(); it.hasNext(); )
// {
// File src = (File)it.next();
// String relPath = pluginUri.relativize(src.toURI()).getPath();
//
// // only get the locale specific file, don't include the default one
// String localizedFile = getLocalizedFile(relPath, false);
// if ( localizedFile != null )
// {
// fileMap.put(relPath, localizedFile);
// }
// }
//
// return fileMap;
// }
/**
* for the given path in the plugin, find the localized files form the nl
* fragemenets and copy the localized files to the destination folder
*
* @param path
* String a relative path to the plugin root. The files in this
* folder will be iterated and their localized files will be
* copied over
* @param toDir
* FIle the destination folder
* @param recursive
* boolean recurively looking for files int the specified folder
* @param useLocaleFileName
* boolean if true the locale specific file names will be used in
* the copied destination, otherwise, the locale specific file
* name will be renamed to the default one in the destination
* folder
* @throws IOException
*/
public void copyLocalizedFiles(String path, File toDir, boolean recursive,
boolean useLocaleFileName) throws IOException {
String pluginPath = getInstallPath();
URI pluginUri = new File(pluginPath).toURI();
URI pathUri = new File(pluginPath, path).toURI();
List<File> files = new ArrayList<File>();
File f = new File(pluginPath, path);
FileUtil.getAllFiles(f, files, recursive);
// for each file found in the specified folder, get the localized file
for (Iterator it = files.iterator(); it.hasNext();) {
URI srcUri = ((File) it.next()).toURI();
// get the relative path of the file to the plugin root, then find
// the localized file
String relPath = pluginUri.relativize(srcUri).getPath();
// only get the locale specific file, don't include the default one
String localizedFile = getLocalizedFile(relPath, false);
if (localizedFile == null) {
continue;
}
// need to change the target file path to relative to the path
// instead of the plugin root
relPath = pathUri.relativize(srcUri).getPath();
File srcFile = new File(localizedFile);
File targetFile = new File(toDir, relPath);
File targetParent = targetFile.getParentFile();
// copy the file to the desitination
// if useLocaleFileName is true, the destination file name should
// also use the locale specific file name
if (useLocaleFileName) {
String fileName = srcFile.getName();
targetFile = new File(targetParent, fileName);
}
if (isDebugging()) {
System.out.println("Copying localized file: "); //$NON-NLS-1$
System.out.println("Source: " + srcFile); //$NON-NLS-1$
System.out.println("Target: " + targetFile); //$NON-NLS-1$
System.out.println(""); //$NON-NLS-1$
}
try {
if (!targetParent.exists()) {
targetParent.mkdirs();
}
if (!targetFile.exists()) {
targetFile.createNewFile();
}
FileUtil.copyFile(srcFile, targetFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Returns the localized resource.
*
* @param key
* The resource key.
* @return The localized resource.
*/
public String getString(String key) {
if (resourceBundle != null) {
try {
return resourceBundle.getString(key);
} catch (MissingResourceException e) {
}
}
return '[' + key + ']';
}
/**
* Returns the formatted localized message given the resource key and the
* message argument.
*
* @param key
* The resource key.
* @param argument
* The message argument.
* @return The formatted localized message.
*/
public String formatMessage(String key, Object argument) {
if (resourceBundle != null) {
try {
String msg = resourceBundle.getString(key);
Object[] arguments = { argument };
return MessageFormat.format(msg, arguments);
} catch (MissingResourceException e) {
}
}
return '[' + key + ']';
}
/**
* Returns the image URL given the relative path.
*
* @param relativePath
* The image's path relative to the plug-in's root.
* @return The image URL.
*/
public URL getImageURL(String relativePath) {
try {
URL url = new URL(iconURL, relativePath);
return FileLocator.resolve(url);
} catch (Exception e) {
return null;
}
}
/**
* Returns the image descriptor given the relative path.
*
* @param relativePath
* The image's path relative to the plug-in's root.
* @return The image descriptor.
*/
public ImageDescriptor getImageDescriptor(String relativePath) {
try {
URL url = new URL(iconURL, relativePath);
return ImageDescriptor.createFromURL(url);
} catch (MalformedURLException e) {
return ImageDescriptor.getMissingImageDescriptor();
}
}
/**
* Returns the image given the relative path.
* <p>
* Note: The returned image need to be freed by the caller.
*
* @param relativePath
* The image's path relative to the plug-in's root.
* @return The image.
*/
public Image getImage(String relativePath) {
Image image = null;
ImageDescriptor imageDescriptor = getImageDescriptor(relativePath);
if (imageDescriptor != null) {
image = imageDescriptor.createImage(false);
}
return image;
}
/**
* Returns the shared image given the relative path.
* <p>
* Note: The returned image will be automatically freed when the plug-in
* shuts down.
*
* @param relativePath
* The image's path relative to the plug-in's root.
* @return The image.
*/
public Image getSharedImage(String relativePath) {
Image image = (Image) sharedImages.get(relativePath);
if (image != null) {
return image;
}
ImageDescriptor imageDescriptor = getImageDescriptor(relativePath);
if (imageDescriptor != null) {
image = imageDescriptor.createImage(false);
if (image != null) {
sharedImages.put(relativePath, image);
}
}
return image;
}
/**
* Returns the logger given the plug-in ID.
*
* @return The new or cached logger.
*/
public Logger getLogger() {
Logger logger = (Logger) loggers.get(pluginId);
if (logger == null) {
logger = new Logger(this);
loggers.put(pluginId, logger);
}
return logger;
}
/**
* Returns the message dialog given the plug-in ID.
*
* @return The new or cached message dialog.
*/
public MsgDialog getMsgDialog() {
MsgDialog msgDialog = (MsgDialog) msgDialogs.get(pluginId);
if (msgDialog == null) {
msgDialog = new MsgDialog(this);
msgDialogs.put(pluginId, msgDialog);
}
return msgDialog;
}
/**
* Returns the standard display to be used. The method first checks, if the
* thread calling this method has an associated disaply. If so, this display
* is returned. Otherwise the method returns the default display.
*/
public static Display getStandardDisplay() {
Display display;
display = Display.getCurrent();
if (display == null)
display = Display.getDefault();
return display;
}
}