Apply Internationalization to Schema
An internationalized Analyzer for MongoDB application would have a schema for each language, where the caption of each object appears in the local language. For example, the [Product]
dimension would have the caption "Product" in English and "Produit" in French.
It is not a good idea to translate the actual names of the schema objects, because then the MDX statements would need to be changed also. All that you need to change is the caption. Every schema object (schema, cube, dimension, hierarchy, level, measure, named set) has a caption attribute, and user interfaces such as JPivot and Pentaho Analyzer display the caption rather than the real name. Additional things to keep in mind include:
- Every schema object has a description attribute.
- A hierarchy can have an
allMemberCaption
attribute as display value of the "All" member. - For the schema, you can set a display value of the measures dimension by the
measuresCaption
attribute. - A calculated member has the properties CAPTION and DESCRIPTION that appear as caption and description if the member is a member of the
Measures
dimension.
One way to create an internationalized application is to create a copy of the schema file for each language, but these are difficult to maintain. A better way is to use the LocalizingDynamicSchemaProcessor
class to perform dynamic substitution on a single schema file.
Localize Schema Processor
First, write your schema using variables as values for caption
, description
, allMemberCaption
, and measuresCaption
attributes.
<Schema ... measuresCaption="%{foodmart.measures.caption}"> <Dimension name="Store" caption="%{foodmart.dimension.store.caption}" description="%{foodmart.dimension.store.description}"> <Hierarchy hasAll="true" allMemberName="All Stores" allMemberCaption="%{foodmart.dimension.store.allmember.caption =All Stores}" primaryKey="store_id" caption="%{foodmart.hierarchy.store.country.caption}" description="%{foodmart.hierararchy.store.country.description}> <Table name="store"/> <Level name="Store Country" column="store_country" uniqueMembers="true" caption="%{foodmart.dimension.store.country.caption}" description="%{foodmart.dimension.store.country.description}"/> <Level name="Store State" column="store_state" uniqueMembers="true" caption="%{foodmart.dimension.store.state.caption}" description="%{foodmart.dimension.store.state.description}"/> <Level name="Store City" column="store_city" uniqueMembers="false" caption="%{foodmart.dimension.store.city.caption}" description="%{foodmart.dimension.store.city.description}"/> <Level name="Store Name" column="store_name" uniqueMembers="true" caption="%{foodmart.dimension.store.name.caption}" description="%{foodmart.dimension.store.name.description}"> <Property name="Store Type" column="store_type" caption="%{foodmart.dimension.store. name.property_type.caption}" description="%{foodmart.dimension.store. name.property_type.description}"/> <Property name="Store Manager" column="store_manager" caption="%{foodmart.dimension.store. name.property_manager.caption}" description="%{foodmart.dimension.store. name.property_manager.description}"/> <Property name="Store Sqft" column="store_sqft" type="Numeric" caption="%{foodmart.dimension.store. name.property_storesqft.caption}" description="%{foodmart.dimension.store. name.property_storesqft.description}"/> <Property name="Grocery Sqft" column="grocery_sqft" type="Numeric"/> <Property name="Frozen Sqft" column="frozen_sqft" type="Numeric"/> <Property name="Meat Sqft" column="meat_sqft" type="Numeric"/> <Property name="Has coffee bar" column="coffee_bar" type="Boolean"/> <Property name="Street address" column="store_street_address" type="String"/> </Level> </Hierarchy> </Dimension> <Cube name="Sales" caption="%{foodmart.cube.sales.caption}" description="%{foodmart.cube.sales.description}"> ... <DimensionUsage name="Store" source="Store" foreignKey="store_id" caption="%{foodmart.cube.sales.name.caption}" description="%{foodmart.cube.sales.name.description}"/> ... <Measure name="Unit Sales" column="unit_sales" caption="%{foodmart.cube.sales.measure.unitsales.caption}" description="%{foodmart.cube.sales.measure.unitsales.description}"/> </Cube> </Schema>
As usual, the default caption for any cube, measure, dimension or level without a caption
attribute is the name of the element. A hierarchy's default caption is the caption of its dimension; for example, the [Store]
hierarchy has no caption
defined, so it inherits the caption
attribute from its parent, the [Store]
dimension.
Next, add the dynamic schema processor and locale to your connect string.
Provider=mondrian; Locale=en_US; DynamicSchemaProcessor=-mondrian.i18n.LocalizingDynamicSchemaProcessor; Jdbc=-jdbc:mysql://localhost/foodmart; JdbcUser=¬foodmart; JdbcPassword=-foodmart; Catalog=¬/WEB-INF/FoodMart.mondrian.xml
Now, for each locale you wish to support, provide a resource file named locale_{locale}.properties
.
# locale.properties: Default resources foodmart.measures.caption=Measures foodmart.dimension.store.country.caption=Store Country foodmart.dimension.store.name.property_type.column= store_type foodmart.dimension.store.country.member.caption= store_country foodmart.dimension.store.name.property_type.caption =Store Type foodmart.dimension.store.name.caption =Store Name foodmart.dimension.store.state.caption =Store State foodmart.dimension.store.name.property_manager.caption =Store Manager foodmart.dimension.store.name.property_storesqft.caption =Store Sq. Ft. foodmart.dimension.store.allmember.caption =All Stores foodmart.dimension.store.caption =Store foodmart.cube.sales.caption =Sales foodmart.dimension.store.city.caption =Store City foodmart.cube.sales.measure.unitsales =Unit Sales
and
# locale_hu.properties: Resources for the 'hu' locale. foodmart.measures.caption=Hungarian Measures foodmart.dimension.store.country.caption=Orsz\u00E1g foodmart.dimension.store.name.property_manager.caption =\u00C1ruh\u00E1z vezet\u0151 foodmart.dimension.store.country.member.caption =store_country_caption_hu foodmart.dimension.store.name.property_type.caption =Tipusa foodmart.dimension.store.name.caption =Megnevez\u00E9s foodmart.dimension.store.state.caption =\u00C1llam/Megye foodmart.dimension.store.name.property_type.column =store_type_caption_hu foodmart.dimension.store.name.property_storesqft.caption =M\u00E9ret n.l\u00E1b foodmart.dimension.store.allmember.caption =Minden \u00C1ruh\u00E1z foodmart.dimension.store.caption =\u00C1ruh\u00E1z foodmart.cube.sales.caption =Forgalom foodmart.dimension.store.city.caption =V\u00E1ros foodmart.cube.sales.measure.unitsales =Eladott db