Home of: [Atelier "FUJIGURUMA"] >> [PageMixer hosted by SourceForge.net]

SEE "For Readers of English Version",
or Japanese version of this page

Render locale sensitively

This section explains how to render HTML page locale sensitively in PageMixer framework. In other words, it is how to use locale support utilities for multi-lingual application.

ATTENTION: PageMixer design explained in this section is changed from 2.x largely.

Overview

Class diagram

Class diagram in this section is shown below:

Class diagram
Class diagram (click for large figure)

Class names

In this tutorial, abbreviated class names are used. Complete names are shown below.

Classes of PageMixer framework

NotationFull name
ClassLoaderLocator jp.ne.dti.lares.foozy.pagemixer.page.ClassLoaderLocator
DefaultPage jp.ne.dti.lares.foozy.pagemixer.page.DefaultPage
LocalFSLocator jp.ne.dti.lares.foozy.pagemixer.page.LocalFSLocator
LocalePage jp.ne.dti.lares.foozy.pagemixer.page.LocalePage
Locator jp.ne.dti.lares.foozy.pagemixer.page.Locator
MonoPage jp.ne.dti.lares.foozy.pagemixer.page.MonoPage
Page jp.ne.dti.lares.foozy.pagemixer.page.Page
PageEntry jp.ne.dti.lares.foozy.pagemixer.page.PageEntry
PageEntryFactory jp.ne.dti.lares.foozy.pagemixer.page.PageEntryFactory
PageParser jp.ne.dti.lares.foozy.pagemixer.mixer.PageParser
PersistentProducer jp.ne.dti.lares.foozy.pagemixer.page.PersistentProducer
Producer jp.ne.dti.lares.foozy.pagemixer.mixer.Producer

Tutorial specific classes

NotationFull name
Bootstrap pagemixer.filter.Bootstrap
LocalePageSample pagemixer.filter.LocalePageSample
NopFilter pagemixer.filter.NopFilter

Concept

In earlier PageMixer, the purpose of 'locale sensitive renderring' is only to make multi-lingual application bulding up easier. So, utility classes focus only in 'locale sensitive'-ness. But, since PageMixer 3.0, 'page' is abstracted more systematicly.

At first, newly introduced concepts shwon below are explained.

'resource'
source of InputStream to instanciate Producer. for example, HTML file and serialized Producer can be 'resources'. one resource corresponds to one Producer.
'resource location'
symbolic name to identify 'resorce'. some 'resource locations' may point same 'resource'.
'page entry'
set of information for renderring. this consists of Producer instance, content type(e.g.: "text/html; charset=Windows-31J"), encoding(e.g.: "Windows-31J") and so on.
'page'
set of 'page entry'. to handle them as logical unit. this also manages relationship between them and 'resource location's.
'entry name'
symbolic name to identify 'page entry' in 'page'. some 'entry name' may point same 'page entry'.

Then, renderring procedure is divided into these parts.

'resource' management:
this encapsulate how to get InputSream of 'resource' corresponded to specified 'resource location', and how to know/compare last modified timestamp of 'resource'.
Producer instantiation:
this encapsulate how to instanciate Producer from InputStream of 'resource'.
'page entry' management:
this encapsulate how to determine 'resource location', content type, encoding and so on from specified 'entry name' and locale. in other words, this is just 'page' itself.

'resource' management

PageMixer provides "Locator" for 'resource' management.

PageMixer also provides "ClassLoaderLocator" for reading 'resource' in via ClassLoader, which is useful to read 'resource' in from packed JAR for example, and "LocalFSLocator" for reading 'resource' in from local file system.

NOTE: some other classes for Servlet environment are also provided, and explained in tutorial for Servlet.

Please see API document(and source code of implementation classes) for detail about Locator to implement your custom 'resource' management(e.g.: management in RDBMS).

Producer instantiation

PageMixer provides "Producer.Factory" for Producer instantiation. And both PageParser and PersistentProducer implements Producer.Factory, in fact.

'page entry' management

PageMixer provides "Page" for 'page entry' management, and some implementation classes described below.

Please see API document(and source code of implementation classes) for detail about Page to implement your custom 'page entry' management(e.g.: management in RDBMS).

MonoPage

At first, "MonoPage" is explained, even though it is not for locale sensitive contents. It is important to render non-ascii character set contents, in fact.

MonoPage manages only one relationship between 'entry name' and 'resource location'. And all of them are specified as parameters, shown below, of its constructor:

Construction example is shown below.


new MonoPage("text/html; charset=Windows-31J",
             "Windows-31J",
             "page/index.ja.html");

MonoPage

Some of construction paramaters can be omitted, and please see API document for detail.

LocalePage

"LocalePage" manages "1 : N" relationship between 'entry name' and 'resource location' to render locale sensitively.

This returns different 'resource location' and renderring information corresponded to specified locale, and it is implemented by ResourceBundle.

Construction parameter of this is only base name to look ResourceBundle up, but looked up ResourceBundle is used to look up the other information shown below.

When you construct LocalePage with "page.demosite.index" as base name of ResourceBundle, "page/demosite/index_ja.properties" may be described as shown below, for example.


contentType:text/html; charset=Windows-31J
encoding:Windows-31J
location:/WEB-INF/page/demosite/index.ja.html

example of *.properties file for "ja" locale

This configuration causes to:

ATTENTION: You should create *.properties file for the default locale of your web application explicitly, if system default locale of runtime environment is not as same as it, because ResourceBundle class looks up by system default locale before by EMPTY locale.

For example, "page/demosite/index_en.properties" file, which is as same as "page/demosite/index.properties", is needed when you provide web application, of which default locale is "en", in "ja" locale environment.

DefaultPage

"DefaultPage" is Page implementation to share same content type and encoding in 'page entry's. This returns fixed "content type" and "encoding" value specified at consttruction time, and returns specified 'entry name' value as 'resource location'.

This seems to be useful in Servlet environment more than in stand alone application environment, because it can be used to use specific content type and encoding for every '*.ja.html' request when you map Servlet using DefaultPage on URL pattern "*.ja.html", for example. It looks like "DefaultServlet" which reads "out of mapping" files in and creates response from them.

Conclusion

Comparison between Page implementation classes is shown below, and this will help you to choose one of them.

--- MonoPage LocalePage DefaultPage
locale sensitive renderring NO YES NO
acceptable # of URI 1 1 N
configuration per URI YES YES NO

Build up

For easy locale sensitive renderring, you should choose implementation classes of Locator, Producer.Factory and Page. In addition to it, you should combine them up for their co-operation.

PageMixer provides "PageEntryFactory" to combine them up easily, even though you can combine them up by your custom class, of course.

For example, code to combine ClassLoaderLocator, PageParser and LocalePage is as shown below.


String baseName = "page.demosite.index";

new PageEntryFactory(new LocalePage(baseName),
                     new ClassLoaderLocator(),
                     new PageParser());

Building up

Now, you can get "PageEntry", which contains content type/encoding/Producer and so on, corresponded to specified 'entry name' and locale via created PageEntryFactory.

Connect and mix

Now, everything needed are ready to use. Execution code is as below (see pagemixer.filter.LocalePageSample for detail).


final PageEntryFactory factory =
new PageEntryFactory(new LocalePage(baseName),
                     new ClassLoaderLocator(),
                     new PageParser());

try{
    Bootstrap bootstrap = new Bootstrap()
    {
        protected Producer createProducer()
            throws IOException, //
                   ClassNotFoundException //
        {
            PageEntry entry =
            factory.create(null, locale);
            return entry.getProducer();
        }
    };
    bootstrap.execute(new NopFilter());
}
catch(Exception e){
    e.printStackTrace(System.err);
}

Connect and Mix

In above example, baseName for PageEntryFactory construction is base name of ResourceBundle, and locale is the one in which result should be renderred.

Sample *.properties files for LocalePage are stored under "src/demo/servlet/war/WEB-INF/classes/page" of src/bin distributions, and these require HTML files under "src/demo/servlet/war". So, you should specify path to "src/demo/servlet/war/WEB-INF/classes" and "src/demo/servlet/war" of src/bin distribution as one of CLASSPATH element, if you want to execute sample as stand-alone application.