Skip to content

Commit

Permalink
XMLA driver now supports localized connections.
Browse files Browse the repository at this point in the history
Implementation is as follows. The driver passes connection's locale in as the
LocaleIdentifier property in metadata requests. As of change 14504,
MONDRIAN-367, mondrian observes the LocaleIdentifier of XMLA requests, and the
Sales cube in the FoodMart schema is localized into French and German. Since
each metadata element only contains caption and description of current locale,
switching locale causes metadata cache flush.)

Revert unintended change to buildJdk16.sh.


git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@470 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
julianhyde committed Aug 2, 2011
1 parent 3583e9f commit 6179da6
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 10 deletions.
2 changes: 1 addition & 1 deletion buildJdk16.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# built under JDK 1.6.

# Change the following line to point to your JDK 1.6 home.
export JAVA_HOME=/usr/local/jdk1.6.0_01
export JAVA_HOME=/usr/local/jdk1.6
export PATH=$JAVA_HOME/bin:$PATH
ant compile.compile

Expand Down
12 changes: 11 additions & 1 deletion foodmart/FoodMart.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
== Agreement, available at the following URL:
== http://www.eclipse.org/legal/epl-v10.html.
== Copyright (C) 2000-2002 Kana Software, Inc.
== Copyright (C) 2002-2009 Julian Hyde and others.
== Copyright (C) 2002-2011 Julian Hyde and others.
== All Rights Reserved.
== You must accept the terms of that agreement to use this software.
-->
Expand Down Expand Up @@ -115,6 +115,16 @@ WHERE "product"."product_class_id" = "product_class"."product_class_id"

<!-- Sales -->
<Cube name="Sales" defaultMeasure="Unit Sales">
<!-- Use annotations to provide translations of this cube's caption and
description into German and French. Use of annotations in this manner is
experimental and unsupported; just for testing right now. -->
<Annotations>
<Annotation name="caption.de_DE">Verkaufen</Annotation>
<Annotation name="caption.fr_FR">Ventes</Annotation>
<Annotation name="description.fr_FR">Cube des ventes</Annotation>
<Annotation name="description.de">Cube Verkaufen</Annotation>
<Annotation name="description.de_AT">Cube den Verkaufen</Annotation>
</Annotations>
<Table name="sales_fact_1997">
<!--
<AggExclude name="agg_l_03_sales_fact_1997" />
Expand Down
10 changes: 9 additions & 1 deletion src/org/olap4j/driver/xmla/DeferredNamedListImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2007-2010 Julian Hyde
// Copyright (C) 2007-2011 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand Down Expand Up @@ -59,6 +59,14 @@ class DeferredNamedListImpl<T extends Named>
? new Object[0] : restrictions;
}

/**
* Flushes the contents of the list. Next access will re-populate.
*/
void reset() {
state = State.NEW;
list.clear();
}

private NamedList<T> getList() {
switch (state) {
case POPULATING:
Expand Down
42 changes: 35 additions & 7 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
private XmlaOlap4jDatabase olap4jDatabase;

/**
* <p>Current schema.
* <p>Current catalog.
*/
private XmlaOlap4jCatalog olap4jCatalog;

Expand Down Expand Up @@ -114,7 +114,7 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
/**
* Root of the metadata hierarchy of this connection.
*/
private NamedList<XmlaOlap4jDatabase> olapDatabases;
private final NamedList<XmlaOlap4jDatabase> olapDatabases;

private final URL serverUrlObject;

Expand Down Expand Up @@ -660,7 +660,27 @@ public void setLocale(Locale locale) {
if (locale == null) {
throw new IllegalArgumentException("locale must not be null");
}
final Locale previousLocale = this.locale;
this.locale = locale;

// If locale has changed, clear the cache. This is necessary because
// metadata elements (e.g. Cubes) only store the caption & description
// of the current locale. The SOAP cache, if enabled, will speed things
// up a little if a client JVM uses connections to the same server with
// different locales.
if (!Olap4jUtil.equal(previousLocale, locale)) {
clearCache();
}
}

/**
* Clears the cache.
*/
private void clearCache() {
((DeferredNamedListImpl) this.olapDatabases).reset();
this.olap4jCatalog = null;
this.olap4jDatabase = null;
this.olap4jSchema = null;
}

public Locale getLocale() {
Expand Down Expand Up @@ -930,6 +950,15 @@ public String generateRequest(
buf.append("</Catalog>\n");
}

if (metadataRequest.allowsLocale()) {
final Locale locale1 = context.olap4jConnection.getLocale();
if (locale1 != null) {
buf.append("<LocaleIdentifier>");
xmlEncode(buf, locale1.toString());
buf.append("</LocaleIdentifier>");
}
}

buf.append(" <Content>");
xmlEncode(buf, content);
buf.append(
Expand Down Expand Up @@ -2260,6 +2289,10 @@ public boolean allowsCatalogName() {
public MetadataColumn getColumn(String name) {
return columnsByName.get(name);
}

public boolean allowsLocale() {
return name().startsWith("MDSCHEMA");
}
}

private static final Pattern LOWERCASE_PATTERN =
Expand Down Expand Up @@ -2310,8 +2343,3 @@ public SelectNode validateSelect(
}

// End XmlaOlap4jConnection.java





37 changes: 37 additions & 0 deletions testsrc/org/olap4j/ConnectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,43 @@ public void testConnectionUnwrap() throws SQLException {
olapConnection.setLocale(Locale.CANADA_FRENCH);
assertEquals(olapConnection.getLocale(), Locale.CANADA_FRENCH);

// Against mondrian, Sales cube is localized.
final OlapDatabaseMetaData metaData = olapConnection.getMetaData();
final String databaseName = metaData.getDatabaseProductName();
final String databaseVersion = metaData.getDatabaseProductVersion();
if (databaseName.equals("Mondrian XML for Analysis Provider")
&& databaseVersion.compareTo("3.3") > 0)
{
olapConnection.setLocale(Locale.US);
final Cube salesCubeUs =
olapConnection.getOlapSchema().getCubes().get("Sales");
assertEquals("Sales", salesCubeUs.getCaption());

// Switch locales. Note that we have to re-read metadata from the
// root (getOlapSchema()).
olapConnection.setLocale(Locale.GERMANY);
final Cube salesCubeGerman =
olapConnection.getOlapSchema().getCubes().get("Sales");
assertEquals("Verkaufen", salesCubeGerman.getCaption());
assertEquals("Cube Verkaufen", salesCubeGerman.getDescription());

olapConnection.setLocale(Locale.FRANCE);
final Cube salesCubeFrance =
olapConnection.getOlapSchema().getCubes().get("Sales");
assertEquals("Ventes", salesCubeFrance.getCaption());
assertEquals("Cube des ventes", salesCubeFrance.getDescription());

// The sales cube queried when the connection had a different
// locale has not been updated. According to the olap4j spec,
// behavior is undefined (e.g. the US sales cube might be invalid).
// In the xmla-olap4j driver, it stays valid but still shows the
// caption under the US locale.
assertEquals("Sales", salesCubeUs.getCaption());

// Reset locale.
olapConnection.setLocale(Locale.US);
}

// Try to set locale to null, should get error.
try {
olapConnection.setLocale(null);
Expand Down

0 comments on commit 6179da6

Please sign in to comment.