All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aceql.jdbc.driver.free.AceQLDriver Maven / Gradle / Ivy

Go to download

The AceQL Java Client JDBC Driver allows to wrap the AceQL HTTP APIs and eliminates the tedious works of handling communications errors and parsing JSON results. Android and Java Desktop application developers can access remote SQL databases and/or SQL databases in the cloud by simply including standard JDBC calls in their code, just like they would for a local database.

The newest version!
/*
 * This file is part of AceQL.
 * AceQL: Remote JDBC access over HTTP.
 * Copyright (C) 2015,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.
 *
 * AceQL is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * AceQL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package com.aceql.jdbc.driver.free;

import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

import com.aceql.jdbc.commons.AceQLConnection;
import com.aceql.jdbc.commons.ConnectionInfo;
import com.aceql.jdbc.commons.InternalWrapper;
import com.aceql.jdbc.commons.driver.util.DriverPropertyInfoBuilder;
import com.aceql.jdbc.commons.driver.util.DriverUtil;
import com.aceql.jdbc.commons.main.util.AceQLConnectionUtil;
import com.aceql.jdbc.commons.main.util.framework.FrameworkDebug;
import com.aceql.jdbc.commons.main.util.framework.JdbcUrlHeader;
import com.aceql.jdbc.commons.main.util.framework.Tag;
import com.aceql.jdbc.commons.metadata.ResultSetMetaDataPolicy;

/**
 *
 * The AceQL JDBC Driver class in order to
 * access remote SQL databases through HTTP from Android or Java desktop
 * programs.
*
* user, password and database are the only required * properties.
*
* Properties: *
    *
  • user: username to connect to the remote database as.
  • *
  • password: password to use when authenticating.
  • *
  • database: name of remote database as defined in the server * {@code aceql-server.properties} file.
  • *
  • proxyType: java.net.Proxy Type to use: DIRECT, HTTP or SOCKS. * Defaults to DIRECT.
  • *
  • proxyHostname: java.net.Proxy hostname to use.
  • *
  • proxyPort: java.net.Proxy Port to use.
  • *
  • proxyUsername: Proxy credential username.
  • *
  • proxyPassword: Proxy credential password.
  • *
  • connectTimeout: Timeout value, in milliseconds, to be used when * opening a communications link to the remote server. If the timeout expires * before the connection can be established, a java.net.SocketTimeoutException is * raised. A timeout of zero is interpreted as an infinite timeout. Defaults to 0.
  • *
  • readTimeout: Read timeout to a specified timeout, in milliseconds. * A non-zero value specifies the timeout when reading from Input stream when a * connection is established to a resource. If the timeout expires before there * is data available for read, a java.net.SocketTimeoutException is raised. A * timeout of zero is interpreted as an infinite timeout. Defaults to 0. *
  • gzipResult: Boolean to say if the ResultSet is Gzipped before * download. Defaults to true.
  • *
  • resultSetMetaDataPolicy: Defines the {@code ResultSet} metadata * policy. Says if the {@code ResultSet} metadata is to be downloaded along with * the ResultSet. Possible values are "on" and "off". Defaults to "on".
  • *
  • clobReadCharset: Name of the charset to use when * reading a CLOB content with the {@code ResultSet} methods. Defaults * to {@code null}.
  • *
  • clobWriteCharset: Name of the charset to use when * writing a CLOB content with the {@code PreparedStatement} streaming methods. Defaults * to "{@code UTF-8}".
  • *
*

* Usage of the AceQL JDBC Driver is straightforward: * *

 * // Define URL of the path to the AceQL Manager Servlet
 * // We will use a secure SSL/TLS session. All uploads/downloads of SQL
 * // commands and data will be encrypted.
 * String url = "http://localhost:9090/aceql";
 *
 * // The login info for strong authentication on server side.
 * // These are *not* the username/password of the remote JDBC Driver,
 * // but are the auth info checked by remote server
 * // UserAuthenticator.login(username, password) method.
 * String database = "sampledb";
 * String user = "user1";
 * String password = "password1";
 *
 * // Register and Load the Driver
 * DriverManager.registerDriver(new AceQLDriver());
 * String driverClassName = AceQLDriver.class.getName();
 * Class.forName(driverClassName);
 *
 * // Attempts to establish a connection to the remote database:
 * Properties info = new Properties();
 * info.put("user", user);
 * info.put("password", password);
 * info.put("database", database);
 *
 * Connection connection = DriverManager.getConnection(url, info);
 * return connection;
 * 
*

* An alternate way of passing connection info is to add them as request * parameters to the URL: *
*


 * // Define URL of the path to the AceQL Manager Servlet, with all properties
 * // passed as request parameters.
 * // (We presume that the aceql_license_key.txt is installed in user.dir.)
 * String url = "http://localhost:9090/aceql?user=user1&password=password1&database=sampledb";
 *
 * // Register and Load the Driver 
 * DriverManager.registerDriver(new AceQLDriver());
 * String driverClassName = AceQLDriver.class.getName();
 * Class.forName(driverClassName);
 *
 * // Attempts to establish a connection to the remote database:
 * Connection connection = DriverManager.getConnection(url, new Properties());
 * 
* * The {@code Connection} returned is now ready to be used as a regular or * classic {@link java.sql.Connection}: * *

 * String sql = "select * from customer where customer_id >= 1 order by customer_id";
 * Statement statement = connection.createStatement();
 * statement.execute(sql);
 *
 * ResultSet rs = statement.getResultSet();
 * // Etc.
 * 
* * The built {@code Connection} is an instance of {@code AceQLConnection} that * contains some specific method. See {@link AceQLConnection} for more info. *
*
* * @since 6.0 * @author Nicolas de Pomereu */ final public class AceQLDriver implements java.sql.Driver { static int LICENSE_INFO; /** The debug flag */ private static boolean DEBUG = FrameworkDebug.isSet(AceQLDriver.class); /** * Attempts to make a database connection to the given URL. * * The driver will return "null" if it realizes it is the wrong kind of driver * to connect to the given URL. {@link #acceptsURL} will return null. * *

* The driver will throwSQLException if it is the right driver to * connect to the given URL but has trouble connecting to the database. * *

* The java.util.Properties argument can be used to pass arbitrary * string tag/value pairs as connection arguments. At least "user", "password" * and "database" properties should be included in the Properties * object, or either passed through the URL parameter. * * @param url the URL of the database to which to connect * @param info a list of arbitrary string tag/value pairs as connection * arguments. At least a "user" and "password" property should be * included. * @return a Connection object that represents a connection to the * URL * @exception SQLException if a database access error occurs */ @Override public Connection connect(String url, Properties info) throws SQLException { if (url == null) { throw new SQLException("url not set. Please provide an url."); } if (!acceptsURL(url)) { return null; } // Properties may be passed in URL info = DriverUtil.addPropertiesFromUrl(url, info); // Remove "aceql:jdbc" prefix & all parameters url = DriverUtil.trimUrl(url); String username = info.getProperty("user"); String password = info.getProperty("password"); String sessionId = info.getProperty("sessionId"); String database = info.getProperty("database"); DriverUtil.checkNonNullValues(username, password, database, sessionId); // Add proxy lookup String proxyType = info.getProperty("proxyType"); String proxyHostname = info.getProperty("proxyHostname"); String proxyPort = info.getProperty("proxyPort"); String proxyUsername = info.getProperty("proxyUsername"); String proxyPassword = info.getProperty("proxyPassword"); String clobReadCharset = info.getProperty("clobReadCharset"); String clobWriteCharset = info.getProperty("clobWriteCharset"); if (clobWriteCharset == null) { clobWriteCharset = StandardCharsets.UTF_8.name(); } debug("info.getProperty(\"clobReadCharset\") : " + clobReadCharset); debug("info.getProperty(\"clobWriteCharset\"): " + clobWriteCharset); boolean gzipResult = DriverUtil.getGzipResult(info); int connectTimeout = DriverUtil.getConnectTimeout(info); int readTimeout = DriverUtil.getReadTimeout(info); ResultSetMetaDataPolicy resultSetMetaDataPolicy = DriverUtil.getResultSetMetaDataPolicy(info); Proxy proxy = DriverUtil.buildProxy(proxyType, proxyHostname, proxyPort); Map requestProperties = DriverUtil.getRequestProperties(info); debug("requestProperties: " + requestProperties); PasswordAuthentication proxyAuthentication = null; if (proxy != null && proxyUsername != null) { // Password cannot be null if (proxyPassword == null) { throw new SQLException(Tag.PRODUCT + " Defining an authenticated proxy: proxyPassword cannot be null!"); } proxyAuthentication = new PasswordAuthentication(proxyUsername, proxyPassword.toCharArray()); } PasswordAuthentication authentication = null; boolean passwordIsSessionId = false; if (sessionId == null) { authentication = new PasswordAuthentication(username, password.toCharArray()); passwordIsSessionId = false; } else { authentication = new PasswordAuthentication(username, sessionId.toCharArray()); passwordIsSessionId = true; } ConnectionInfo connectionInfo = InternalWrapper.connectionInfoBuilder(url, database, authentication, passwordIsSessionId, proxy, proxyAuthentication, connectTimeout, readTimeout, gzipResult, resultSetMetaDataPolicy, requestProperties, clobReadCharset, clobWriteCharset); AceQLConnection connection = InternalWrapper.connectionBuilder(connectionInfo); if (!AceQLConnectionUtil.isVersion12_2OrHigher(connection)) { throw new SQLException("AceQL Server version must be >= " + AceQLConnectionUtil.SERVER_VERSION_12_2 + " in order to use the AceQL Client JDBC Driver."); } return connection; } /** * Retrieves whether the driver thinks that it can open a connection to the * given URL. Typically drivers will return true if they understand * the subprotocol specified in the URL and false if they do not. *
*
* The AceQL driver requires an URL which is an http url in the format:
* {@code jdbc:aceql:http(s):///} *
*
* Example:
* {@code jdbc:aceql:https://www.acme.com:9443/aceql}
*
* Note that the {@code "jdbc:aceql:"} prefix is optional and thus an URL such * as {@code https://www.aceql.com:9443/aceql} is accepted * * @param url the URL of the database * @return true if this driver understands the given URL; * false otherwise * @exception SQLException if a database access error occurs */ @Override public boolean acceptsURL(String url) throws SQLException { if (url == null) { throw new IllegalArgumentException("url is null!"); } String urlHttpOnly = JdbcUrlHeader.getUrlHttpOnly(url); return DriverUtil.isHttpProtocolUrl(urlHttpOnly); } /** * Gets information about the possible properties for this driver. *

* The getPropertyInfo method is intended to allow a generic GUI * tool to discover what properties it should prompt a human for in order to get * enough information to connect to a database. Note that depending on the * values the human has supplied so far, additional values may become necessary, * so it may be necessary to iterate though several calls to the * getPropertyInfo method. * * @param url the URL of the database to which to connect * @param info a proposed list of tag/value pairs that will be sent on connect * open * @return an array of DriverPropertyInfo objects describing * possible properties. * @exception SQLException if a database access error occurs */ @Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { DriverPropertyInfoBuilder driverPropertyInfoBuilder = new DriverPropertyInfoBuilder(); List driverPropertyInfoList = driverPropertyInfoBuilder.build(info); DriverPropertyInfo[] arrayOfDriverPropertyInfo = driverPropertyInfoList .toArray(new DriverPropertyInfo[driverPropertyInfoList.size()]); return arrayOfDriverPropertyInfo; } /** * Retrieves this driver's major version number. * * @return this driver's major version number */ @Override public int getMajorVersion() { return 9; } /** * Gets the driver's minor version number. * * @return this driver's minor version number */ @Override public int getMinorVersion() { return 3; } /** * Reports whether this driver is a genuine JDBC Compliant ™ driver. A * driver may only report true here if it passes the JDBC * compliance tests; otherwise it is required to return false. *

* JDBC compliance requires full support for the JDBC API and full support for * SQL 92 Entry Level. *

* Because the AceQL driver works as a special Driver over HTTP to support many * SQL databases vendors, it does not aim to be a genuine JDBC Compliant ™ * driver. Thus, method returns false. * * @return false */ @Override public boolean jdbcCompliant() { return false; } /** * debug tool */ private static void debug(String s) { if (DEBUG) { System.out.println(new Date() + " " + s); } } // ///////////////////////////////////////////////////////// // JAVA 7 METHOD EMULATION // // ///////////////////////////////////////////////////////// /** * Return the parent Logger of all the Loggers used by this driver. This should * be the Logger farthest from the root Logger that is still an ancestor of all * of the Loggers used by this driver. Configuring this Logger will affect all * of the log messages generated by the driver. In the worst case, this may be * the root Logger. * * @return the parent Logger for this driver * @throws SQLFeatureNotSupportedException if the driver does not use * java.util.logging. * @since 1.7 */ @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { throw new SQLFeatureNotSupportedException(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy