Skip to content

Commit

Permalink
Fix XMLA teste and XMLA driver for DBCP.
Browse files Browse the repository at this point in the history
git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@89 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
julianhyde committed Apr 13, 2008
1 parent 22e6f32 commit 8a3e97d
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 67 deletions.
38 changes: 21 additions & 17 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
/**
* <p>Holds on to the provider name
*/
private String providerName = null;
private String providerName;

/**
* <p>Holds on to the datasource name.
*/
private String datasourceName = null;
private String datasourceName;

/**
* <p>Holds on to the datasource name as specified by the
Expand All @@ -90,7 +90,9 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
* query value.
*
*/
private String nativeDatasourceName = null;
private String nativeDatasourceName;
private boolean autoCommit;
private boolean readOnly;

/**
* <p>Creates an Olap4j connection an XML/A provider.
Expand Down Expand Up @@ -122,12 +124,7 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
throw new AssertionError(
"does not start with '" + CONNECT_STRING_PREFIX + "'");
}
String x = url.substring(CONNECT_STRING_PREFIX.length());
Map<String, String> map =
ConnectStringParser.parseConnectString(x);
for (Map.Entry<String,String> entry : toMap(info).entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
Map<String, String> map = parseConnectString(url, info);

this.providerName = map.get(XmlaOlap4jDriver.Property.Provider.name());
this.datasourceName = map.get(XmlaOlap4jDriver.Property.DataSource.name());
Expand Down Expand Up @@ -170,13 +167,20 @@ abstract class XmlaOlap4jConnection implements OlapConnection {
this.olap4jSchema = new XmlaOlap4jSchema(catalog, catalogName);
}

static Map<String, String> parseConnectString(String url, Properties info) {
String x = url.substring(CONNECT_STRING_PREFIX.length());
Map<String, String> map =
ConnectStringParser.parseConnectString(x);
for (Map.Entry<String,String> entry : toMap(info).entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}

static boolean acceptsURL(String url) {
return url.startsWith(CONNECT_STRING_PREFIX);
}




// not part of public API
String getDataSourceInfo() throws OlapException
{
Expand Down Expand Up @@ -285,11 +289,11 @@ public String nativeSQL(String sql) throws SQLException {
}

public void setAutoCommit(boolean autoCommit) throws SQLException {
throw new UnsupportedOperationException();
this.autoCommit = autoCommit;
}

public boolean getAutoCommit() throws SQLException {
throw new UnsupportedOperationException();
return autoCommit;
}

public void commit() throws SQLException {
Expand Down Expand Up @@ -317,11 +321,11 @@ public NamedList<Catalog> getCatalogs() {
}

public void setReadOnly(boolean readOnly) throws SQLException {
throw new UnsupportedOperationException();
this.readOnly = readOnly;
}

public boolean isReadOnly() throws SQLException {
throw new UnsupportedOperationException();
return readOnly;
}

public void setCatalog(String catalog) throws SQLException {
Expand Down Expand Up @@ -607,7 +611,7 @@ Element xxx(String request) throws OlapException {
* values of the restriction)
*
* <p>This signature only relays the execution to
* {@link XmlaOlap4jConnection.generateRequest(Context,MetadataRequest,Object[])}
* {@link #generateRequest(Context,MetadataRequest,Object[])}
* but passes it a true value to mark any request as datasource name
* specific.
*
Expand Down
94 changes: 69 additions & 25 deletions src/org/olap4j/driver/xmla/XmlaOlap4jDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package org.olap4j.driver.xmla;

import org.olap4j.impl.Base64;
import org.olap4j.impl.Olap4jUtil;

import java.io.*;
import java.net.URL;
Expand Down Expand Up @@ -48,20 +49,27 @@
*
* <h3>Connection properties</h3>
*
* <p>Unless otherwise stated, properties are optional. If a property occurs
* multiple times in the connect string, the first occurrence is used.
*
* <table border="1">
* <tr> <th>Property</th> <th>Description</th> </tr>
*
* <tr> <td>Server</td> <td>URL of HTTP server.</td> </tr>
* <tr> <td>Server</td> <td>URL of HTTP server. Required.</td> </tr>
*
* <tr> <td>Catalog</td> <td>Catalog name to use</td> </tr>
* <tr> <td>Catalog</td> <td>Catalog name to use. Required.</td> </tr>
*
* <tr> <td>Provider</td> <td>Name of the XMLA provider. This option is facultative. By default, the first one available will be used.</td> </tr>
* <tr> <td>Provider</td> <td>Name of the XMLA provider.</td> </tr>
*
* <tr> <td>DataSource</td> <td>Name of the XMLA datasource. This option is facultative. By default, the first one available will be used. When using a Mondrian backed XMLA server, be sure to include the full datasource name between quotes.</td> </tr>
* <tr> <td>DataSource</td> <td>Name of the XMLA datasource. When using a
* Mondrian backed XMLA server, be sure to
* include the full datasource name between
* quotes.</td> </tr>
*
* <tr> <td>UseThreadProxy</td> <td>If true, use the proxy object in the
* {@link #THREAD_PROXY} field. For testing.
* Default is false.</td> </tr>
* <tr> <td>TestProxyCookie</td> <td>String that uniquely identifies a proxy
* object in {@link #PROXY_MAP} via which to
* send XMLA requests for testing
* purposes.</td> </tr>
*
* </table>
*
Expand All @@ -71,9 +79,9 @@
*/
public class XmlaOlap4jDriver implements Driver {
public static final String NAME = "olap4j driver for XML/A";
public static final String VERSION = "0.9.4";
public static final String VERSION = "0.9.5";
public static final int MAJOR_VERSION = 0;
public static final int MINOR_VERSION = 904;
public static final int MINOR_VERSION = 905;
private final Factory factory;

/**
Expand All @@ -82,6 +90,8 @@ public class XmlaOlap4jDriver implements Driver {
private static final ExecutorService executor =
Executors.newCachedThreadPool();

private static int nextCookie;

static {
try {
register();
Expand All @@ -93,6 +103,9 @@ public class XmlaOlap4jDriver implements Driver {
}
}

/**
* Creates an XmlaOlap4jDriver.
*/
protected XmlaOlap4jDriver() {
String factoryClassName;
try {
Expand All @@ -115,6 +128,11 @@ protected XmlaOlap4jDriver() {
}
}

/**
* Registers this driver.
*
* @throws SQLException on error
*/
private static void register() throws SQLException {
DriverManager.registerDriver(new XmlaOlap4jDriver());
}
Expand All @@ -123,7 +141,9 @@ public Connection connect(String url, Properties info) throws SQLException {
if (!XmlaOlap4jConnection.acceptsURL(url)) {
return null;
}
Proxy proxy = createProxy(info);
Map<String, String> map =
XmlaOlap4jConnection.parseConnectString(url, info);
Proxy proxy = createProxy(map);
return factory.newConnection(proxy, url, info);
}

Expand Down Expand Up @@ -166,23 +186,30 @@ public boolean jdbcCompliant() {
* implementation, for testing, which talks to mondrian's XMLA service
* in-process.
*
* @param info Connection properties
* @param map Connection properties
* @return A Proxy with which to submit XML requests
*/
protected Proxy createProxy(Properties info) {
String useThreadProxy =
info.getProperty(
Property.UseThreadProxy.name());
if (useThreadProxy != null &&
Boolean.valueOf(useThreadProxy)) {
Proxy proxy = THREAD_PROXY.get();
protected Proxy createProxy(Map<String, String> map) {
String cookie = map.get(Property.TestProxyCookie.name());
if (cookie != null) {
Proxy proxy = PROXY_MAP.get(cookie);
if (proxy != null) {
return proxy;
}
}
return new HttpProxy();
}

/**
* Returns a future object representing an asynchronous submission of an
* XMLA request to a URL.
*
* @param proxy Proxy via which to send the request
* @param url URL of XMLA server
* @param request Request
* @return Future object from which the byte array containing the result
* of the XMLA call can be obtained
*/
public Future<byte[]> getFuture(
final Proxy proxy,
final URL url,
Expand Down Expand Up @@ -282,25 +309,42 @@ public String getEncodingCharsetName() {
}

/**
* For testing.
* For testing. Map from a cookie value (which is uniquely generated for
* each test) to a proxy object. Uses a weak hash map so that, if the code
* that created the proxy 'forgets' the cookie value, then the proxy can
* be garbage-collected.
*/
public static final ThreadLocal<Proxy> THREAD_PROXY =
new ThreadLocal<Proxy>();
public static final Map<String, Proxy> PROXY_MAP =
Collections.synchronizedMap(new WeakHashMap<String, Proxy>());

/**
* Generates and returns a unique string.
*
* @return unique string
*/
public static synchronized String nextCookie() {
return "cookie" + nextCookie++;
}

/**
* Properties supported by this driver.
*/
public enum Property {
UseThreadProxy(
"If true, use the proxy object in the THREAD_PROXY field. "
+ "For testing. Default is false."),

TestProxyCookie(
"String that uniquely identifies a proxy object via which to send "
+ "XMLA requests for testing purposes."),
Server("URL of HTTP server"),
Catalog("Catalog name"),
Provider("Name of the datasource provider"),
DataSource("Name of the datasource");

/**
* Creates a property.
*
* @param description Description of property
*/
Property(String description) {
Olap4jUtil.discard(description);
}
}
}
Expand Down
42 changes: 17 additions & 25 deletions testsrc/org/olap4j/XmlaTester.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/
public class XmlaTester implements TestContext.Tester {
final XmlaOlap4jDriver.Proxy proxy;
final String cookie;
private Connection connection;

/**
Expand Down Expand Up @@ -57,6 +58,8 @@ public XmlaTester()
this.proxy =
(XmlaOlap4jDriver.Proxy) constructor.newInstance(
catalogNameUrls, urlString);
this.cookie = XmlaOlap4jDriver.nextCookie();
XmlaOlap4jDriver.PROXY_MAP.put(cookie, proxy);
}

public Connection createConnection() throws SQLException {
Expand All @@ -68,21 +71,14 @@ public Connection createConnection() throws SQLException {
} catch (ClassNotFoundException e) {
throw new RuntimeException("oops", e);
}
try {
XmlaOlap4jDriver.THREAD_PROXY.set(proxy);
Properties info = new Properties();
info.setProperty(
XmlaOlap4jDriver.Property.UseThreadProxy.name(), "true");
info.setProperty(
XmlaOlap4jDriver.Property.Catalog.name(), "FoodMart");
connection =
DriverManager.getConnection(
getURL(),
info);
return connection;
} finally {
XmlaOlap4jDriver.THREAD_PROXY.set(null);
}
Properties info = new Properties();
info.setProperty(
XmlaOlap4jDriver.Property.Catalog.name(), "FoodMart");
connection =
DriverManager.getConnection(
getURL(),
info);
return connection;
}

public Connection createConnectionWithUserPassword() throws SQLException {
Expand All @@ -91,15 +87,11 @@ public Connection createConnectionWithUserPassword() throws SQLException {
} catch (ClassNotFoundException e) {
throw new RuntimeException("oops", e);
}
try {
XmlaOlap4jDriver.THREAD_PROXY.set(proxy);
Properties info = new Properties();
info.setProperty("UseThreadProxy", "true");
return DriverManager.getConnection(
getURL(), USER, PASSWORD);
} finally {
XmlaOlap4jDriver.THREAD_PROXY.set(null);
}
Properties info = new Properties();
info.setProperty(
XmlaOlap4jDriver.Property.Catalog.name(), "FoodMart");
return DriverManager.getConnection(
getURL(), USER, PASSWORD);
}

public String getDriverUrlPrefix() {
Expand All @@ -111,7 +103,7 @@ public String getDriverClassName() {
}

public String getURL() {
return "jdbc:xmla:Server=http://foo;UseThreadProxy=true";
return "jdbc:xmla:Server=http://foo;Catalog=FoodMart;TestProxyCookie=" + cookie;
}

public Flavor getFlavor() {
Expand Down

0 comments on commit 8a3e97d

Please sign in to comment.