Skip to content

Commit

Permalink
MONDRIAN: improve internationalization support.
Browse files Browse the repository at this point in the history
[git-p4: depot-paths = "//open/mondrian/": change = 2827]
  • Loading branch information
hhaas committed Nov 4, 2004
1 parent cd2434a commit 1512446
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 39 deletions.
82 changes: 53 additions & 29 deletions doc/schema.html
Expand Up @@ -26,35 +26,36 @@ <h2>Contents</h2>
<ol>
<li><a href="#What_is_a_schema">What is a schema?</a></li>
<li><a href="#Schema_files">Schema files</a></li>
<li><a href="#Cubes_and_dimensions">Cubes and dimensions</a></li>
<li><a href="#Star_schemas">Star schemas</a><ol>
<li><a href="#Shared_dimensions">Shared dimensions</a></li>
<li><a href="#Join_optimization">Join optimization</a></li>
</ol>
</li>
<li><a href="#Advanced_logical_constructs">Advanced logical constructs</a><ol>
<li><a href="#Virtual_cubes">Virtual cubes</a></li>
<li><a href="#Shared_dimensions">Shared dimensions</a></li>
<li><a href="#Parent_child_hierarchies">Parent-child hierarchies</a></li>
<li><a href="#Member_properties">Member properties</a></li>
</ol>
</li>
<li><a href="#Advanced_physical_constructs">Advanced physical constructs</a><ol>
<li><a href="#Member_readers">Member readers</a></li>
<li><a href="#Cell_readers">Cell readers</a></li>
<li><a href="#Cell_formatter">Cell formatter</a></li>
<li><a href="#Member_formatter">Member formatter</a></li>
</ol>
</li>
<li><a href="#Access_control">Access-control</a><ol>
<li><a href="#Defining_roles">Defining a role</a></li>
<li><a href="#Setting_a_connections_role">Setting a connection's role</a></li>
</ol>
</li>
<li><a href="#Other_stuff">Other stuff</a><ol>
<li><a href="#Cubes_and_dimensions">Logical model</a></li>
<li><a href="#Star_schemas">Star and snowflake schemas</a>
<ol>
<li><a href="#Shared_dimensions">Shared dimensions</a></li>
<li><a href="#Join_optimization">Join optimization</a></li>
</ol></li>
<li><a href="#Advanced_logical_constructs">Advanced logical constructs</a>
<ol>
<li><a href="#Virtual_cubes">Virtual cubes</a></li>
<li><a href="#Shared_dimensions">Shared dimensions</a></li>
<li><a href="#Parent_child_hierarchies">Parent-child hierarchies</a></li>
<li><a href="#Member_properties">Member properties</a></li>
</ol></li>
<li><a href="#Advanced_physical_constructs">Advanced physical constructs</a>
<ol>
<li><a href="#Member_readers">Member readers</a></li>
<li><a href="#Cell_readers">Cell readers</a></li>
<li><a href="#Cell_formatter">Cell formatter</a></li>
<li><a href="#Member_formatter">Member formatter</a></li>
<li><a href="#I18n">Internationalization</a></li>
</ol></li>
<li><a href="#Access_control">Access-control</a>
<ol>
<li><a href="#Defining_roles">Defining a role</a></li>
<li><a href="#Setting_a_connections_role">Setting a connection's role</a></li>
</ol></li>
<li><a href="#Other_stuff">Other stuff</a>
<ol>
<li><a href="#Format_strings">Format strings</a></li>
</ol>
</li>
</ol></li>
<li><a href="#Appendix_A_XML_elements">Appendix A: XML elements</a></li>
</ol>
<h2><a name="What_is_a_schema">What is a schema?</a></h2>
Expand Down Expand Up @@ -539,7 +540,6 @@ <h3><a name="Cell_formatter">Cell formatter</a></h3>
<h3><a name="Member_formatter">Member formatter</a></h3>
<p>A member formatter attribute demotes a java class to format a member's display value
returned by <code><a href="http://mondrian.sourceforge.net/api/mondrian/olap/Member.html#getCaption()">getCaption()</a></code>.</p>
<Level column="BUCHDAT" name="Buchungsdatum" uniqueMembers="false" formatter="com.tonbeller.bii.gwg.mondrian.MFBuchdat"/>
<blockquote>
<pre dir="ltr">&lt;<a href="#XML_Level">Level</a> column=&quot;column&quot; name=&quot;name&quot; formatter=&quot;com.foo.MyMemberFormatter&quot;&gt;</pre>
</blockquote>
Expand All @@ -548,7 +548,31 @@ <h3><a name="Member_formatter">Member formatter</a></h3>
<a href="http://mondrian.sourceforge.net/api/mondrian/olap/MemberFormatter.html">
interface mondrian.olap.MemberFormatter</a></code>.</p>

<h3><a name="#I18n">Internationalization</a></h3>
<p>Internationalized applications based on Mondrian could use multiple, language dependent schemas.<br/>
If so, the MDX statements would be language dependent too. This might be more difficult to maintain.<br/>
Instead of holding several copies of schema and MDX we provide a way to dynamically handle Mondrian schemas.<br/>
Calling <code><a href="http://mondrian.sourceforge.net/api/mondrian/olap/DriverManager.html#getConnection(mondrian.olap.Util.PropertyList, boolean)">DriverManager.getConnection()</a></code>
we can provide a property "DynamicSchemaProcessor" denoting the name of a class to implement the
<code><a href="http://mondrian.sourceforge.net/api/mondrian/olap/DynamicSchemaProcessor.html">DynamicSchemaProcessor</a></code> interface.<br/>
So any transformation can be applied to a Mondrian schema at runtime. A "dynamic" schema will not be cached by Mondrian.
</p><p>
To keep the MDX expressions free from language dependent names, it is a good idea to use the "caption" attribute,
which is supported for any Olap element.<br/>
</p><p>
<b><u>Examples</u></b><br/>
If your DynamicSchemaProcessor would support JSTL-like resolving of variables,<br>
you might use <code>caption</code> or <code>allMemberCaption</code> attributes as follows.

<blockquote>
<pre dir="ltr">&lt;<a href="#XML_Dimension">Dimension</a> name=&quot;Gender&quot; foreignKey=&quot;customer_id&quot; caption=&quot;${GENDER}&quot;&gt;</pre>
<pre dir="ltr">&lt;<a href="#XML_Hierarchy">Hierarchy</a> hasAll=&quot;true&quot; allMemberName=&quot;All Genders&quot; primaryKey=&quot;customer_id&quot; allMemberCaption=&quot;${GENDER}&quot;&gt;</pre>
<pre dir="ltr">&lt;<a href="#XML_Level">Level</a> name=&quot;Gender&quot; column=&quot;gender&quot; uniqueMembers=&quot;true&quot; caption=&quot;${GENDER}&quot;&gt;</pre>
<pre dir="ltr">&lt;<a href="#XML_Measure">Measure</a> name=&quot;Unit Sales&quot; column=&quot;unit_sales&quot; caption=&quot;${UNITSALES}&quot;&gt;</pre>
</blockquote>

A hierarchy with no <code>caption</code> defined would inherit the <code>caption</code> attribute from the dimension parent.
</p>
<h2><a name="Access_control">Access-control</a></h2>

<p>You've got all this great data, but you don't everyone to be able to read all
Expand Down
2 changes: 0 additions & 2 deletions src/main/mondrian/olap/Member.java
Expand Up @@ -53,8 +53,6 @@ public interface Member extends OlapElement, Comparable {
*/
String getParentUniqueName();

String getCaption();

/**
* Returns the type of member. Values are {@link #UNKNOWN_MEMBER_TYPE},
* {@link #REGULAR_MEMBER_TYPE}, {@link #ALL_MEMBER_TYPE}, {@link
Expand Down
37 changes: 33 additions & 4 deletions src/main/mondrian/olap/Mondrian.xml
Expand Up @@ -231,6 +231,12 @@ todo:
<Value>StandardDimension</Value>
<Value>TimeDimension</Value>
</Attribute>
<Attribute name="caption" required="false">
<Doc>
A string being displayed instead of the dimensions's name.
</Doc>
</Attribute>

<Array name="hierarchies" type="Hierarchy"><Doc></Doc></Array>
<Code>
// implement CubeDimension
Expand Down Expand Up @@ -278,6 +284,11 @@ todo:
called '(All)'.
</Doc>
</Attribute>
<Attribute name="allMemberCaption" required="false">
<Doc>
A string being displayed instead as the all member's name.
</Doc>
</Attribute>
<Attribute name="primaryKey">
<Doc>
The name of the column which identifies members, and
Expand All @@ -301,6 +312,12 @@ todo:
{@link Broadbase.olap.RolapConnection.MemberReader}.
</Doc>
</Attribute>
<Attribute name="caption" required="false">
<Doc>
A string being displayed instead of the hierarchie's name.
</Doc>
</Attribute>

<Object name="relation" type="Relation">
<Doc>
The {@link MondrianDef.Table table},
Expand Down Expand Up @@ -405,10 +422,16 @@ todo:
</Attribute>
<Attribute name="formatter" required="false">
<Doc>
Name of a formatter class for the member labels beeing displayed.
Name of a formatter class for the member labels being displayed.
The class must implement the mondrian.olap.MemberFormatter interface.
</Doc>
</Attribute>
<Attribute name="caption" required="false">
<Doc>
A string being displayed instead of the level's name.
</Doc>
</Attribute>

<Object name="keyExp" type="KeyExpression" required="false">
<Doc>
The SQL expression used to populate this level's key.
Expand Down Expand Up @@ -489,10 +512,16 @@ todo:
</Attribute>
<Attribute name="formatter" required="false">
<Doc>
Name of a formatter class for the appropriate property value beeing displayed.
Name of a formatter class for the appropriate property value being displayed.
The class must implement the mondrian.olap.PropertyFormatter interface.
</Doc>
</Attribute>
<Attribute name="caption" required="false">
<Doc>
A string being displayed instead of the name.
</Doc>
</Attribute>


</Element>

Expand Down Expand Up @@ -520,13 +549,13 @@ todo:
</Attribute>
<Attribute name="formatter" required="false">
<Doc>
Name of a formatter class for the appropriate cell beeing displayed.
Name of a formatter class for the appropriate cell being displayed.
The class must implement the mondrian.olap.CellFormatter interface.
</Doc>
</Attribute>
<Attribute name="caption" required="false">
<Doc>
A string beeing displayed instead of the name.
A string being displayed instead of the name.
</Doc>
</Attribute>
</Element>
Expand Down
1 change: 1 addition & 0 deletions src/main/mondrian/olap/OlapElement.java
Expand Up @@ -30,6 +30,7 @@ public interface OlapElement extends Exp
/** Returns the name of this element qualified by its class, for example
* "hierarchy 'Customers'". **/
String getQualifiedName();
String getCaption();
}

// End OlapElement.java
1 change: 1 addition & 0 deletions src/main/mondrian/olap/Property.java
Expand Up @@ -84,6 +84,7 @@ public int getType() {
public PropertyFormatter getFormatter() {
return null;
}
public abstract String getCaption();
}

// End Property.java
4 changes: 4 additions & 0 deletions src/main/mondrian/rolap/RolapDimension.java
Expand Up @@ -86,6 +86,10 @@ class RolapDimension extends DimensionBase {
if (cube != null) {
Util.assertTrue(cube.schema == schema);
}

if (xmlDimension.caption != null && xmlDimension.caption.length() >0 )
setCaption(xmlDimension.caption);

this.hierarchies = new RolapHierarchy[xmlDimension.hierarchies.length];
for (int i = 0; i < xmlDimension.hierarchies.length; i++) {
hierarchies[i] = new RolapHierarchy(cube, this, xmlDimension.hierarchies[i],
Expand Down
9 changes: 9 additions & 0 deletions src/main/mondrian/rolap/RolapHierarchy.java
Expand Up @@ -126,6 +126,15 @@ class RolapHierarchy extends HierarchyBase
.newHierarchyMustNotHaveMoreThanOneSource(getUniqueName());
}
this.foreignKey = xmlCubeDimension.foreignKey;
if (xmlHierarchy.caption != null && xmlHierarchy.caption.length() > 0)
setCaption(xmlHierarchy.caption);
else {
// inherit caption from dimension, if there is a special assignment
String dimCaption = dimension.getCaption();
if (!dimension.getName().equals(dimCaption))
setCaption(dimCaption);
}

}

public boolean equals(Object o) {
Expand Down
8 changes: 5 additions & 3 deletions src/main/mondrian/rolap/RolapLevel.java
Expand Up @@ -166,6 +166,8 @@ private Property lookupProperty(ArrayList list, String propertyName) {
(xmlLevel.uniqueMembers.booleanValue() ? UNIQUE : 0),
HideMemberCondition.lookup(xmlLevel.hideMemberIf),
LevelType.lookup(xmlLevel.levelType));
if (xmlLevel.caption != null && xmlLevel.caption.length() > 0)
setCaption(xmlLevel.caption);
if (xmlLevel.formatter != null && xmlLevel.formatter.length() > 0) {
// there is a special member formatter class
try {
Expand All @@ -178,21 +180,21 @@ private Property lookupProperty(ArrayList list, String propertyName) {
}
}

// helper for constructor
// helper for constructor
private static RolapProperty[] createProperties(
MondrianDef.Level xmlLevel) {
ArrayList list = new ArrayList();
final MondrianDef.Expression nameExp = xmlLevel.getNameExp();
if (nameExp != null) {
list.add(new RolapProperty(
Property.PROPERTY_NAME, Property.TYPE_STRING, nameExp, null));
Property.PROPERTY_NAME, Property.TYPE_STRING, nameExp, null, null));
}
for (int i = 0; i < xmlLevel.properties.length; i++) {
MondrianDef.Property property = xmlLevel.properties[i];
list.add(new RolapProperty(
property.name,
convertPropertyTypeNameToCode(property.type),
xmlLevel.getPropertyExp(i), property.formatter));
xmlLevel.getPropertyExp(i), property.formatter, property.caption));
}
return (RolapProperty[]) list.toArray(RolapProperty.emptyArray);
}
Expand Down
10 changes: 9 additions & 1 deletion src/main/mondrian/rolap/RolapProperty.java
Expand Up @@ -25,10 +25,12 @@ class RolapProperty extends Property {
static final RolapProperty[] emptyArray = new RolapProperty[0];

private PropertyFormatter formatter = null;
private String caption= null;

RolapProperty(String name, int type, MondrianDef.Expression exp, String formatterDef) {
RolapProperty(String name, int type, MondrianDef.Expression exp, String formatterDef, String caption) {
super(name, type);
this.exp = exp;
this.caption = caption;
if (formatterDef != null && formatterDef.length() > 0) {
// there is a special property formatter class
try {
Expand All @@ -48,6 +50,12 @@ public PropertyFormatter getFormatter() {
/** The column or expression which yields the property's value. */
MondrianDef.Expression exp;

/**
* @return Returns the caption.
*/
public String getCaption() {
return caption;
}
}

// End RolapProperty.java
5 changes: 5 additions & 0 deletions src/main/mondrian/rolap/SqlMemberSource.java
Expand Up @@ -309,6 +309,11 @@ private RolapMember[] getMembers(Connection jdbcConnection) {
null, (RolapLevel) hierarchy.getLevels()[0],
null, hierarchy.getAllMemberName(),
Member.ALL_MEMBER_TYPE);
// assign "all member" caption
if (hierarchy.xmlHierarchy.allMemberCaption != null &&
hierarchy.xmlHierarchy.allMemberCaption.length() > 0)
root.setCaption(hierarchy.xmlHierarchy.allMemberCaption );

root.ordinal = lastOrdinal++;
list.add(root);
}
Expand Down

0 comments on commit 1512446

Please sign in to comment.