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:
The Resource Provider Bundle is packed in the resprovider.jar file, located in the bundles directory of Framework Professional Edition Package .
|
The Resource Provider Bundle exports the com.prosyst.util.resprovider
package. It contains the API of the 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.
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.
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.
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 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).
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 = Oui2 = 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.
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.
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:
<resource-provider>...</resource-provider>
tags<resource>...</resource> tags. The
components (both required) of a resource description are:
<type>...</type> tags. The
resource type defines a name for the resource<file>...</file> tags. The
value of this tag must be <path>/<common_resource_name>.
It points to the location of the .properties file containing the
resources. It must be given without the ".properties" ending,
and without the country and language suffixes. For example, if you have
the following files: /resources/oven.properties containing the
images; /resources/oven_en_US.properties containing the resources
for US English locale; then the content of the <file>...</file>
section must be <file>/resources/oven</file>.
The value of this tag is case sensitive.<range>...</range> tags.
This component is mandatory if the resource file contains Integer resource
IDs. It specifies the range of the resource IDs. There can be more than
one range component in a resource description. The resulting range of
the resource IDs will be the union of all ranges specified by separate
<range>...</range> tags. In addition, the range
may include numbers that are not taken by any resource IDs.There may be more than one resource definition in the same XML file.
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)> ]> |
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> |
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? |
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();
}
. . .
|
There are two ways of specifying the resource types of interest for the importing bundle:
For example, the Resource-Type header may look like this:
Resource-Type: ICQ.oven, system
getString/getURL
method of the Resource Provider service. 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:
|
Tip: Type help to receive information about rp group commands.
The Resource Provider bundle uses the following system properties for debug:
|
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.