Resource Provider Bundle

The Resource Provider Bundle allows OSGi bundles to share their resources. This facilitates the internationalization and localization of user interface. The resources available in one bundle can be used by all other bundles that need the same resources.

Contents:


Bundle Information

Bundle JAR

The Resource Provider Bundle is packed in the resprovider.jar file, located in the bundles directory of Framework Professional Edition Package .

Import

Package Exporter Description
com.prosyst.mbs.framework.access System Bundle The Framework Access service for accessing some of the specific features of the mBS framework.
com.prosyst.util.hash System Bundle /
ProSyst Util Full Bundle
ProSyst hashtable utility.
com.prosyst.util.ref ProSyst Utility Bundle /
ProSyst Util Full Bundle
ProSyst utility for work with the OSGi Log Service.
com.prosyst.util.xml ProSyst XML-parsing utility.

Export

The Resource Provider Bundle exports the com.prosyst.util.resprovider package. It contains the API of the Resource Provider service.

Services

Resource Provider Service

The Resource Provider service is registered under the com.prosyst.util.resprovider.ResourceProvider interface. It detects the resources exported by bundles for use across the OSGi framework, and enables bundles needing to use such resources to import them.

All bundles that need to use resources provided by other bundles must get the Resource Provider service and use its methods for resource management. See Importing Resources.

Note that a bundle exporting resources does NOT need to communicate directly with the Resource Provider service. It only needs to describe the resourses in an XML file, and then specify the location of the file in its manifest. See Exporting Resources.

The Resource Provider service listens for the appearance of bundles with the Resource-Config manifest header. When such a bundle is installed, the Resource Provider parses its resource XML, and stores the found resources in a hashtable. When another bundle requests a resource, it is taken from the Resource Provider's hashtable of resources. When a bundle providing resources is updated or uninstalled, its resource records are updated or removed from the Resource Provider's hashtable.

Pluggable Commands

The Resource Provider Bundle registers the com.prosyst.util.pcommands.PluggableCommands service which contains the commands for listing available resource types of a bundle and bundles exporting a resource type. The Parser Service of the ProSyst Util Bundle detects the PluggableCommands service and submits these commands to requesting bundles, such as the Console and Telnet bundles.

Using the Resource Provider

Resource Management Overview

In an OSGi framework, there may be bundles that need to use resources as a way of providing more flexible user interface. Using resources is a standard technique in Java 2. It allows developers to provide settings such as UI messages, labels, images, fonts, colors, etc. in external .properties files, instead of in hardcoded parts of their applications. This may be useful for internationalization of applications, or for easy modification of application look-and-feel. The ProSyst Resource Provider allows multiple bundles to use the same resources.

Locales

The basic class used in Java internationalization is java.util.Locale. It represents a locale consisting of a country and language pair. Each application working with resources must have a locale defined as default locale. The default locale is the locale that will be searched for a resource definition if the current locale does not provide a definition for a used resource. All used resources in the application must have a definition at least for the default locale. This makes sure the application user will never see components without a label or image, for example. In the worst case, he/she will see messages/images in the default language for the system.

Resource Files

Resource files are UTF-8 encoded text files with the .properties extension.

The resources common for all locales must be contained in a <common_resource_name>.properties file. Such common resources are images, most often.

The resources for each different locale must be contained in a separate file having as suffix the country and language international abbreviations. The name of each .properties file must look like this:

<common_resource_name>_<language>_<country>.properties

For example: settings_en_US.properties, settings_fr_BE.properties, etc. In this example, "settings" is the common name of the resources, and the "en_US" and "fr_BE" specify the "American English" and "French Belgium" locales respectively.

Besides providing resources for locales, .properties files can provide resources for a language (without a country specified). This means that all locales having the same language will use the same .properties files. For example, if a file is named labels_en.properties, the properties specified in it will be available for both the "American English" and "British English" locales (as well as for all other locales that contain the English language).

Resource Properties

Each resource property has a resource ID and resource value. The ID, logically, identifies the property. It is the same for all locales. The resource value depends on the current locale. The resource is written in the following format in the .properties file:

<resource_id> = <resource_value>

The resource ID may be either String or Integer. The recommended type, however, is Integer, while String is considered deprecated.

The resource value is always String.

There are two kinds of resources:

Resources can be static or dynamic. Static resources always have the same value, for example:

1 = Oui
2 = Non

Other properties may have dynamic values. For example, you want to create a warning dialog saying in different languages: "The file with name <filename> will be deleted. Are you sure?". For the locales with English language, the property will look like this:

1 = The file with location {0} will be deleted. Are you sure?

For French locales, the property will look like this:

1 = Le fichier avec le nom {0} sera supprimé. Êtes-vous sûr?

For German locales, the property will look like this:

1 = Die Akte mit relativer Satznummer {0} wird gelöscht. Sind Sie sicher?    

The syntax of dynamic properties is:

 <resource_id> = <message_part_0> {0} <message_part_1> {1}    ... <message_part_n> {n} ...

Where <message_part> is the part of the String before or after the included parameter.

The unspecified parts of dynamic properties are defined later as parameters by the resource-importer.

The Resource Provider uses the java.text.MessageFormat utility class from the standard Java 2 Platform API for formatting the values of dynamic properties.

Resource Types

In the ProSyst Resource Provider, each resource has a resource type. When a bundle requests a property value, it must specify the resource types from which it needs the property. Different resource types may have the same property ID with different values, and the requester will be given only the value of the property from the specified resource type. A bundle may also declare more than one resource type of interest. In such case, the Resource Provider will pass to it the value of the first property with the specified ID found among the declared (preliminarily in the bundle manifest or later upon resource requesting) types.

Note: The resource type is case sensitive!

For more information about internationalization, please refer to the Java Internationalization Documentation from the Sun Microsystems Web site.

Exporting Resources

If a bundle needs to export resources for sharing with other bundles in the OSGi framework, it must describe the exported resources in an XML file with the following syntax:

The DTD of the resource provider XML is:

<!DOCTYPE resource-provider [
  <!ELEMENT resource-provider (resource)+>
  <!ELEMENT resource (type, file, range?)>
  <!ELEMENT type (#PCDATA)>
  <!ELEMENT file (#PCDATA)>
  <!ELEMENT range (#PCDATA)>
]>

Listing 1.1: Resource Provider DTD

An example of such an XML description file can be:

    <resource-provider>
      <resource>
        <type>ICQ.oven</type>
        <file>/resources/oven</file>
        <range>1:30</range>
</resource> <resource> <type>ICQ.dishwasher</type> <file>/resources/dishwasher</file> <range>1:5</range> <range>20:30</range>
</resource> </resource-provider>
Listing 1.2: Sample XML file describing the exported resources

The location of the XML file must be included in the bundle manifest as a value of the Resource-Config header. For example:

Resouce-Config: test/resources/oven.xml;

For example, the .properties file describing the resources for the US English locale may be named settings_EN_US.properties, and may look like this:

2 = First line
3 = Second line

1 = The file with location {0} will be deleted. Are you sure?
Listing 2: Sample .properties file containing resources

Importing Resources

To use a resource exported by another bundle, you need to get the Resource Provider service, and use its methods.

For getting the value of String properties, use some of the variants of the getString method of the Resource Provider service.

For getting the value of file URL properties, use some of the variants of the getURL method.

If you want to use a property with dynamic value, you need to specify the arguments defined in the property value on using the getString/getURL method.

If you want the same language & other locale settings to be used within the entire system, use the setLocale(java.util.Locale locale) method. After that, you can get all necessary resources without having to specify a locale.

The source example in Listing 3 illustrates getting the Resource Provider service and using it to take the values of several properties.

package test.resource.usage;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import com.prosyst.util.resprovider.ResourceProvider;
import java.util.Locale;

  . . .
  private ServiceReference refResourceProvider = null;
  private ResourceProvider resProvider = null;

  . . .       
    try {
       
      //Getting the Resource Provider                
      refResourceProvider = bc.getServiceReference(ResourceProvider.class.getName());
      if (refResourceProvider != null) { 
                        
        resProvider = (ResourceProvider) bc.getService(refResourceProvider);

        //Setting the current locale so we don't have to specify it 
        //each time we are getting a resource
        resProvider.setLocale(Locale.GERMAN);
		
        //Getting a String property
        String value = resProvider.getString(2);                        
        System.out.println("The value of the property with ID 2 is: " + value);

        //Getting a dynamic property
        String propWithArg = resProvider.getString("1", 
                                           new Object[] {"d:\\my_files\\my_file.del"}); 
        System.out.println("The value of the property with ID 1 is " + propWithArg);
                                
      }

    } catch (Exception e) {
      e.printStackTrace();                
    }
    . . .
Listing 3: Using the Resource Provider

There are two ways of specifying the resource types of interest for the importing bundle:

Console Commands

The Resource Provider Bundle plugs a new command group called rp into the Parser Service. mBS administrators can issue the commands in this group from the local runtime console and from a Telnet application.

The rp group commands allow one to list the resource types of a bundle as well as the bundles exporting a certain resource type.

After you start the ProSyst mBS, from the local runtime console or from a Telnet application, type cd rp or rp/ to enter the command group of the Resource Provider Bundle. The commands in the group are as follows:

Command Shortcut Description
list ls Lists available resource types.
typeInfo <type>[ <type>] t Lists the bundles exporting the specified resource type(s).
bundleInfo <bundleID>[ <bundleID>] b Lists the resource types exported by the specified bundle(s).

Tip: Type help to receive information about rp group commands.

System Properties

The Resource Provider bundle uses the following system properties for debug:

System Property Default Value Description
mbs.resprovider.debug false Defines if the Resource Provider will use the OSGi Log Service for storing debug information during its runtime performance.
mbs.resprovider.print false Shows if the generated debug information will be printed in the server console.

How to set system properties in ProSyst mBS is described in the System Properties document.

If you set/change these properties after the bundle has been activated, you must restart it so that it will accept the new values.

References


Utility Bundles