Oracle9iAS Portal Developer Kit
How to Build a Multi Language Java Portlet using
PDK-Java v2
This article shows you how to build a Java portlet using PDK-Java v2 that
can be rendered in different languages. The language used in your portlet
will depend upon on the language setting that has been chosen in the Portal
that is displaying it. Once you have completed this article you will easily
be able to write your portlets to support as many or as few languages as
you want them to, or convert your existing portlet to support multiple languages.
Once a portlet is written to support multiple languages, it is an easy process
to plug in new languages as and when you want to.
ASSUMPTIONS
- You have followed through and understood the articles How To Build
A Java Portlet Using PDK-Java v2.
- All of the assumptions in the above article apply here too.
INTERNATIONALIZING YOUR PORTLET
PROVIDING TRANSLATIONS FOR PORTLET CONTENT
In the previous article How To Build A
Java Portlet Using PDK-Java v2 you created a portlet that printed a message
on the screen. This message is only available in one language and the text
to be displayed is hard-coded in to the portlet's renderer class. To make
your portlets available in multiple languages you have to store such language
dependent elements in their own classes, known as resource bundles.
Below is the show mode renderer class, MyCustomRenderer
from the previous article. The language dependent elements are shown in bold.
import java.io.*; import oracle.portal.provider.v2.*; import oracle.portal.provider.v2.render.*; import oracle.portal.provider.v2.render.http.*; public class MyCustomRenderer extends BaseManagedRenderer { public void renderBody(PortletRenderRequest pr) throws PortletException { try { // Get a writer for this renderer's output PrintWriter out = pr.getWriter();
// Generate output and send to the writer out.println("<b>Hi " + pr.getUser().getName() + "!</b><br>"); out.println("This output was generated by my very own renderer!");
} catch (IOException ioe) { throw new PortletException(ioe);
} } }
|
Creating Resource Bundles
For each language you want your portlet to be available in, you will need
a resource bundle. You will also need to create a 'default' resource bundle
that will be used when there is no resource bundle corresponding to the language
setting chosen in the portal.
Create A Default Resource Bundle
- First create your default resource bundle. Using your favourite text
editor, create a Java class called MyProviderBundle,
that extends ListResourceBundle from the java.util package. The class should contain a multi-dimensional
array of objects, that holds key-value pairs representing each of the language
dependent elements from MyCustomRenderer. This
is demonstrated in the following code:
import java.util.ListResourceBundle;
public class MyProviderBundle extends ListResourceBundle { public static String HELLO_MSG = "FirstPortletHelloMessage"; public static String INFO_MSG = "FirstPortletInfoMessage";
public Object[][] getContents() { return contents; } static private final Object[][] contents = { {HELLO_MSG, "Hi"}, {INFO_MSG, "This output was generated by my very own renderer!"} }; }
|
- Save MyProviderBundle in the same place
as MyCustomRenderer.
- Compile MyProviderBundle using the instructions
outlined in How
To Build A Java Portlet Using PDK-Java v2.
Creating Resource Bundles For Other Supported Languages
Now you must create a resource bundle class for each language you want
your portlet to support. Each of these classes must be named the same as
your default resource bundle class, but with a language code appended to
the end. For example, if you want to support the French language, create
a Java class named MyProviderBundle_fr. The
language code fr is the same as the code that
will be used by the locale object in the portal if the language setting
is set to French ( for more information on Locales, see the JavaDoc
for java.util.Locale). When you change the language
setting in Oracle9iAS Portal, you change the value of the current
locale object and therefore the locale object's language code. These language
codes adhere to the ISO:639
codes for representation for names of languages.
- To create a French resource bundle, create a Java class named MyProviderBundle_fr, as described in the paragraph
above.
- Using your default resource bundle as a template, replace the English
language strings with their French equivalents. An example is given below:
import java.util.ListResourceBundle;
public class MyProviderBundle_fr extends ListResourceBundle { public Object[][] getContents() { return contents; } static private final Object[][] contents = { {MyProviderBundle.HELLO_MSG, "Bonjour"}, {MyProviderBundle.INFO_MSG, "Ça rendement était produire près de mon véritable propre rendre!"}
}; }
|
- Save MyProviderBundle_fr in the same place
as MyProviderBundle and MyCustomRenderer.
- Compile MyProviderBundle_fr using the
instructions outlined in How To Build
A Java Portlet Using PDK-Java v2.
- Repeat the above four steps for every language that you wish to create
a resource bundle for, updating the class name with the appropriate language
code and the message strings with their equivalent in the appropriate language.
Updating Your Renderer
To make use of the resource bundles you have just created you now need
to update MyCustomRenderer, replacing the hard-coded
messages with references that will pick up the messages at run time from
the resource bundle that corresponds most closely with the locale object
of the portal.
- Open up MyCustomRenderer and change it
so that it contains the code listed below. Updates are shown in bold text.
import java.io.*; import java.util.ResourceBundle;
import oracle.portal.provider.v2.*;
import oracle.portal.provider.v2.render.*;
import oracle.portal.provider.v2.render.http.*;
public class MyCustomRenderer extends BaseManagedRenderer
{
public void renderBody(PortletRenderRequest pr) throws PortletException
{
try
{
// Get a writer for this renderer's output
PrintWriter out = pr.getWriter();
// Get a resource bundle object for the current language ResourceBundle b = ResourceBundle.getBundle("MyProviderBundle",pr.getLocale());
// Generate output and send to the writer out.println("<b>" + b.getString(MyProviderBundle.HELLO_MSG) + " " + pr.getUser().getName() + "!</b><br>"); out.println(b.getString(MyProviderBundle.INFO_MSG));
}
catch (IOException ioe)
{
throw new PortletException(ioe);
}
}
}
|
- Save MyCustomRenderer.
- Compile MyCustomRenderer using the instructions
outlined in How
To Build A Java Portlet Using PDK-Java v2.
PROVIDING TRANSLATIONS FOR PORTLET ATTRIBUTES
In your provider's definition file, provider.xml,
a number of attributes describing your portlet are defined such as the portlets
name and description, these are used in places, for example in your portlet's
title bar in show mode and so should be translated too. There are two different
ways of providing these translations, which one you choose is up to you.
Both of these methods are outlined below:
METHOD 1 - USING RESOURCE BUNDLES AT PROVIDER LEVEL
You can provide translations for your portlet attributes in your resource
bundle(s), then specify that you want to use these resource bundle in provider.xml, specifying the keys you have used in
your resource bundles. Using this method you can use the keys you want to,
and as long as you use different keys for each corresponding attribute in
your provider's various portlets you can have just one set of resource bundles
that all of your provider's portlets can use.
Updating Your Resource Bundles
- Open your default resource bundle, MyProviderBundle.java.
- Update it so that it looks like the code example below. Additions to
the existing class are shown in bold
import java.util.ListResourceBundle;
public class MyProviderBundle extends ListResourceBundle { public static String HELLO_MSG = "FirstPortletHelloMessage"; public static String INFO_MSG = "FirstPortletInfoMessage"; public static String PORTLET_NAME = "FirstPortletName"; public static String PORTLET_TITLE = "FirstPortletTitle"; public static String PORTLET_SHORT_TITLE = "FirstPortletShortTitle"; public static String PORTLET_DESCRIPTION = "FirstPortletDescription"; public static String TIMEOUT_MESSAGE = "FirstPortletTimeoutMessage";
public Object[][] getContents()
{
return contents;
}
static private final Object[][] contents =
{
{HELLO_MSG, "Hi"},
{INFO_MSG, "This output was generated by my very own renderer!"},
{PORTLET_NAME, "MyFirstPortlet"}, {PORTLET_TITLE, "My First Portlet"}, {PORTLET_SHORT_TITLE, "MyFirstPortlet"}, {PORTLET_DESCRIPTION, "My first ever portlet, using my own custom renderer"}, {TIMEOUT_MESSAGE, "Timed out waiting for MyFirstPortlet"}
};
}
|
- Save and close MyProviderBundle.java.
- Open MyProviderBundle_fr.java. Change
it so that it contains the code listed below, again, updates are in bold
text.
import java.util.ListResourceBundle;
public class MyProviderBundle_fr extends ListResourceBundle { public Object[][] getContents() { return contents; } static private final Object[][] contents = { {MyProviderBundle.HELLO_MSG, "Bonjour"}, {MyProviderBundle.INFO_MSG, "Ça rendement était produire près de mon véritable propre rendre!"}, {MyProviderBundle.PORTLET_NAME, "MonPremierPortlet"}, {MyProviderBundle.PORTLET_TITLE, "Mon Premier Portlet"}, {MyProviderBundle.PORTLET_SHORT_TITLE, "MonPremierPortlet"}, {MyProviderBundle.PORTLET_DESCRIPTION, "Mon premièrement jamais portlet, l'utilisation de mon propre renderer de coutume"}, {MyProviderBundle.TIMEOUT_MESSAGE, "Chronométré hors attendre MyFirstPortlet"}
};
}
|
- Save and close MyProviderBundle_fr.java.
- Compile both MyProviderBundle.java and
MyProviderBundle_fr.java using the instructions
outlined in How
To Build A Java Portlet Using PDK-Java v2.
Updating Provider.xml
- Open up the provider.xml file you created
in How To Build
A Java Portlet Using PDK-Java v2.
- Update the file as shown below, all additions are shown in bold.
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <?providerDefinition version="3.1"?> <provider class="oracle.portal.provider.v2.DefaultProviderDefinition"> <session>false</session> <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition"> <id>1</id> <resource>MyProviderBundle</resource> <nameKey>FirstPortletName</nameKey> <titleKey>FirstPortletTitle</titleKey> <ShortTitleKey>FirstPortletShortTitle</ShortTitleKey> <descriptionKey>FirstPortletDescription</descriptionKey>
<timeout>10</timeout>
<timeoutMessageKey>FirstPortletTimeoutMessage</timeoutMessageKey>
<renderer class="oracle.portal.provider.v2.render.RenderManager">
<showPage class="MyCustomRenderer"/>
</renderer>
</portlet>
</provider>
|
- Save and close provider.xml.
METHOD 2 - CREATING RESOURCE BUNDLES AT PORTLET
LEVEL.
PDK Java-v2 defines a set of resource bundle keys
that you can use for providing translations for your portlet attributes.
Making use of these keys means that you don't have to specify the resource
bundle keys you have used in your provider.xml
file, as we did in the method 1 example. However, this does mean that you
will have to provide a separate set of resource bundles for each portlet
in your provider as the keys you use for each portlet will need to be the
same, but their values will differ.
Updating Your Resource Bundles
- Open your default resource bundle, MyProviderBundle.java.
- Update it so that it looks like the code example below. Updates to
the existing class are shown in bold
import java.util.ListResourceBundle; import oracle.portal.provider.v2.PortletConstants;
public class MyProviderBundle extends ListResourceBundle { public static String HELLO_MSG = "FirstPortletHelloMessage"; public static String INFO_MSG = "FirstPortletInfoMessage";
public Object[][] getContents() { return contents; } static private final Object[][] contents = { {HELLO_MSG, "Hi"}, {INFO_MSG, "This output was generated by my very own renderer!"}, {PortletConstants.NAME, "MyFirstPortlet"}, {PortletConstants.TITLE, "My first portlet"}, {PortletConstants.SHORTTITLE, "MyFirstPortlet"}, {PortletConstants.DESCRIPTION, "My first ever portlet, using my own custom renderer"}, {PortletConstants.TIMEOUTMSG, "Timed out waiting for MyFirstPortlet"}
};
}
|
- Save and close MyProviderBundle.java.
- Open MyProviderBundle_fr.java. Change
it so that it contains the code listed below, again, updates are in bold
text.
import java.util.ListResourceBundle; import oracle.portal.provider.v2.PortletConstants;
public class MyProviderBundle_fr extends ListResourceBundle { public Object[][] getContents() { return contents; } static private final Object[][] contents = { {MyProviderBundle.HELLO_MSG, "Bonjour"}, {MyProviderBundle.INFO_MSG, "Ça rendement était produire près de mon véritable propre rendre!"}, {PortletConstants.NAME, "MonPremierPortlet"}, {PortletConstants.TITLE, "Mon Premier Portlet"}, {PortletConstants.SHORTTITLE, "MonPremierPortlet"}, {PortletConstants.DESCRIPTION, "Mon premièrement jamais portlet, l'utilisation de mon propre renderer de coutume"}, {PortletConstants.TIMEOUTMSG, "Chronométré hors attendre MyFirstPortlet"}
};
}
|
- Save and close MyProviderBundle_fr.java.
- Compile both MyProviderBundle.java and
MyProviderBundle_fr.java using the instructions
outlined in How
To Build A Java Portlet Using PDK-Java v2.
Updating Provider.xml
- Open up the provider.xml file you created
in How To Build
A Java Portlet Using PDK-Java v2.
- Update the file as shown below, all updates are shown in bold.
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <?providerDefinition version="3.1"?> <provider class="oracle.portal.provider.v2.DefaultProviderDefinition"> <session>false</session> <portlet class="oracle.portal.provider.v2.DefaultPortletDefinition"> <id>1</id> <resource>MyProviderBundle</resource> <timeout>10</timeout> <renderer class="oracle.portal.provider.v2.render.RenderManager"> <showPage class="MyCustomRenderer"/> </renderer> </portlet> </provider>
|
- Save and close provider.xml.
For more information on Java Internationalization see the Internationalization
trail of the JavaTM Tutorial.
CONFIGURING OC4J
To update your portlet's provider and install that provider into OC4J,
see the article Packaging
and Deploying Your Provider, updating the provider with the files that
you have changed and created in this tutorial.
VIEWING THE PORTLET
Once you have updated your provider and reinstalled it into OC4J, refresh
the portal page containing your portlet. To see your resource bundles working,
add the "Set Language" portlet to your page and try changing the language
setting to French. Remember that the default resource bundle is English,
and that selecting any other language that doesn't have a corresponding resource
bundle will result in the portlet being displayed in English.
Revision History: