/*
* 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;
}
}