package com.quantum.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Set; import com.quantum.IQuantumConstants; import com.quantum.QuantumPlugin; import com.quantum.adapters.AdapterFactory; import com.quantum.adapters.DatabaseAdapter; import com.quantum.sql.ConnectionEstablisher; import com.quantum.sql.MultiSQLServer; import org.eclipse.jface.preference.IPreferenceStore; /** * Class Bookmark holds the "static" information of a bookmark, that is the data that * is saved and loaded from the external file and describes a bookmark. This info will * be filled up by the end user. * * @author root */ public class Bookmark implements Displayable { public static final int SCHEMA_RULE_USE_ALL = 1; public static final int SCHEMA_RULE_USE_DEFAULT = 2; public static final int SCHEMA_RULE_USE_SELECTED = 3; private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); private String name = ""; //$NON-NLS-1$ private String username = ""; //$NON-NLS-1$ private String password = ""; //$NON-NLS-1$ private String connectionUrl = ""; //$NON-NLS-1$ private JDBCDriver driver; private int schemaRule = SCHEMA_RULE_USE_ALL; /** * A quick list is a list of favourite tables that a person might want to view * without having to look at the entire list of tables. */ private Map quickList = new Hashtable(); private Set schemas = new HashSet(); private Connection connection = null; private ConnectionEstablisher connectionEstablisher; private boolean changed = true; private List queries = Collections.synchronizedList(new ArrayList()); private boolean promptForPassword = false; private boolean autoCommit = true; private String autoCommitPreference = IQuantumConstants.autoCommitTrue; private Database database; public Bookmark() { this(MultiSQLServer.getInstance()); } public Bookmark(ConnectionEstablisher connectionEstablisher) { this.connectionEstablisher = connectionEstablisher; } public Bookmark(Bookmark data) { this(); setName(data.getName()); setUsername(data.getUsername()); setPassword(data.getPassword()); setConnect(data.getConnect()); setJDBCDriver(data.getJDBCDriver()); setPromptForPassword(data.getPromptForPassword()); setAutoCommit(data.isAutoCommit()); setAutoCommitPreference(data.getAutoCommitPreference()); setSchemaRule(data.getSchemaRule()); this.schemas.addAll(data.schemas); this.quickList = new Hashtable(data.quickList); } /** * Returns the JDBC URL. * @return String */ public String getConnect() { return this.connectionUrl; } /** * Returns the password. * @return String */ public String getPassword() { if (this.promptForPassword) { return null; } else { return this.password; } } /** * Returns the username. * @return String */ public String getUsername() { return username; } /** * Sets the connect. * @param connectionUrl The connect to set */ public void setConnect(String connectionUrl) { if (connectionUrl == null) { connectionUrl = ""; //$NON-NLS-1$ } this.connectionUrl = connectionUrl; } /** * Sets the password. * @param password The password to set */ public void setPassword(String password) { if (password == null) { password = ""; //$NON-NLS-1$ } this.password = password; } /** * Sets the username. * @param username The username to set */ public void setUsername(String username) { if (username == null) { username = ""; //$NON-NLS-1$ } this.username = username; } /** * Returns the name. * @return String */ public String getName() { return name; } /** * Sets the name. * @param name The name to set */ public void setName(String name) { if (name == null) { name = ""; //$NON-NLS-1$ } if (!name.equals(this.name)) { String oldName = this.name; this.name = name; this.propertyChangeSupport.firePropertyChange("name", oldName, this.name); this.changed = true; } } public boolean isEmpty() { if (name.equals("") && //$NON-NLS-1$ username.equals("") && //$NON-NLS-1$ password.equals("") && //$NON-NLS-1$ connectionUrl.equals("") && //$NON-NLS-1$ driver.equals("") && //$NON-NLS-1$ driver == null) { return true; } return false; } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("["); //$NON-NLS-1$ buffer.append("name="); //$NON-NLS-1$ buffer.append(name); buffer.append(", "); //$NON-NLS-1$ buffer.append("username="); //$NON-NLS-1$ buffer.append(username); buffer.append(", "); //$NON-NLS-1$ buffer.append("password=****"); //$NON-NLS-1$ buffer.append(", "); //$NON-NLS-1$ buffer.append("connect="); //$NON-NLS-1$ buffer.append(connectionUrl); buffer.append(", "); //$NON-NLS-1$ buffer.append("driver="); //$NON-NLS-1$ buffer.append(driver); buffer.append("]"); //$NON-NLS-1$ return buffer.toString(); } public Connection connect(PasswordFinder passwordFinder) throws ConnectionException { boolean isConnected = isConnected(); if (this.connection == null) { this.connection = this.connectionEstablisher.connect(this, passwordFinder); } if (isConnected() != isConnected) { this.propertyChangeSupport.firePropertyChange( "connected", isConnected, isConnected()); } return this.connection; } /** * Returns the connection object. * @return the Connection object associated with the current JDBC source. * */ public Connection getConnection() throws NotConnectedException { if (this.connection == null) { throw new NotConnectedException(); } return this.connection; } /** * @return true if the BookmarkNode is connected to a JDBC source */ public boolean isConnected() { return (connection != null); } /** * Sets the connection member. From that moment on the BookmarkNode is "connected" (open) * @param connection : a valid connection to a JDBC source */ public void setConnection(Connection connection) { this.connection = connection; } public void disconnect() throws SQLException { boolean isConnected = isConnected(); try { if (this.connection != null) { this.connectionEstablisher.disconnect(this.connection); } } finally { this.connection = null; this.database = null; if (isConnected() != isConnected) { this.propertyChangeSupport.firePropertyChange( "connected", isConnected, isConnected()); } } } public void addSchema(String schema) { if (schema != null && schema.trim().length() > 0) { addSchema(new Schema(schema)); } } public void addSchema(Schema qualifier) { if (qualifier != null) { this.schemas.add(qualifier); this.changed = true; this.propertyChangeSupport.firePropertyChange("schemas", null, null); } } public void setSchemaSelections(Schema[] schemas) { this.schemas.clear(); for (int i = 0, length = (schemas == null) ? 0 : schemas.length; i < length; i++) { this.schemas.add(schemas[i]); } this.changed = true; this.propertyChangeSupport.firePropertyChange("schemas", null, null); } /** * @return a list of all the schemas that have been set up. */ public Schema[] getSchemaSelections() { List list = new ArrayList(this.schemas); Collections.sort(list); return (Schema[]) list.toArray(new Schema[list.size()]); } public Schema[] getSchemas() throws NotConnectedException, SQLException { Schema[] schemas = null; if (useUsernameAsSchema()) { // do nothing } else if (useAllSchemas()) { schemas = getDatabase().getSchemas(); } else { schemas = verifySchemas(getSchemaSelections()); } return (schemas == null || schemas.length == 0) ? new Schema[] { getDefaultSchema() } : schemas; } /** * @param schemaSelections * @return * @throws SQLException * @throws NotConnectedException */ private Schema[] verifySchemas(Schema[] schemaSelections) throws NotConnectedException, SQLException { Schema[] schemasFromDatabase = getDatabase().getSchemas(); List list = Arrays.asList(schemasFromDatabase); for (int i = 0, length = schemaSelections == null ? 0 : schemaSelections.length; i < length; i++) { schemaSelections[i].setExists(list.contains(schemaSelections[i])); } return schemaSelections; } /** * @return * @throws NotConnectedException * @throws SQLException */ private Schema getDefaultSchema() throws NotConnectedException, SQLException { String username = getDatabase().getUsername(); String actual = getAdapter().getDefaultSchema(username); return new Schema(actual, username, true); } /** * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (!(obj instanceof Bookmark)) return false; String name = ((Bookmark)obj).getName(); if (name.equals(this.getName())) return true; return false; } /** * @param listener */ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { this.propertyChangeSupport.addPropertyChangeListener(listener); } /** * @param listener */ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { this.propertyChangeSupport.removePropertyChangeListener(listener); } public void addQuickListEntry(String type, String schemaName, String name) { Entity entity = EntityFactory.getInstance().create(this, schemaName, name, type); this.quickList.put(entity.getQualifiedName(), entity); this.propertyChangeSupport.firePropertyChange("quickList", null, null); this.changed = true; } public void addQuickListEntry(Entity entity) { addQuickListEntry(entity.getType(), entity.getSchema(), entity.getName()); } public void removeQuickListEntry(Entity entity) { if (entity != null && this.quickList.containsKey(entity.getQualifiedName())) { this.quickList.remove(entity.getQualifiedName()); this.propertyChangeSupport.firePropertyChange("quickList", null, null); this.changed = true; } } public Entity[] getQuickListEntries() { return (Entity[]) this.quickList.values().toArray(new Entity[this.quickList.size()]); } public boolean hasQuickList() { return !this.quickList.isEmpty(); } /** * @return */ public boolean isChanged() { return changed; } /** * @param b */ public void setChanged(boolean b) { changed = b; } public Database getDatabase() throws NotConnectedException { if (!isConnected()) { throw new NotConnectedException(); } if (this.database == null) { this.database = new Database(this); } return this.database; } public DatabaseAdapter getAdapter() { return this.driver == null ? null : AdapterFactory.getInstance().getAdapter(this.driver.getType()); } public Entity[] getEntitiesForSchema(Schema schema, String type) throws SQLException { try { Entity[] entities = getDatabase().getEntities(this, schema, type); return entities; } catch (NotConnectedException e) { return new Entity[0]; } } public Entity getEntity(Schema schema, String name) throws SQLException { Entity result = null; if (schema != null && name != null) { Entity[] entities = getEntitiesForSchema(schema, null); for (int i = 0, length = (entities == null) ? 0 : entities.length; result == null && i < length; i++) { if (schema.equals(entities[i].getSchema()) && name.equals(entities[i].getName())) { result = entities[i]; } } } return result; } public boolean isInQuickList(Entity entity) { return this.quickList.containsKey(entity.getQualifiedName()); } /** * * @param queryString */ public void addQuery(String queryString) { if (this.queries.contains(queryString)) { this.queries.remove(queryString); } this.queries.add(queryString); int size = getQueryHistorySize(); while (this.queries.size() > size) { this.queries.remove(0); } this.propertyChangeSupport.firePropertyChange("queries", null, null); this.changed = true; } public String[] getQueries() { return (String[]) this.queries.toArray(new String[this.queries.size()]); } private int getQueryHistorySize() { IPreferenceStore store = QuantumPlugin.getDefault().getPreferenceStore(); return store.getInt(getClass().getName() + ".queryHistorySize"); //$NON-NLS-1$ } /** * @return */ public boolean getPromptForPassword() { return promptForPassword; } /** * @param b */ public void setPromptForPassword(boolean b) { promptForPassword = b; } /** * @return */ public boolean isAutoCommit() { return autoCommit; } /** * @return */ public String getAutoCommitPreference() { return autoCommitPreference; } /** * @param b */ public void setAutoCommit(boolean b) { autoCommit = b; } /** * @param string */ public void setAutoCommitPreference(String string) { autoCommitPreference = string; } // Returns true or false indicating whether this bookmark must be set to AutoCommit on connection or not public boolean getDefaultAutoCommit(){ if (autoCommitPreference.equals(IQuantumConstants.autoCommitTrue)) return true; else if (autoCommitPreference.equals(IQuantumConstants.autoCommitFalse)) return false; else if (autoCommitPreference.equals(IQuantumConstants.autoCommitSaved)) return autoCommit; return true; } public void setJDBCDriver(JDBCDriver jdbcDriver) { this.driver = BookmarkCollection.getInstance().findDriver(jdbcDriver); this.changed = true; } public JDBCDriver getJDBCDriver() { return this.driver; } public boolean useAllSchemas() { return this.schemaRule == SCHEMA_RULE_USE_ALL; } public boolean useUsernameAsSchema() { return this.schemaRule == SCHEMA_RULE_USE_DEFAULT; } public boolean useSelectedSchemas() { return this.schemaRule == SCHEMA_RULE_USE_SELECTED; } public int getSchemaRule() { return this.schemaRule; } public void setSchemaRule(int schemaRule) { if (this.schemaRule != schemaRule) { this.schemaRule = schemaRule; this.propertyChangeSupport.firePropertyChange("schemas", null, null); } } public String getDisplayName() { return this.name; } /** * @param query */ public void removeQuery(String query) { if (this.queries.remove(query)) { this.propertyChangeSupport.firePropertyChange("queries", null, null); this.changed = true; } } }