001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.monitoring.jdbc;
018    
019    import org.apache.commons.monitoring.Role;
020    import org.apache.commons.monitoring.counters.Counter;
021    import org.apache.commons.monitoring.repositories.Repository;
022    
023    import java.sql.Connection;
024    import java.sql.Driver;
025    import java.sql.DriverManager;
026    import java.sql.DriverPropertyInfo;
027    import java.sql.SQLException;
028    import java.sql.SQLFeatureNotSupportedException;
029    import java.util.Properties;
030    import java.util.logging.Logger;
031    
032    public class MonitoringDriver implements Driver {
033        static {
034            try {
035                DriverManager.registerDriver(new MonitoringDriver());
036            } catch (final SQLException e) {
037                // no-op
038            }
039        }
040    
041        private static final String PREFIX = "jdbc:monitoring:";
042        private static final String DRIVER_SUFFIX = "delegateDriver=";
043    
044        public static void load() {
045        } // sexier than Class.forName("org.apache.commons.monitoring.jdbc.MonitoringDriver"); in full java
046    
047        @Override
048        public Connection connect(final String url, final Properties info) throws SQLException {
049            if (!acceptsURL(url)) {
050                throw new SQLException("Driver " + MonitoringDriver.class.getName() + " doesn't accept " + url + ". Pattern is jdbc:monitoring:<xxx>:<yyy>?delegateDriver=<zzz>");
051            }
052    
053            final int driverIndex = url.indexOf(DRIVER_SUFFIX);
054    
055            String realUrl = "jdbc:" + url.substring(PREFIX.length(), driverIndex);
056            if (realUrl.endsWith("?") || realUrl.endsWith("&")) {
057                realUrl = realUrl.substring(0, realUrl.length() - 1);
058            }
059    
060            final String realDriver = url.substring(driverIndex + DRIVER_SUFFIX.length());
061            try {
062                final Driver delegate = Driver.class.cast(Class.forName(realDriver).newInstance());
063                return MonitoredConnection.monitor(delegate.connect(realUrl, info), Repository.INSTANCE.getCounter(new Counter.Key(Role.JDBC, url)));
064            } catch (final Exception e) {
065                throw new SQLException(e);
066            }
067        }
068    
069        @Override
070        public boolean acceptsURL(final String url) throws SQLException {
071            return url != null && url.startsWith(PREFIX) && url.contains(DRIVER_SUFFIX);
072        }
073    
074        @Override
075        public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) throws SQLException {
076            return new DriverPropertyInfo[0];
077        }
078    
079        @Override
080        public int getMajorVersion() {
081            return 1;
082        }
083    
084        @Override
085        public int getMinorVersion() {
086            return 0;
087        }
088    
089        @Override
090        public boolean jdbcCompliant() {
091            return true;
092        }
093    
094        // @Override // java 7
095        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
096            return Logger.getLogger("commons-monitoring.jdbc-driver");
097        }
098    }