/**
* Copyright (c) 2009-2011 VMware, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.springsource.insight.plugin.jdbc.parser.parsers;
/* Copyright (c) (c) 2001-2008, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above Copyright (c) notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above Copyright (c) notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE Copyright (c) HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.Locale;
/*
* Parses a connection URL into parts.
*
* @author fredt@users
* @version 1.8.0
* @since 1.8.0
*/
public class DatabaseURL {
static int SC_DEFAULT_HSQL_SERVER_PORT = 9001;
static int SC_DEFAULT_HSQLS_SERVER_PORT = 554;
static int SC_DEFAULT_HTTP_SERVER_PORT = 80;
static int SC_DEFAULT_HTTPS_SERVER_PORT = 443;
static final String S_DOT = ".";
public static final String S_MEM = "mem:";
public static final String S_FILE = "file:";
public static final String S_RES = "res:";
public static final String S_ALIAS = "alias:";
public static final String S_HSQL = "hsql://";
public static final String S_HSQLS = "hsqls://";
public static final String S_HTTP = "http://";
public static final String S_HTTPS = "https://";
public static final String S_URL_PREFIX = "jdbc:hsqldb:";
/**
* Returns true if type represents an in-process connection to a file backed
* database.
*/
public static boolean isFileBasedDatabaseType(String url) {
if (S_FILE.equals(url) || S_RES.equals(url)) {
return true;
}
return false;
}
/**
* Returns true if type represents an in-process connection to database.
*/
public static boolean isInProcessDatabaseType(String url) {
if (S_FILE.equals(url) || S_RES.equals(url) || S_MEM.equals(url)) {
return true;
}
return false;
}
/**
* Parses the url into components that are returned in a properties
* object. <p>
* <p/>
* The following components are isolated: <p>
* <p/>
* <ul>
* url: the original url<p>
* connection_type: a static string that indicate the protocol. If the
* url does not begin with a valid protocol, null is returned by this
* method instead of the properties object.<p>
* host: name of host in networked modes in lowercase<p>
* port: port number in networked mode, or 0 if not present<p>
* path: path of the resource on server in networked modes,
* / (slash) in all cases apart from
* servlet path which is / (slash) plus the name of the servlet<p>
* database: database name. For memory, resource and networked modes,
* this is returned in lowercase, for file databases the original
* case of characters is preserved. Returns empty string if name is not
* present in the url.<p>
* for each protocol if port number is not in the url<p>
* Additional connection properties specified as key/value pairs.
* </ul>
*
* @return null returned if the part that should represent the port is not
* an integer or the part for database name is empty.
* Empty HsqlProperties returned if if url does not begin with valid
* protocol and could refer to another JDBC driver.
*/
public static HsqlProperties parseURL(String url, boolean hasPrefix) {
String urlImage = url.toLowerCase(Locale.ENGLISH);
HsqlProperties props = new HsqlProperties();
HsqlProperties extraProps = null;
String arguments = null;
int pos = 0;
if (hasPrefix) {
if (urlImage.startsWith(S_URL_PREFIX)) {
pos = S_URL_PREFIX.length();
} else {
return props;
}
}
String type = null;
String host;
int port = 0;
String database;
String path;
boolean isNetwork = false;
props.setProperty("url", url);
int semicolpos = url.indexOf(';', pos);
if (semicolpos < 0) {
semicolpos = url.length();
} else {
arguments = urlImage.substring(semicolpos + 1, urlImage.length());
extraProps = HsqlProperties.delimitedArgPairsToProps(arguments,
"=", ";", null);
//todo - check if properties have valid names / values
props.addProperties(extraProps);
}
if (semicolpos == pos + 1 && urlImage.startsWith(S_DOT, pos)) {
type = S_DOT;
} else if (urlImage.startsWith(S_MEM, pos)) {
type = S_MEM;
} else if (urlImage.startsWith(S_FILE, pos)) {
type = S_FILE;
} else if (urlImage.startsWith(S_RES, pos)) {
type = S_RES;
} else if (urlImage.startsWith(S_ALIAS, pos)) {
type = S_ALIAS;
} else if (urlImage.startsWith(S_HSQL, pos)) {
type = S_HSQL;
port = SC_DEFAULT_HSQL_SERVER_PORT;
isNetwork = true;
} else if (urlImage.startsWith(S_HSQLS, pos)) {
type = S_HSQLS;
port = SC_DEFAULT_HSQLS_SERVER_PORT;
isNetwork = true;
} else if (urlImage.startsWith(S_HTTP, pos)) {
type = S_HTTP;
port = SC_DEFAULT_HTTP_SERVER_PORT;
isNetwork = true;
} else if (urlImage.startsWith(S_HTTPS, pos)) {
type = S_HTTPS;
port = SC_DEFAULT_HTTPS_SERVER_PORT;
isNetwork = true;
}
if (type == null) {
type = S_FILE;
} else if (type == S_DOT) {
type = S_MEM;
// keep pos
} else {
pos += type.length();
}
props.setProperty("connection_type", type);
if (isNetwork) {
int slashpos = url.indexOf('/', pos);
if (slashpos < pos || slashpos > semicolpos) {
slashpos = semicolpos;
}
int colonpos = url.indexOf(':', pos);
if (colonpos < pos || colonpos > slashpos) {
colonpos = slashpos;
} else {
try {
port = Integer.parseInt(url.substring(colonpos + 1,
slashpos));
} catch (NumberFormatException e) {
return null;
}
}
host = urlImage.substring(pos, colonpos);
int secondslashpos = url.lastIndexOf('/', semicolpos);
if (secondslashpos < pos) {
path = "/";
database = "";
} else if (secondslashpos == slashpos) {
path = "/";
database = urlImage.substring(secondslashpos + 1, semicolpos);
} else {
path = url.substring(slashpos, secondslashpos);
database = urlImage.substring(secondslashpos + 1, semicolpos);
}
props.setProperty("port", port);
props.setProperty("host", host);
props.setProperty("path", path);
if (extraProps != null) {
String filePath = extraProps.getProperty("filepath");
if (filePath != null && database.length() != 0) {
database += ";" + filePath;
}
}
} else {
if (type == S_MEM || type == S_RES) {
database = urlImage.substring(pos, semicolpos).toLowerCase();
if (type == S_RES) {
if (database.indexOf('/') != 0) {
database = '/' + database;
}
}
} else {
database = url.substring(pos, semicolpos);
}
if (database.length() == 0) {
return null;
}
}
props.setProperty("database", database);
return props;
}
/*
public static void main(String[] argv) {
parseURL(
"JDBC:hsqldb:hsql://myhost:1777/mydb;filepath=c:/myfile/database/db",
true);
parseURL("JDBC:hsqldb:../data/mydb.db", true);
parseURL("JDBC:hsqldb:../data/mydb.db;ifexists=true", true);
parseURL("JDBC:hsqldb:HSQL://localhost:9000/mydb", true);
parseURL(
"JDBC:hsqldb:Http://localhost:8080/servlet/org.hsqldb.Servlet/mydb;ifexists=true",
true);
parseURL("JDBC:hsqldb:Http://localhost/servlet/org.hsqldb.Servlet/",
true);
parseURL("JDBC:hsqldb:hsql://myhost", true);
}
*/
}