/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.plugin.skinresourcepack; import java.net.*; import java.util.*; import org.osgi.framework.*; import net.java.sip.communicator.service.resources.*; import net.java.sip.communicator.util.*; /** * The skin resource pack. * * @author Adam Netocny */ public class SkinResourcePack implements BundleActivator, SkinPack { /** * The Logger used by the SkinResourcePack and its * instances for logging output. */ private static final Logger logger = Logger.getLogger(SkinResourcePack.class); /** * The default resource path. */ private static final String DEFAULT_RESOURCE_PATH = "info"; /** * The resource path of skin images. */ private static final String DEFAULT_IMAGE_RESOURCE_PATH = "images.images"; /** * The resource path of skin colors. */ private static final String DEFAULT_COLOR_RESOURCE_PATH = "colors.colors"; /** * The resource path f skin styles. */ private static final String DEFAULT_STYLE_RESOURCE_PATH = "styles.styles"; /** * The resource path f skin settings. */ private static final String DEFAULT_SETTINGS_RESOURCE_PATH = "settings.settings"; /** * The bundle context. */ private static BundleContext bundleContext; /** * Buffer for resource files found. */ private static Hashtable> ressourcesFiles = new Hashtable>(); /** * A map of all skin image resources. */ private Map imageResources = null; /** * A map of all skin style resources. */ private Map styleResources = null; /** * A map of all skin color resources. */ private Map colorResources = null; /** * A map of all skin settings resources. */ private Map sttingsResources = null; /** * Starts the bundle. * @param bc BundleContext * @throws Exception - */ public void start(BundleContext bc) throws Exception { bundleContext = bc; Hashtable props = new Hashtable(); props.put(ResourcePack.RESOURCE_NAME, SkinPack.RESOURCE_NAME_DEFAULT_VALUE); bundleContext.registerService(SkinPack.class.getName(), this, props); } /** * Stops the bundle. * @param bc BundleContext * @throws Exception - */ public void stop(BundleContext bc) throws Exception {} /** * Returns a Map, containing all [key, value] pairs for image * resource pack. * * @return a Map, containing all [key, value] pairs for image * resource pack. */ public Map getImageResources() { if(imageResources != null) { return imageResources; } Map resources = new TreeMap(); try { ResourceBundle resourceBundle = ResourceBundle.getBundle(DEFAULT_IMAGE_RESOURCE_PATH); this.initResources(resourceBundle, resources); } catch (MissingResourceException ex) { logger.info("Failed to obtain bundle from image resource path.", ex); } this.initImagePluginResources(resources); imageResources = resources; return resources; } /** * Returns a Map, containing all [key, value] pairs for style * resource pack. * * @return a Map, containing all [key, value] pairs for style * resource pack. */ public Map getStyleResources() { if(styleResources != null) { return styleResources; } Map resources = new TreeMap(); try { ResourceBundle resourceBundle = ResourceBundle.getBundle(DEFAULT_STYLE_RESOURCE_PATH); this.initResources(resourceBundle, resources); } catch (MissingResourceException ex) { logger.info("Failed to obtain bundle from style resource path.", ex); } this.initStylePluginResources(resources); styleResources = resources; return resources; } /** * Returns a Map, containing all [key, value] pairs for color * resource pack. * * @return a Map, containing all [key, value] pairs for color * resource pack. */ public Map getColorResources() { if(colorResources != null) { return colorResources; } Map resources = new TreeMap(); try { ResourceBundle resourceBundle = ResourceBundle.getBundle(DEFAULT_COLOR_RESOURCE_PATH); this.initResources(resourceBundle, resources); } catch (MissingResourceException ex) { logger.info("Failed to obtain bundle from color resource path.", ex); } this.initColorPluginResources(resources); colorResources = resources; return resources; } /** * Returns a Map, containing all [key, value] pairs for color * resource pack. * * @return a Map, containing all [key, value] pairs for color * resource pack. */ public Map getSettingsResources() { if(sttingsResources != null) { return sttingsResources; } Map resources = new TreeMap(); try { ResourceBundle resourceBundle = ResourceBundle.getBundle(DEFAULT_SETTINGS_RESOURCE_PATH); this.initResources(resourceBundle, resources); } catch (MissingResourceException ex) { logger.info("Failed to obtain bundle from color resource path.", ex); } this.initSettingsPluginResources(resources); sttingsResources = resources; return resources; } /** * Returns a Map, containing all [key, value] pairs for this * resource pack. * * @return a Map, containing all [key, value] pairs for this * resource pack. */ public Map getResources() { ResourceBundle resourceBundle = ResourceBundle.getBundle(DEFAULT_RESOURCE_PATH); Map resources = new TreeMap(); this.initResources(resourceBundle, resources); resources.putAll(getImageResources()); resources.putAll(getStyleResources()); resources.putAll(getColorResources()); return resources; } /** * Returns the name of this resource pack. * * @return the name of this resource pack. */ public String getName() { Map resources = getResources(); String name = resources.get("display_name"); if(name != null) { return name + " Skin Resources"; } else { return "Skin Resources"; } } /** * Returns the description of this resource pack. * * @return the description of this resource pack. */ public String getDescription() { Map resources = getResources(); String name = resources.get("display_name"); if(name != null) { return "Provide SIP Communicator " + name + " skin resource pack."; } else { return "Provide SIP Communicator skin resource pack."; } } /** * Fills the given resource map with all (key,value) pairs obtained from the * given ResourceBundle. This method will look in the properties * files for references to other properties files and will include in the * final map data from all referenced files. * * @param resourceBundle The initial ResourceBundle, corresponding * to the "main" properties file. * @param resources A Map that would store the data. */ private void initResources( ResourceBundle resourceBundle, Map resources) { Enumeration colorKeys = resourceBundle.getKeys(); while (colorKeys.hasMoreElements()) { String key = colorKeys.nextElement(); String value = resourceBundle.getString(key); resources.put(key, value); } } /** * Finds all plugin image resources, matching the "images-*.properties" * pattern and adds them to this resource pack. * @param resources the map of key, value image resource pairs */ private void initImagePluginResources(Map resources) { Iterator pluginProperties = findResourcePaths("images", "images-*.properties"); while (pluginProperties.hasNext()) { String resourceBundleName = pluginProperties.next(); ResourceBundle resourceBundle = ResourceBundle.getBundle( resourceBundleName.substring( 0, resourceBundleName.indexOf(".properties"))); initResources(resourceBundle, resources); } } /** * Finds all plugin style resources, matching the "styles-*.properties" * pattern and adds them to this resource pack. * @param resources the map of key, value stype resource pairs */ private void initStylePluginResources(Map resources) { Iterator pluginProperties = findResourcePaths("styles", "styles-*.properties"); while (pluginProperties.hasNext()) { String resourceBundleName = pluginProperties.next(); ResourceBundle resourceBundle = ResourceBundle.getBundle( resourceBundleName.substring( 0, resourceBundleName.indexOf(".properties"))); initResources(resourceBundle, resources); } } /** * Finds all plugin color resources, matching the "colors-*.properties" * pattern and adds them to this resource pack. * @param resources the map of key, value color resource pairs */ private void initColorPluginResources(Map resources) { Iterator pluginProperties = findResourcePaths("colors", "colors-*.properties"); while (pluginProperties.hasNext()) { String resourceBundleName = pluginProperties.next(); ResourceBundle resourceBundle = ResourceBundle.getBundle( resourceBundleName.substring( 0, resourceBundleName.indexOf(".properties"))); initResources(resourceBundle, resources); } } /** * Finds all plugin style resources, matching the "styles-*.properties" * pattern and adds them to this resource pack. * * @param resources the map of key, value type resource pairs */ private void initSettingsPluginResources(Map resources) { Iterator pluginProperties = findResourcePaths("settings", "settings-*.properties"); while (pluginProperties.hasNext()) { String resourceBundleName = pluginProperties.next(); ResourceBundle resourceBundle = ResourceBundle.getBundle( resourceBundleName.substring( 0, resourceBundleName.indexOf(".properties"))); initResources(resourceBundle, resources); } } /** * Finds all properties files for the given path in this bundle. * * @param path the path pointing to the properties files. * @param pattern the pattern for properties files * (ex. "colors-*.properties") * @return an Iterator over a list of all properties files found * for the given path and pattern */ protected static Iterator findResourcePaths(String path, String pattern) { Iterator bufferedResult = ressourcesFiles.get(path + "/" + pattern); if (bufferedResult != null) { return bufferedResult; } ArrayList propertiesList = new ArrayList(); @SuppressWarnings ("unchecked") Enumeration propertiesUrls = bundleContext.getBundle() .findEntries(path, pattern, false); if (propertiesUrls != null) { while (propertiesUrls.hasMoreElements()) { URL propertyUrl = propertiesUrls.nextElement(); // Remove the first slash. String propertyFilePath = propertyUrl.getPath().substring(1); // Replace all slashes with dots. propertyFilePath = propertyFilePath.replaceAll("/", "."); propertiesList.add(propertyFilePath); } } Iterator result = propertiesList.iterator(); ressourcesFiles.put(path + pattern, result); return result; } }