Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/utils/MapUtils.java @ 9672:b70b1bc0eece 3.2.x
Essentially rewrite MapUtils.getConnection() to cope with driver capabilities
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Sat, 23 May 2020 10:37:23 +0200 |
parents | 9cfc495a9f40 |
children | 0a5239a1e46e |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/utils/MapUtils.java Fri May 22 19:45:08 2020 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/utils/MapUtils.java Sat May 23 10:37:23 2020 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde +/* Copyright (C) 2011, 2012, 2013, 2020 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) @@ -8,8 +8,8 @@ package org.dive4elements.river.utils; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.net.URI; +import java.net.URISyntaxException; import org.apache.log4j.Logger; import org.hibernate.impl.SessionFactoryImpl; @@ -21,8 +21,10 @@ { private static final Logger log = Logger.getLogger(MapUtils.class); - public static final Pattern DB_URL_PATTERN = - Pattern.compile("(.*)\\/\\/(.*):([0-9]+)\\/([\\.a-zA-Z0-9_-]+)"); + private static final String JDBC_SCHEME = "^jdbc:"; + + private static final String JDBC_DRV_PATTERN = + JDBC_SCHEME + "(postgresql|oracle:(thin|oci)):.*"; /** * This method returns a connection string for databases used by @@ -42,56 +44,83 @@ } public static String getConnection(String user, String pass, String url) { - log.debug("Parse connection url: " + url); + log.info("Parse connection string: " + url); - Matcher m = DB_URL_PATTERN.matcher(url); - if (!m.matches()) { - log.warn("Could not parse Connection string"); + if (!url.matches(JDBC_DRV_PATTERN)) { + log.error("Could not parse connection string: " + + "Not a JDBC URL with PostgreSQL or Oracle driver"); return null; } - int groups = m.groupCount(); - - if (log.isDebugEnabled()) { - for (int i = 0; i <= groups; i++) { - log.debug("Group " + i + ": " + m.group(i)); - } + URI uri = null; + try { + // Strip JDBC_SCHEME to let the driver be parsed as scheme + uri = new URI(url.replaceFirst(JDBC_SCHEME, "")); } - - String connection = null; - - if (groups < 4) { - log.warn("Could only partially parse connection string."); + catch (URISyntaxException e) { + log.error("Could not parse connection string: " + e.getMessage()); return null; } - String host = m.group(2); - String port = m.group(3); - String db = m.group(4); + String drv = uri.getScheme(); + log.debug("Driver: " + drv); - if (url.startsWith("jdbc:oracle:")) { - connection = user + "/" + pass - + "@" + host + ":" + port + "/" + db; + String connection = null; + if (drv.equals("oracle")) { + try { + // Work-around the extra colon in the driver part of the scheme + String con = new URI(uri.getSchemeSpecificPart()) + .getSchemeSpecificPart().replaceFirst("^@(//)?", ""); + log.debug("Database specifier: " + con); + connection = user + "/" + pass + "@" + con; + } + catch (URISyntaxException e) { + log.error("Could not parse Oracle connection string: " + + e.getMessage()); + return null; + } } - else { + else { // assume PostgreSQL + String host = uri.getHost(); + if (host == null && uri.getSchemeSpecificPart().startsWith("//")) { + // invalid hostnames (e.g. containing '_') are not parsed! + log.error("Could not parse PostgreSQL connection string: " + + "invalid host name"); + return null; + } + String db = host == null + ? uri.getSchemeSpecificPart() + : uri.getPath(); + int port = uri.getPort(); connection = createConnectionString(user, pass, host, db, port); } return connection; } - public static String createConnectionString( + private static String createConnectionString( String user, String pass, String host, String db, - String port + int port ) { StringBuilder sb = new StringBuilder(); - sb.append("dbname=").append(db); - sb.append(" host='").append(host).append("'"); + // Required parameters + // defaults to user name in PostgreSQL JDBC: + if (db != null) { + db = db.replaceFirst("/", ""); + } + sb.append("dbname=").append(db == null || db.equals("") ? user : db); sb.append(" user=").append(user); - sb.append(" port=").append(port); + + // Optional parameters + if (host != null) { + sb.append(" host='").append(host).append("'"); + } + if (port != -1) { + sb.append(" port=").append(port); + } // XXX: We need to escape this somehow. sb.append(" password='").append(pass).append("'"); sb.append(" sslmode=disable");