/**
* eXist Open Source Native XML Database
* Copyright (C) 2001-06 Wolfgang M. Meier
* wolfgang@exist-db.org
* http://exist.sourceforge.net
*
* This program 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 of the License, or (at your
* option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.exist.client;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.Properties;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.exist.xmldb.XmldbURI;
/**
* This class implements the graphical login panel used to log into
* local and remote eXist database instances.
*
* @author Wolfgang M. Meier <wolfgang@exist-db.org>
* @author Tobias Wunden <tobias.wunden@o2it.ch>
*/
public class LoginPanel extends JPanel {
public static final int TYPE_REMOTE = 0;
public static final int TYPE_EMBEDDED = 1;
/** Uri for local connections */
public static final String URI_EMBEDDED = XmldbURI.EMBEDDED_SERVER_URI.toString();
/** Default uri for remote connections */
public static final String URI_REMOTE = "xmldb:exist://localhost:8080/exist/xmlrpc"; //$NON-NLS-1$
/** Name of Preference node containing favourites */
public static final String FAVOURITES_NODE = Messages.getString("LoginPanel.1"); //$NON-NLS-1$
/** The properties modified by this panel */
protected Properties properties;
/** Ui components */
JTextField username;
JPasswordField password;
JTextField cur_url;
JTextField configuration;
JButton selectConf;
JComboBox type;
JList favourites;
DefaultListModel favouritesModel;
JTextField title;
JButton btnAddFavourite;
JButton btnRemoveFavourite;
JButton btnLoadFavourite;
JButton btnExportFavourite;
JButton btnImportFavourite;
/**
* Creates a new login panel with properties
*
* @param props a list of properties modified by the panel
*/
public LoginPanel(Properties props) {
super(false);
this.properties=new Properties(props);
setupComponents();
}
/**
* Sets up the graphical components.
*/
private void setupComponents() {
GridBagLayout grid = new GridBagLayout();
setLayout(grid);
GridBagConstraints c = new GridBagConstraints();
final int inset = 5;
c.insets = new Insets(inset, inset, inset, inset);
// y pos as a counter
int gridy=0;
JLabel label = new JLabel(Messages.getString("LoginPanel.2")); //$NON-NLS-1$
c.gridx = 0;
c.gridy = gridy;
c.gridwidth = 1;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
add(label);
username = new JTextField(properties.getProperty(InteractiveClient.USER), 12);
c.gridx = 1;
c.gridy = gridy;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(username, c);
add(username);
gridy++;
label = new JLabel(Messages.getString("LoginPanel.3")); //$NON-NLS-1$
c.gridx = 0;
c.gridy = gridy;
c.gridwidth = 1;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
add(label);
password = new JPasswordField(12);
c.gridx = 1;
c.gridy = gridy;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(password, c);
add(password);
gridy++;
label = new JLabel(Messages.getString("LoginPanel.4")); //$NON-NLS-1$
c.gridx = 0;
c.gridy = gridy;
c.gridwidth = 1;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
add(label);
type = new JComboBox();
type.addItem(Messages.getString("LoginPanel.5")); //$NON-NLS-1$
// when parameter is specified, embedded mode can not be selected
boolean showEmbeddedMode =
properties.getProperty("NO_EMBED_MODE", "FALSE").equalsIgnoreCase("FALSE");
if(showEmbeddedMode){
type.addItem(Messages.getString("LoginPanel.6"));
}
final String uri=properties.getProperty("uri"); //$NON-NLS-1$
type.setSelectedIndex(uri.equals(URI_EMBEDDED) ? TYPE_EMBEDDED : TYPE_REMOTE);
type.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
switch (type.getSelectedIndex()) {
// in case embedded, default URL xmldb:exist//, allow to change conf file
case TYPE_EMBEDDED:
cur_url.setText(URI_EMBEDDED);
cur_url.setEnabled(false);
configuration.setEnabled(true);
selectConf.setEnabled(true);
break;
case TYPE_REMOTE:
cur_url.setText(!uri.equals(URI_EMBEDDED) ? uri : URI_REMOTE);
cur_url.setEnabled(true);
configuration.setEnabled(false);
selectConf.setEnabled(false);
break;
}
}
});
c.gridx = 1;
c.gridy = gridy;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
grid.setConstraints(type, c);
add(type);
gridy++;
// File chooser for a conf file in local, active in local mode
label = new JLabel(Messages.getString("LoginPanel.8")); //$NON-NLS-1$
c.gridx = 0;
c.gridy = gridy;
c.gridwidth = 1;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
add(label);
configuration = new JTextField(properties.getProperty(InteractiveClient.CONFIGURATION), 40);
// the client will run by itself the Database (needs exclusive access otherwise access is read-only)
configuration.setToolTipText(Messages.getString("LoginPanel.9")); //$NON-NLS-1$
// if type selected is remote, select a conf file should be disable
if (type.getSelectedIndex() == TYPE_REMOTE) configuration.setEnabled(false);
c.gridx = 1;
c.gridy = gridy;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(configuration, c);
add(configuration);
selectConf = new JButton(Messages.getString("LoginPanel.10")); //$NON-NLS-1$
selectConf.setToolTipText(Messages.getString("LoginPanel.11")); //$NON-NLS-1$
if (type.getSelectedIndex() == TYPE_REMOTE) selectConf.setEnabled(false);
selectConf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String conf=configuration.getText();
if (conf == null) selectConfFile(null);
else selectConfFile(new File(conf).getParentFile());
}
});
c.gridx = 2;
c.gridy = gridy;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(selectConf, c);
add(selectConf);
gridy++;
// URI, active in remote mode
label = new JLabel(Messages.getString("LoginPanel.12")); //$NON-NLS-1$
c.gridx = 0;
c.gridy = gridy;
c.gridwidth = 1;
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
add(label);
cur_url = new JTextField(uri, 20);
cur_url.setEnabled(!uri.equals(URI_EMBEDDED));
c.gridx = 1;
c.gridy = gridy;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(cur_url, c);
add(cur_url);
gridy++;
gridy++;
label = new JLabel(Messages.getString("LoginPanel.13")); //$NON-NLS-1$
c.gridx = 0;
c.gridy = gridy;
c.gridwidth = 1;
c.insets = new Insets(20, inset, inset, inset);
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
add(label);
title = new JTextField();
title.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent arg0) {
btnAddFavourite.setEnabled(title.getText().length() > 0);
}
public void removeUpdate(DocumentEvent arg0) {
btnAddFavourite.setEnabled(title.getText().length() > 0);
}
public void changedUpdate(DocumentEvent arg0) {
btnAddFavourite.setEnabled(title.getText().length() > 0);
}
});
c.gridx = 1;
c.gridy = gridy;
c.gridwidth = 2;
c.insets = new Insets(20, inset, inset, inset);
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(title, c);
add(title);
gridy++;
label = new JLabel(Messages.getString("LoginPanel.14")); //$NON-NLS-1$
c.gridx = 0;
c.gridy = gridy;
c.gridwidth = 1;
c.gridheight = 4;
c.insets = new Insets(inset, inset, inset, inset);
c.anchor = GridBagConstraints.NORTHEAST;
c.fill = GridBagConstraints.NONE;
grid.setConstraints(label, c);
add(label);
favouritesModel = new DefaultListModel();
Favourite[] f = loadFavourites();
for (int i=0; i < f.length; favouritesModel.addElement(f[i++]));
favourites = new JList(favouritesModel);
favourites.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
boolean selection = favourites.getSelectedIndex() >= 0;
btnLoadFavourite.setEnabled(selection);
btnRemoveFavourite.setEnabled(selection);
}
});
favourites.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (e.getClickCount() == 2 && favourites.getSelectedIndex() >= 0) {
Favourite f = (Favourite)favourites.getSelectedValue();
title.setText(f.getName());
username.setText(f.getUsername());
password.setText(f.getPassword());
configuration.setText(f.getConfiguration());
type.setSelectedIndex(URI_EMBEDDED.equals(f.getUrl()) ? TYPE_EMBEDDED : TYPE_REMOTE);
cur_url.setText(f.getUrl());
}
}
});
JScrollPane scroll = new JScrollPane(favourites);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll.setPreferredSize(new Dimension(200, 130));
c.gridx = 1;
c.gridy = gridy;
c.gridheight = 4;
c.insets = new Insets(inset, inset, inset, inset);
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(scroll, c);
add(scroll);
btnLoadFavourite = new JButton(Messages.getString("LoginPanel.15")); //$NON-NLS-1$
btnLoadFavourite.setToolTipText(Messages.getString("LoginPanel.16")); //$NON-NLS-1$
btnLoadFavourite.setEnabled(false);
btnLoadFavourite.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Favourite f = (Favourite)favourites.getSelectedValue();
title.setText(f.getName());
username.setText(f.getUsername());
password.setText(f.getPassword());
configuration.setText(f.getConfiguration());
type.setSelectedIndex(URI_EMBEDDED.equals(f.getUrl()) ? TYPE_EMBEDDED : TYPE_REMOTE);
cur_url.setText(f.getUrl());
}
});
c.gridx = 2;
c.gridy = gridy;
c.gridwidth = 1;
c.gridheight = 1;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(inset, inset, 15, inset);
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(btnLoadFavourite, c);
add(btnLoadFavourite);
gridy++;
btnAddFavourite = new JButton(Messages.getString("LoginPanel.17")); //$NON-NLS-1$
btnAddFavourite.setToolTipText(Messages.getString("LoginPanel.18")); //$NON-NLS-1$
btnAddFavourite.setEnabled(false);
btnAddFavourite.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String t = title.getText();
for (int i=0; i < favouritesModel.getSize(); i++) {
if (favouritesModel.elementAt(i).equals(t)) {
int result = JOptionPane.showConfirmDialog(LoginPanel.this, Messages.getString("LoginPanel.19"), Messages.getString("LoginPanel.20"), JOptionPane.YES_NO_OPTION); //$NON-NLS-1$ //$NON-NLS-2$
if (result == JOptionPane.NO_OPTION) {
return;
}
favouritesModel.remove(i);
break;
}
}
Favourite f = new Favourite(
title.getText()
, username.getText()
, new String(password.getPassword())
, cur_url.getText()
, configuration.getText()
);
favouritesModel.addElement(f);
storeFavourites(favouritesModel);
}
});
c.gridx = 2;
c.gridy = gridy;
c.gridwidth = 1;
c.gridheight = 1;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(inset, inset, inset, inset);
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(btnAddFavourite, c);
add(btnAddFavourite);
btnRemoveFavourite = new JButton(Messages.getString("LoginPanel.21")); //$NON-NLS-1$
btnRemoveFavourite.setEnabled(false);
btnRemoveFavourite.setToolTipText(Messages.getString("LoginPanel.22")); //$NON-NLS-1$
btnRemoveFavourite.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
favouritesModel.remove(favourites.getSelectedIndex());
btnRemoveFavourite.setEnabled(false);
btnLoadFavourite.setEnabled(false);
storeFavourites(favourites.getModel());
repaint();
}
});
gridy++;
c.gridx = 2;
c.gridy = gridy;
c.gridwidth = 1;
c.gridheight = 1;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(inset, inset, 15, inset);
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(btnRemoveFavourite, c);
add(btnRemoveFavourite);
btnExportFavourite = new JButton(Messages.getString("LoginPanel.23")); //$NON-NLS-1$
btnExportFavourite.setEnabled(true);
btnExportFavourite.setToolTipText(Messages.getString("LoginPanel.24")); //$NON-NLS-1$
btnExportFavourite.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
File file = new File( Messages.getString("LoginPanel.25") ); //$NON-NLS-1$
JFileChooser chooser = new JFileChooser();
chooser.setSelectedFile(file);
chooser.showSaveDialog(LoginPanel.this);
File selectedFile = chooser.getSelectedFile();
if(selectedFile==null){
JOptionPane.showMessageDialog(LoginPanel.this, Messages.getString("LoginPanel.26"), Messages.getString("LoginPanel.27"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
if(selectedFile.exists() && !selectedFile.canWrite()){
JOptionPane.showMessageDialog(LoginPanel.this, Messages.getString("LoginPanel.28"), Messages.getString("LoginPanel.29"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
exportFavourites(selectedFile);
repaint();
}
});
gridy++;
c.gridx = 2;
c.gridy = gridy;
c.gridwidth = 1;
c.gridheight = 1;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(inset, inset, inset, inset);
grid.setConstraints(btnExportFavourite, c);
add(btnExportFavourite);
btnImportFavourite = new JButton(Messages.getString("LoginPanel.30")); //$NON-NLS-1$
btnImportFavourite.setEnabled(true);
btnImportFavourite.setToolTipText(Messages.getString("LoginPanel.31")); //$NON-NLS-1$
btnImportFavourite.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
File file = new File( "favourites.xml" ); //$NON-NLS-1$
JFileChooser chooser = new JFileChooser();
chooser.setSelectedFile(file);
chooser.showOpenDialog(LoginPanel.this);
File selectedFile = chooser.getSelectedFile();
if(selectedFile==null){
JOptionPane.showMessageDialog(LoginPanel.this, Messages.getString("LoginPanel.33"), Messages.getString("LoginPanel.34"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
if(!selectedFile.canRead()){
JOptionPane.showMessageDialog(LoginPanel.this, Messages.getString("LoginPanel.35"), Messages.getString("LoginPanel.36"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
importFavourites(selectedFile);
repaint();
}
});
gridy++;
c.gridx = 2;
c.gridy = gridy;
c.gridwidth = 1;
c.gridheight = 1;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(btnImportFavourite, c);
add(btnImportFavourite);
JPanel spacer = new JPanel();
c.gridx = 2;
c.gridy = 8;
c.gridwidth = 1;
c.gridheight = 1;
c.fill = GridBagConstraints.BOTH;
grid.setConstraints(spacer, c);
add(spacer);
}
/**
* Set and return the modified properties
*/
public Properties getProperties() {
this.properties.setProperty(InteractiveClient.PASSWORD , new String(password.getPassword()));
this.properties.setProperty(InteractiveClient.URI , cur_url.getText());
this.properties.setProperty(InteractiveClient.USER , username.getText());
this.properties.setProperty(InteractiveClient.CONFIGURATION , configuration.getText());
return this.properties;
}
/**
* File chooser for a configuration file
*/
private void selectConfFile(File dir) {
JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setCurrentDirectory(dir);
if (chooser.showDialog(this, Messages.getString("LoginPanel.37")) //$NON-NLS-1$
== JFileChooser.APPROVE_OPTION) {
File f = chooser.getSelectedFile();
configuration.setText(f.getAbsolutePath());
}
}
/**
* Loads the connection favourites using the Preferences API.
*
* @return the favourites
*/
private Favourite[] loadFavourites() {
Preferences prefs = Preferences.userNodeForPackage(LoginPanel.class);
Preferences favouritesNode = prefs.node(FAVOURITES_NODE);
// Get all favourites
String favouriteNodeNames[]=new String[0];
try {
favouriteNodeNames = favouritesNode.childrenNames();
} catch (BackingStoreException ex) {
ex.printStackTrace();
}
// Copy for each connection data into Favourite array
Favourite[] favourites = new Favourite[favouriteNodeNames.length];
for(int i=0 ; i< favouriteNodeNames.length ; i++){
Preferences node = favouritesNode.node( favouriteNodeNames[i]);
Favourite favourite = new Favourite(
favouriteNodeNames[i]
, node.get(Favourite.USERNAME, "") //$NON-NLS-1$
, node.get(Favourite.PASSWORD, "") //$NON-NLS-1$
, node.get(Favourite.URL, "") //$NON-NLS-1$
, node.get(Favourite.CONFIGURATION, "") //$NON-NLS-1$
);
favourites[i]=favourite;
}
Arrays.sort(favourites);
return favourites;
}
private void storeFavourites(Favourite[] favs) {
Preferences prefs = Preferences.userNodeForPackage(LoginPanel.class);
// Clear connection node
Preferences favouritesNode = prefs.node(FAVOURITES_NODE);
try {
favouritesNode.removeNode();
} catch (BackingStoreException ex) {
ex.printStackTrace();
}
// Recreate connection node
favouritesNode = prefs.node(FAVOURITES_NODE);
// Write all favourites
for (int i=0; i < favs.length; i++) {
if(favs[i]!=null){
// Create node
Preferences favouriteNode = favouritesNode.node(favs[i].getName());
// Fill node
favouriteNode.put(Favourite.USERNAME, favs[i].getUsername());
favouriteNode.put(Favourite.PASSWORD, favs[i].getPassword());
favouriteNode.put(Favourite.URL, favs[i].getUrl());
favouriteNode.put(Favourite.CONFIGURATION, favs[i].getConfiguration());
}
}
}
/**
* Saves the connections favourites using the Preferences API.
*
* @param model the list model
*/
private void storeFavourites(ListModel model) {
Favourite favs[] = new Favourite[model.getSize()];
// Write a node for each item in model.
for (int i=0; i < model.getSize(); i++) {
favs[i]= (Favourite)model.getElementAt(i);
}
storeFavourites(favs);
}
public static boolean importFavourites(File importFile){
boolean importOk=false;
Preferences prefs = Preferences.userNodeForPackage(LoginPanel.class);
try{
FileInputStream fis = new FileInputStream(importFile);
prefs.importPreferences(fis);
importOk=true;
fis.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return importOk;
}
public static boolean exportFavourites(File exportFile){
boolean exportOk=false;
Preferences prefs = Preferences.userNodeForPackage(LoginPanel.class);
try {
FileOutputStream fos = new FileOutputStream(exportFile);
prefs.exportSubtree(fos);
exportOk=true;
fos.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return exportOk;
}
/**
* Wrapper used to hold a favourite's connection information.
*
* @author Tobias Wunden
*/
static class Favourite implements Comparable {
public static final String NAME=Messages.getString("LoginPanel.42"); //$NON-NLS-1$
public static final String USERNAME=Messages.getString("LoginPanel.43"); //$NON-NLS-1$
public static final String PASSWORD=Messages.getString("LoginPanel.44"); //$NON-NLS-1$
public static final String URL=Messages.getString("LoginPanel.45"); //$NON-NLS-1$
public static final String CONFIGURATION=Messages.getString("LoginPanel.46"); //$NON-NLS-1$
private String name;
private String username;
private String password;
private String url;
/** path to an alternate configuration file for emebeded mode */
private String configuration;
/**
* Creates a new connection favourite from the given parameters.
*
* @param name the favourite's name
* @param username the username
* @param password the password
* @param url the url
*/
public Favourite(String name, String username, String password, String url, String configuration) {
this.name = name;
this.username = username;
this.password = password;
this.url = url;
this.configuration = configuration;
}
/**
* Returns the connection name.
*
* @return the connection name
*/
public String getName() {
return name;
}
/**
* Returns the username.
*
* @return the username
*/
public String getUsername() {
return username;
}
/**
* Returns the password.
*
* @return the password
*/
public String getPassword() {
return password;
}
/**
* Returns the url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Returns the configuration file path for emebeded mode.
*
* @return the url
*/
public String getConfiguration() {
return configuration;
}
/**
* Compares <code>o</code> to this favourite by comparing the
* connection names to the object's toString() output.
*
* @see java.util.Comparator#compareTo(Object)
*/
public int compareTo(Object o) {
return name.compareTo(o.toString());
}
/**
* Returns the favourite's hashcode.
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return name.hashCode();
}
/**
* Returns <code>true</code> if this favourite equals the given object.
*
* @see java.lang.Object#equals(Object)
*/
public boolean equals(Object o) {
return name.equals(o.toString());
}
/**
* Returns the connection name.
*
* @return the connection name
*/
public String toString() {
return name;
}
}
}