001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap4j/MondrianOlap4jDriver.java#1 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2007-2007 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.olap4j;
011    
012    import mondrian.rolap.RolapConnectionProperties;
013    
014    import java.sql.*;
015    import java.util.Properties;
016    import java.util.List;
017    import java.util.ArrayList;
018    import java.util.Map;
019    
020    /**
021     * Olap4j driver for Mondrian.
022     *
023     * <p>Since olap4j is a superset of JDBC, you register this driver as you would
024     * any JDBC driver:
025     *
026     * <blockquote>
027     * <code>Class.forName("mondrian.olap4j.MondrianOlap4jDriver");</code>
028     * </blockquote>
029     *
030     * Then create a connection using a URL with the prefix "jdbc:mondrian:".
031     * For example,
032     *
033     * <blockquote>
034     * <code>import java.sql.Connection;<br/>
035     * import java.sql.DriverManager;<br/>
036     * import org.olap4j.OlapConnection;<br/>
037     * <br/>
038     * Connection connection =<br/>
039     * &nbsp;&nbsp;&nbsp;DriverManager.getConnection(<br/>
040     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"jdbc:mondrian:Jdbc=jdbc:odbc:MondrianFoodMart; Catalog=file:/mondrian/demo/FoodMart.xml; JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver");<br/>
041     * OlapConnection olapConnection =<br/>
042     * &nbsp;&nbsp;&nbsp;connection.unwrap(OlapConnection.class);</code>
043     * </blockquote>
044     *
045     * <p>Note how we use the {@link Connection#unwrap(Class)} method to down-cast
046     * the JDBC connection object to the extension {@link org.olap4j.OlapConnection}
047     * object. This method is only available in the JDBC 4.0 (JDK 1.6 onwards).
048     *
049     * <h3>Connection properties</h3>
050     *
051     * <p>The driver supports the same set of properties as a traditional mondrian
052     * connection. See {@link mondrian.rolap.RolapConnectionProperties}.
053     *
054     * <h3>Catalogs and schemas</h3>
055     *
056     * <p>Mondrian has a sole catalog, called "LOCALDB". You will get an error
057     * if you attempt to use {@link java.sql.Connection#setCatalog(String)} to set
058     * it to anything else.
059     *
060     * @author jhyde
061     * @version $Id: //open/mondrian/src/main/mondrian/olap4j/MondrianOlap4jDriver.java#1 $
062     * @since May 22, 2007
063     */
064    public class MondrianOlap4jDriver implements Driver {
065        public static final String NAME = "Mondrian olap4j driver";
066        public static final String VERSION = "2.4";
067        public static final int MAJOR_VERSION = 2;
068        public static final int MINOR_VERSION = 4;
069        private final Factory factory;
070    
071        static {
072            try {
073                register();
074            } catch (SQLException e) {
075                e.printStackTrace();
076            }
077        }
078    
079        MondrianOlap4jDriver() {
080            String factoryClassName;
081            try {
082                Class.forName("java.sql.Wrapper");
083                factoryClassName = "mondrian.olap4j.FactoryJdbc4Impl";
084            } catch (ClassNotFoundException e) {
085                // java.sql.Wrapper is not present. This means we are running JDBC
086                // 3.0 or earlier (probably JDK 1.5). Load the JDBC 3.0 factory
087                factoryClassName = "mondrian.olap4j.FactoryJdbc3Impl";
088            }
089            try {
090                final Class clazz = Class.forName(factoryClassName);
091                factory = (Factory) clazz.newInstance();
092            } catch (ClassNotFoundException e) {
093                throw new RuntimeException(e);
094            } catch (IllegalAccessException e) {
095                throw new RuntimeException(e);
096            } catch (InstantiationException e) {
097                throw new RuntimeException(e);
098            }
099        }
100    
101        private static void register() throws SQLException {
102            DriverManager.registerDriver(new MondrianOlap4jDriver());
103        }
104    
105        public Connection connect(String url, Properties info) throws SQLException {
106            if (!MondrianOlap4jConnection.acceptsURL(url)) {
107                return null;
108            }
109            return factory.newConnection(url, info);
110        }
111    
112        public boolean acceptsURL(String url) throws SQLException {
113            return MondrianOlap4jConnection.acceptsURL(url);
114        }
115    
116        public DriverPropertyInfo[] getPropertyInfo(
117            String url, Properties info) throws SQLException
118        {
119            List<DriverPropertyInfo> list = new ArrayList<DriverPropertyInfo>();
120    
121            // First, add the contents of info
122            for (Map.Entry<Object,Object> entry : info.entrySet()) {
123                list.add(
124                    new DriverPropertyInfo(
125                        (String) entry.getKey(),
126                        (String) entry.getValue()));
127            }
128            // Next, add property defns not mentioned in info
129            for (RolapConnectionProperties p : RolapConnectionProperties.values()) {
130                if (info.containsKey(p.name())) {
131                    continue;
132                }
133                list.add(
134                    new DriverPropertyInfo(
135                        p.name(),
136                        null));
137            }
138            return list.toArray(new DriverPropertyInfo[list.size()]);
139        }
140    
141        public int getMajorVersion() {
142            return MAJOR_VERSION;
143        }
144    
145        public int getMinorVersion() {
146            return MINOR_VERSION;
147        }
148    
149        public boolean jdbcCompliant() {
150            return false;
151        }
152    }
153    
154    // End MondrianOlap4jDriver.java