/*
Copyright (C) 2003 EBI, GRL
This library 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.
This library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.ensembl.mart.guiutils;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.ensembl.mart.editor.LabelledComboBox;
/**
* Stateful dialog for entering and editing database settings.
*/
public class DatabaseSettingsDialog extends Box implements ChangeListener {
private Preferences preferences;
private LabelledComboBox databaseType;
private LabelledComboBox driver;
private LabelledComboBox host;
private LabelledComboBox port;
private LabelledComboBox database;
private LabelledComboBox schema;
private LabelledComboBox user;
private LabelledComboBox martUser;
private LabelledComboBox connectionName;
private JPasswordField password;
private String passwordPreferenceKey;
private JCheckBox rememberPassword;
private String rememberPasswordKey;
private final String[] defaultDBTypes = new String[] { "mysql",
"oracle",
"postgres"
};
/*
* the order of the default drivers must coincide with the order of their corresponding
* default types above for the auto completion to work
*/
private final String[] defaultDBDrivers = new String[] { "com.mysql.jdbc.Driver",
"oracle.jdbc.driver.OracleDriver",
"org.postgresql.Driver"
};
public DatabaseSettingsDialog() {
this(null);
}
public DatabaseSettingsDialog(Preferences preferences) {
super( BoxLayout.Y_AXIS );
connectionName = new LabelledComboBox("Display Name");
connectionName.setPreferenceKey("connection_name");
add( connectionName );
databaseType = new LabelledComboBox("Database Type");
databaseType.setPreferenceKey("database_type");
//databaseType.setEditable( false );
add( databaseType );
driver = new LabelledComboBox("Database Driver");
driver.setPreferenceKey("driver_type");
//driver.setEditable( false );
add( driver );
host = new LabelledComboBox("Host");
host.setPreferenceKey("host");
add( host );
port = new LabelledComboBox("Port");
port.setPreferenceKey( "port" );
add( port );
database = new LabelledComboBox("Database");
database.setPreferenceKey("database");
add( database );
schema = new LabelledComboBox("Schema");
schema.setPreferenceKey("schema");
add( schema );
user = new LabelledComboBox("Database User");
user.setPreferenceKey("user");
add( user );
add( createPasswordPanel() );
martUser = new LabelledComboBox("Mart User");
martUser.setPreferenceKey("martUser");
//add( martUser );
if ( preferences!=null ) setPrefs(preferences);
//setup changeListeners after initialization
connectionName.addChangeListener( this );
databaseType.addChangeListener( this );
}
/**
* Constructs password panel.
* @return
*/
private Box createPasswordPanel() {
password = new JPasswordField("Password");
passwordPreferenceKey = "password";
rememberPassword = new JCheckBox("Remember Password", false);
rememberPasswordKey = "store_password";
rememberPassword.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (rememberPassword.isSelected()) {
int option =
JOptionPane.showOptionDialog(
rememberPassword,
"The password will be stored unencrypted."
+ "\nAnyone with access to your account"
+ "\ncould read this password. "
+ "\nRemember it?",
"Remember Password?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
null,
null);
rememberPassword.setSelected(option == JOptionPane.YES_OPTION);
}
}
});
Box box = Box.createHorizontalBox();
box.add(new JLabel("Password"));
box.add(password);
box.add(rememberPassword);
return box;
}
private final String[] dialogOptions = new String[] { "Ok",
"Cancel",
"Delete"
};
public boolean showDialog(Component parent,String title) {
if (title.equals(""))
title = "Database Connection Settings";
int option =
JOptionPane.showOptionDialog(
parent,
this,
title,
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
dialogOptions,
null);
if (option == 2) {
//remove connection and its associated parameters from the persistence store
String cname = connectionName.getText();
String[] oldConnectionList = preferences.get(connectionName.getPreferenceKey(), "").split(",");
StringBuffer newList = new StringBuffer();
String comma = null;
for (int i = 0, n = oldConnectionList.length; i < n; i++) {
if (oldConnectionList[i].length() < 1 || oldConnectionList[i].equals(cname)) continue;
if (comma != null)
newList.append(comma);
newList.append(oldConnectionList[i]);
comma = ",";
}
if (newList.length() > 1) {
preferences.put(connectionName.getPreferenceKey(), newList.toString());
}
try {
preferences.node(cname).clear();
preferences.flush();
} catch (BackingStoreException e) {
e.printStackTrace();
}
}
if (option != 0) {
loadPreferences(preferences);
return false;
}
String pass = getPassword();
storePreferences( preferences );
loadPreferences(preferences);
//this is required to preserve password for this session only
if (!rememberPassword.isSelected())
password.setText(pass);
return true;
}
/**
*
*/
private void storePreferences( Preferences preferences) {
// persist state for next time program runs
String cname = connectionName.getText();
connectionName.store(preferences, 10);
if (cname != null)
saveStoredPreferencesFor(cname);
}
private void loadPreferences(Preferences preferences) {
connectionName.load(preferences);
String cname = connectionName.getText();
if (cname != null)
loadStoredPreferencesFor(cname);
loadDBSettings();
}
private void loadStoredPreferencesFor(String cname) {
Preferences newPrefs = preferences.node(cname);
databaseType.load(newPrefs);
driver.load(newPrefs);
host.load(newPrefs);
port.load(newPrefs);
database.load(newPrefs);
user.load(newPrefs);
martUser.load(newPrefs);
schema.load(newPrefs);
rememberPassword.setSelected( newPrefs.getBoolean( rememberPasswordKey, false) );
password.setText(newPrefs.get(passwordPreferenceKey, ""));
}
public void saveStoredPreferencesFor(String cname) {
Preferences newPrefs = preferences.node(cname);
databaseType.store(newPrefs, 10);
driver.store(newPrefs, 10);
host.store(newPrefs, 10);
port.store(newPrefs, 10);
database.store(newPrefs, 10);
schema.store(newPrefs, 10);
user.store(newPrefs, 10);
martUser.store(newPrefs, 10);
newPrefs.putBoolean( rememberPasswordKey, rememberPassword.isSelected() );
if (rememberPassword.isSelected())
newPrefs.put(passwordPreferenceKey, getPassword());
else
newPrefs.remove(passwordPreferenceKey);
try {
// write preferences to persistent storage
preferences.flush();
} catch (BackingStoreException e) {
e.printStackTrace();
}
}
private void loadDBSettings() {
for (int i = 0, n = defaultDBTypes.length; i < n; i++) {
if (!databaseType.hasItem( defaultDBTypes[i]))
databaseType.addItem( defaultDBTypes[i] );
}
for (int i = 0, n = defaultDBDrivers.length; i < n; i++) {
if (!driver.hasItem( defaultDBDrivers[i] ))
driver.addItem( defaultDBDrivers[i] );
}
}
public static void main(String[] args) {
DatabaseSettingsDialog d = new DatabaseSettingsDialog( );
d.setPrefs( Preferences.userNodeForPackage( d.getClass() ) );
d.showDialog( null,"" );
System.exit(0);
}
public String getConnectionName() {
return connectionName.getText();
}
public String getHost() {
return host.getText();
}
public String getMartUser() {
return martUser.getText();
}
public String getDatabaseType() {
return databaseType.getText();
}
public void setPrefs(Preferences prefs) {
this.preferences = prefs;
loadPreferences( preferences );
}
public Preferences getPrefs() {
return preferences;
}
public String getDatabase() {
return database.getText();
}
public String getSchema() {
return schema.getText();
}
public String getPassword() {
return new String( password.getPassword() );
}
public String getPort() {
return port.getText();
}
public String getUser() {
return user.getText();
}
public String getDriver() {
return driver.getText();
}
/**
* Adds item if not already in list.
* @param type
*/
public void addDatabaseType(String type) {
databaseType.addItem( type );
}
/**
* Adds item if not already in list.
* @param driverName
*/
public void addDriver(String driverName) {
driver.addItem( driverName );
}
/* (non-Javadoc)
* @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
*/
public void stateChanged(ChangeEvent e) {
if (e.getSource().equals(connectionName)) {
//thrown when connectonName box status is changed
String cname = connectionName.getText();
if (cname != null) {
loadStoredPreferencesFor(cname);
}
loadDBSettings();
} else if (e.getSource().equals(databaseType)){
//thrown when databaseType box status is changed
String dbtype = databaseType.getText();
for (int i = 0, n = defaultDBTypes.length; i < n; i++) {
if (dbtype.equals(defaultDBTypes[i])) {
driver.setSelectedItem( defaultDBDrivers[i] );
break;
}
}
}
}
}