/* * Copyright (C) 2007 SQL Explorer Development Team http://sourceforge.net/projects/eclipsesql * * 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.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 net.sourceforge.sqlexplorer.dbproduct; import java.util.Collection; import java.util.List; import java.util.TreeMap; import net.sourceforge.sqlexplorer.ExplorerException; import net.sourceforge.sqlexplorer.plugin.SQLExplorerPlugin; import org.dom4j.Element; import org.dom4j.tree.DefaultElement; /** * Represents a configured Alias, maintaining a pool of available connections * * Note that this superceeds the old net.sourceforge.sqlexplorer.AliasModel and * net.sourceforge.sqlexplorer.sessiontree.model.* classes. * * This is basically a large rewrite of SQLAlias, which was originally taken from SquirrelSQL; it was based on and used * parts of Squirrel which no longer exist (even in the SquirrelSQL CVS on Sourceforge) and are effectively * undocumented. Changes needed to fix bugs relating to transactions and multiple logons per alias meant that keeping * the old code became unmaintainable, hence the sweeping rewrite. * * @author John Spackman */ public class Alias { /* package */static final String ALIASES = "aliases"; /* package */static final String ALIAS = "alias"; /* package */static final String AUTO_LOGON = "auto-logon"; /* package */static final String CONNECT_AT_STARTUP = "connect-at-startup"; /* package */static final String DEFAULT_USER = "default-user"; /* package */static final String DRIVER_ID = "driver-id"; /* package */static final String FOLDER_FILTER_EXPRESSION = "folder-filter-expression"; /* package */static final String HAS_NO_USER_NAME = "has-no-user-name"; /* package */static final String NAME = "name"; /* package */static final String NAME_FILTER_EXPRESSION = "name-filter-expression"; /* package */static final String SCHEMA_FILTER_EXPRESSION = "schema-filter-expression"; /* package */static final String URL = "url"; /* package */static final String USERS = "users"; private static int s_serialNo = 0; // Descriptive name of the Alias private String name; // Driver private String driverId; // Database URL private String url; // Whether to auto-logon the default user private boolean autoLogon; // Whether to connect at startup private boolean connectAtStartup; // Filters private String folderFilterExpression = ""; private String nameFilterExpression = ""; private String schemaFilterExpression = ""; // Whether username/password are required private boolean hasNoUserName; // Default user private User defaultUser; // List of all users (including the default user), indexed by user name private TreeMap<String, User> users = new TreeMap<String, User>(); /** * Constructs a new Alias with a given name * */ public Alias(String name) { this.name = name; } /** * Constructs a new Alias with a unique name * */ public Alias() { this("new-alias-" + (++s_serialNo)); } /** * Constructs an Alias from XML, previously obtained from describeAsXml() * * @param root */ public Alias(Element root) { autoLogon = Boolean.parseBoolean(root.attributeValue(AUTO_LOGON)); connectAtStartup = Boolean.parseBoolean(root.attributeValue(CONNECT_AT_STARTUP)); driverId = root.attributeValue(DRIVER_ID); String str = root.attributeValue(HAS_NO_USER_NAME); if (str != null) { hasNoUserName = Boolean.parseBoolean(str); } name = root.elementText(NAME); url = root.elementText(URL); folderFilterExpression = root.elementText(FOLDER_FILTER_EXPRESSION); nameFilterExpression = root.elementText(NAME_FILTER_EXPRESSION); schemaFilterExpression = root.elementText(SCHEMA_FILTER_EXPRESSION); if (hasNoUserName) { User user = new User("", ""); addUser(user); setDefaultUser(user); } else { Element usersElem = root.element(USERS); if (usersElem != null) { List<Element> list = usersElem.elements(User.USER); if (list != null) { for (Element userElem : list) { User user = new User(userElem); // if (user.getUserName() != null && user.getUserName().trim().length() > 0) { addUser(user); // } } } String defaultUserName = root.elementText(DEFAULT_USER); if (defaultUserName != null) { User user = users.get(defaultUserName); if (user != null) { defaultUser = user; } } } } } /** * Describes this alias in XML; the result can be passed to the Alias(Element) constructor to refabricate it * * @return */ public Element describeAsXml() { DefaultElement root = new DefaultElement(ALIAS); root.addAttribute(AUTO_LOGON, Boolean.toString(autoLogon)); root.addAttribute(CONNECT_AT_STARTUP, Boolean.toString(connectAtStartup)); root.addAttribute(DRIVER_ID, driverId); root.addAttribute(HAS_NO_USER_NAME, Boolean.toString(hasNoUserName)); root.addElement(NAME).setText(name); root.addElement(URL).setText(url); root.addElement(FOLDER_FILTER_EXPRESSION).setText(folderFilterExpression); root.addElement(NAME_FILTER_EXPRESSION).setText(nameFilterExpression); root.addElement(SCHEMA_FILTER_EXPRESSION).setText(schemaFilterExpression); Element usersElem = root.addElement(USERS); for (User user : users.values()) { // user.setPassword(ALIAS) usersElem.add(user.describeAsXml()); } if (defaultUser != null) { root.addElement(DEFAULT_USER).setText(defaultUser.getUserName()); } return root; } /** * Constructs an Alias as a duplicate of another, but with a new name * * @param copyFrom */ public Alias(Alias copyFrom) { this("Copy of " + copyFrom.getName()); if (copyFrom.defaultUser != null) { defaultUser = copyFrom.defaultUser.createCopy(); addUser(defaultUser); } } /** * Closes all connections * * @throws ExplorerException */ public void closeAllConnections() { for (User user : users.values()) { user.closeAllSessions(); } } /** * Removes this Alias (permanently) * * @throws ExplorerException */ public void remove() { closeAllConnections(); SQLExplorerPlugin.getDefault().getAliasManager().removeAlias(getName()); } /** * Returns the name of the alias * * @return */ public String getName() { return name; } /** * Adds or redefines a User; if the user does not exist (IE there is no User object with the same user name) then * the new user is added, but if a User already exists then the passed in User is used to reconfigure the existing * User. In both cases addUser() will return the User object which remains in this Alias instance; EG when * reconfiguring a User, the reconfigured, pre-existing User object is returned. * * @param user * @return the User object which is kept in the list of Users */ public User addUser(User user) { if (user.getAlias() != null) { if (user.getAlias() != this) { throw new IllegalArgumentException("User already belongs to a different Alias"); } return user; } // if (user.getUserName() == null || user.getUserName().length() == 0) // throw new IllegalArgumentException("Illegal user name"); // if (!users.isEmpty() && hasNoUserName) // throw new IllegalArgumentException("Cannot add users when usernames are not required by the alias"); User existingUser = users.get(user.getUserName()); if (existingUser != null) { existingUser.mergeWith(user); return existingUser; } users.put(user.getUserName(), user); user.setAlias(this); if (defaultUser == null) { defaultUser = user; } SQLExplorerPlugin.getDefault().getAliasManager().modelChanged(); return user; } /** * Removes the User from the list of users * * @param user */ public void removeUser(User user) { boolean isDefault = user == defaultUser; if (user.getAlias() != this) { throw new IllegalArgumentException("User belongs to a different Alias"); } user.closeAllSessions(); user.setAlias(null); users.remove(user.getUserName()); if (isDefault) { if (!users.isEmpty()) { defaultUser = users.values().iterator().next(); } else { defaultUser = null; } } } /** * Returns the user with a given name * * @param userName * @return */ public User getUser(String userName) { return users.get(userName); } /** * Returns a list of all users * * @return */ public Collection<User> getUsers() { return users.values(); } /** * Returns true if the user belongs to this Alias * * @param user * @return */ public boolean contains(User user) { return users.values().contains(user); } /** * Returns the ISQLDriver underlying this alias * * @return */ public ManagedDriver getDriver() { return SQLExplorerPlugin.getDefault().getDriverModel().getDriver(driverId); } /** * Sets the underlying driver * * @param driver */ public void setDriver(ManagedDriver driver) { driverId = driver.getId(); } /** * Returns true if filtering is applied * * @return */ public boolean isFiltered() { return (folderFilterExpression != null && folderFilterExpression.trim().length() > 0) || (nameFilterExpression != null && nameFilterExpression.trim().length() > 0) || (schemaFilterExpression != null && schemaFilterExpression.trim().length() > 0); } public boolean isAutoLogon() { return autoLogon; } public void setAutoLogon(boolean autoLogon) { this.autoLogon = autoLogon; } public boolean isConnectAtStartup() { return connectAtStartup; } public void setConnectAtStartup(boolean connectAtStartup) { this.connectAtStartup = connectAtStartup; } public User getDefaultUser() { return defaultUser; } /** * Sets the default user, adding it to the list of users if necessary; if the defaultUser is a new user and a user * with the same username already exists then the existing user is updated and returned (see addUser()) * * @param defaultUser * @return */ public User setDefaultUser(User defaultUser) { this.defaultUser = addUser(defaultUser); return this.defaultUser; } public String getFolderFilterExpression() { return folderFilterExpression; } public void setFolderFilterExpression(String folderFilterExpression) { this.folderFilterExpression = folderFilterExpression; } public String getNameFilterExpression() { return nameFilterExpression; } public void setNameFilterExpression(String nameFilterExpression) { this.nameFilterExpression = nameFilterExpression; } public String getSchemaFilterExpression() { return schemaFilterExpression; } public void setSchemaFilterExpression(String schemaFilterExpression) { this.schemaFilterExpression = schemaFilterExpression; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public void setName(String name) { this.name = name; } public String getDriverId() { return driverId; } /** * @return the hasNoUserName */ public boolean hasNoUserName() { return hasNoUserName; } /** * @param hasNoUserName the hasNoUserName to set */ public void setHasNoUserName(boolean hasNoUserName) { if (this.hasNoUserName == hasNoUserName) { return; } this.hasNoUserName = hasNoUserName; if (hasNoUserName) { for (User user : users.values()) { user.setAlias(null); } users.clear(); User user = new User("", ""); addUser(user); setDefaultUser(user); } else { for (User user : users.values()) { user.setAlias(null); } users.clear(); } } }