*/
public static HsqlProperties parseURL(String url, boolean hasPrefix,
boolean noPath) {
String urlImage = url.toLowerCase(Locale.ENGLISH);
HsqlProperties props = new HsqlProperties();
HsqlProperties extraProps = null;
String arguments = null;
int pos = 0;
String type = null;
int port = 0;
String database;
String path;
boolean isNetwork = false;
if (hasPrefix) {
if (urlImage.startsWith(S_URL_PREFIX)) {
pos = S_URL_PREFIX.length();
} else {
return props;
}
}
while (true) {
int replacePos = url.indexOf("${");
if (replacePos == -1) {
break;
}
int endPos = url.indexOf("}", replacePos);
if (endPos == -1) {
break;
}
String varName = url.substring(replacePos + 2, endPos);
String varValue = null;
try {
varValue = System.getProperty(varName);
} catch (SecurityException e) {}
if (varValue == null) {
break;
}
url = url.substring(0, replacePos) + varValue
+ url.substring(endPos + 1);
urlImage = url.toLowerCase(Locale.ENGLISH);
}
props.setProperty("url", url);
int postUrlPos = url.length();
// postUrlPos is the END position in url String,
// wrt what remains to be processed.
// I.e., if postUrlPos is 100, url no longer needs to examined at
// index 100 or later.
int semiPos = url.indexOf(';', pos);
if (semiPos > -1) {
arguments = url.substring(semiPos + 1, urlImage.length());
postUrlPos = semiPos;
extraProps = HsqlProperties.delimitedArgPairsToProps(arguments,
"=", ";", null);
// validity checks are performed by engine
props.addProperties(extraProps);
}
if (postUrlPos == 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 = ServerConstants.SC_DEFAULT_HSQL_SERVER_PORT;
isNetwork = true;
} else if (urlImage.startsWith(S_HSQLS, pos)) {
type = S_HSQLS;
port = ServerConstants.SC_DEFAULT_HSQLS_SERVER_PORT;
isNetwork = true;
} else if (urlImage.startsWith(S_HTTP, pos)) {
type = S_HTTP;
port = ServerConstants.SC_DEFAULT_HTTP_SERVER_PORT;
isNetwork = true;
} else if (urlImage.startsWith(S_HTTPS, pos)) {
type = S_HTTPS;
port = ServerConstants.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) {
// First capture 3 segments: host + port + path
String pathSeg = null;
String hostSeg = null;
String portSeg = null;
int endPos = url.indexOf('/', pos);
if (endPos > 0 && endPos < postUrlPos) {
pathSeg = url.substring(endPos, postUrlPos);
// N.b. pathSeg necessarily begins with /.
} else {
endPos = postUrlPos;
}
// Processing different for ipv6 host address and all others:
if (url.charAt(pos) == '[') {
// ipv6
int endIpv6 = url.indexOf(']', pos + 2);
// Notice 2 instead of 1 to require non-empty addr segment
if (endIpv6 < 0 || endIpv6 >= endPos) {
return null;
// Wish could throw something with a useful message for user
// here.
}
hostSeg = urlImage.substring(pos + 1, endIpv6);
if (endPos > endIpv6 + 1) {
portSeg = url.substring(endIpv6 + 1, endPos);
}
} else {
// non-ipv6
int colPos = url.indexOf(':', pos + 1);
if (colPos > -1 && colPos < endPos) {
// portSeg will be non-empty, but could contain just ":"
portSeg = url.substring(colPos, endPos);
} else {
colPos = -1;
}
hostSeg = urlImage.substring(pos, (colPos > 0) ? colPos
: endPos);
}
// At this point, the entire url has been parsed into
// hostSeg + portSeg + pathSeg.
if (portSeg != null) {
if (portSeg.length() < 2 || portSeg.charAt(0) != ':') {
// Wish could throw something with a useful message for user
// here.
return null;
}
try {
port = Integer.parseInt(portSeg.substring(1));
} catch (NumberFormatException e) {
// System.err.println("NFE for (" + portSeg + ')'); debug
return null;
}
}
if (noPath) {
path = "";
database = pathSeg;
} else if (pathSeg == null) {
path = "/";
database = "";
} else {
int lastSlashPos = pathSeg.lastIndexOf('/');
if (lastSlashPos < 1) {
path = "/";
database =
pathSeg.substring(1).toLowerCase(Locale.ENGLISH);
} else {
path = pathSeg.substring(0, lastSlashPos);
database = pathSeg.substring(lastSlashPos + 1);
}
}
/* Just for debug. Remove once stable:
System.err.println("Host seg (" + hostSeg + "), Port val (" + port
+ "), Path val (" + pathSeg + "), path (" + path
+ "), db (" + database + ')');
*/
props.setProperty("port", port);
props.setProperty("host", hostSeg);
props.setProperty("path", path);
if (!noPath && extraProps != null) {
String filePath = extraProps.getProperty("filepath");
if (filePath != null && database.length() != 0) {
database += ";" + filePath;
} else {
if (url.indexOf(S_MEM) == postUrlPos + 1