/* * Copyright 2016 TWO SIGMA OPEN SOURCE, LLC * * 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.twosigma.beaker.sql; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import java.nio.charset.StandardCharsets; import java.sql.Driver; import java.sql.DriverPropertyInfo; import java.sql.SQLException; public class ConnectionStringHolder { public static final String USER_CONNECTION_KEY = "user"; public static final String PASSWORD_CONNECTION_KEY = "password"; public static final String KEY_FOR_DISPLAY_INPUT_DIALOG = "<prompt>"; public static final char EQUAL_SIGN = '='; public static final char [] SEPARATORS = new char[]{'?', '&', ';' , '/' , '\\'}; private JDBCClient jdbcClient; private String connectionString; private String user; private String password; private boolean showDialog; public ConnectionStringHolder(String connectionString, JDBCClient jdbcClient) { this.jdbcClient = jdbcClient; setConnectionString(connectionString); } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isShowDialog() { return showDialog; } public void setShowDialog(boolean showDialog) { this.showDialog = showDialog; } public String getConnectionString() { return connectionString; } public String getActualConnectionString() { return removeParameter(connectionString, USER_CONNECTION_KEY, PASSWORD_CONNECTION_KEY); } public void setConnectionString(String connectionString) { this.connectionString = connectionString; if(connectionString != null && !connectionString.isEmpty()){ BasicDataSource ds = null; String user = null; try { ds = jdbcClient.getDataSource(connectionString); } catch (SQLException e) {} if(ds!= null){ user = getProperty(USER_CONNECTION_KEY, connectionString, ds.getDriver()); }if(user == null){ user = getProperty(USER_CONNECTION_KEY, connectionString); } if (user != null) { if (KEY_FOR_DISPLAY_INPUT_DIALOG.equals(user)) { showDialog = true; } else { this.user = user; } String password = getProperty(PASSWORD_CONNECTION_KEY, connectionString); if (password != null) { if (KEY_FOR_DISPLAY_INPUT_DIALOG.equals(password)) { showDialog = true; } else { this.password = password; } } else { showDialog = true; } } } } protected static String getProperty(String property, String connectionString, Driver dbDriver){ String ret = null; if(property != null && !property.isEmpty() && dbDriver != null && connectionString != null && !connectionString.isEmpty()){ try { for (DriverPropertyInfo dpi : dbDriver.getPropertyInfo(connectionString, null)) { if(property.equalsIgnoreCase(dpi.name.trim())){ ret = dpi.value; break; } } } catch (SQLException e) {} } return ret; } /** * MSSQL driver do not return password, so we need to parse it manually * @param property * @param connectionString * @return */ protected static String getProperty(String property, String connectionString) { String ret = null; if (property != null && !property.isEmpty() && connectionString != null && !connectionString.isEmpty()) { for (NameValuePair param : URLEncodedUtils.parse(connectionString, StandardCharsets.UTF_8, SEPARATORS)) { if(property.equals(param.getName())){ ret = param.getValue(); break; } } } return ret; } protected static String removeParameter(String connectionString, String ... parameters) { String ret = connectionString; for (String parameter : parameters) { int index = ret.indexOf(parameter + EQUAL_SIGN); if(index > -1){ int parameterEnd = ret.length(); for (char c : SEPARATORS) { int temp = ret.indexOf(c, index); if(temp > -1){ parameterEnd = Math.min(temp, parameterEnd); } } String toRet = ret.substring(0, index); toRet += ret.substring(parameterEnd, ret.length()); ret = toRet; } } return ret; } }