Merge xdebug from 1.3.x.
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / model / Bookmark.java
1 package com.quantum.model;
2
3 import java.beans.PropertyChangeListener;
4 import java.beans.PropertyChangeSupport;
5 import java.sql.Connection;
6 import java.sql.SQLException;
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import java.util.Collections;
10 import java.util.HashSet;
11 import java.util.Hashtable;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import com.quantum.IQuantumConstants;
17 import com.quantum.QuantumPlugin;
18 import com.quantum.adapters.AdapterFactory;
19 import com.quantum.adapters.DatabaseAdapter;
20 import com.quantum.sql.ConnectionEstablisher;
21 import com.quantum.sql.MultiSQLServer;
22
23 import org.eclipse.jface.preference.IPreferenceStore;
24
25 /**
26  * Class Bookmark holds the "static" information of a bookmark, that is the data that
27  * is saved and loaded from the external file and describes a bookmark. This info will
28  * be filled up by the end user.
29  * 
30  * @author root
31  */
32 public class Bookmark implements Displayable {
33         
34         public static final int SCHEMA_RULE_USE_ALL = 1;
35         public static final int SCHEMA_RULE_USE_DEFAULT = 2;
36         public static final int SCHEMA_RULE_USE_SELECTED = 3;
37     
38     private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
39         private String name = ""; //$NON-NLS-1$
40         private String username = ""; //$NON-NLS-1$
41     private String password = ""; //$NON-NLS-1$
42     private String connectionUrl = ""; //$NON-NLS-1$
43     private JDBCDriver driver;
44     
45     private int schemaRule = SCHEMA_RULE_USE_ALL;
46     
47     /**
48      * A quick list is a list of favourite tables that a person might want to view
49      * without having to look at the entire list of tables.
50      */
51     private Map quickList = new Hashtable();
52         private Set schemas = new HashSet();   
53         private Connection connection = null;
54     private ConnectionEstablisher connectionEstablisher;
55     private boolean changed = true;
56     private List queries = Collections.synchronizedList(new ArrayList());
57     private boolean promptForPassword = false;
58     private boolean autoCommit = true;
59     private String autoCommitPreference = IQuantumConstants.autoCommitTrue;
60         private Database database;
61         
62         public Bookmark() {
63         this(MultiSQLServer.getInstance());
64         }
65     
66     public Bookmark(ConnectionEstablisher connectionEstablisher) {
67         this.connectionEstablisher = connectionEstablisher;
68     }
69
70         public Bookmark(Bookmark data) {
71                 this();
72                 setName(data.getName());
73                 setUsername(data.getUsername());
74                 setPassword(data.getPassword());
75                 setConnect(data.getConnect());
76                 setJDBCDriver(data.getJDBCDriver());
77         setPromptForPassword(data.getPromptForPassword());
78         setAutoCommit(data.isAutoCommit());
79         setAutoCommitPreference(data.getAutoCommitPreference());
80         setSchemaRule(data.getSchemaRule());
81         
82         this.schemas.addAll(data.schemas);
83         this.quickList = new Hashtable(data.quickList);
84         }
85
86         /**
87          * Returns the JDBC URL.
88          * @return String
89          */
90         public String getConnect() {
91                 return this.connectionUrl;
92         }
93
94         /**
95          * Returns the password.
96          * @return String
97          */
98         public String getPassword() {
99                 if (this.promptForPassword) {
100                         return null;
101                 } else {
102                         return this.password;
103                 }
104         }
105
106         /**
107          * Returns the username.
108          * @return String
109          */
110         public String getUsername() {
111                 return username;
112         }
113
114         /**
115          * Sets the connect.
116          * @param connectionUrl The connect to set
117          */
118         public void setConnect(String connectionUrl) {
119                 if (connectionUrl == null) {
120                         connectionUrl = ""; //$NON-NLS-1$
121                 }
122                 this.connectionUrl = connectionUrl;
123         }
124
125         /**
126          * Sets the password.
127          * @param password The password to set
128          */
129         public void setPassword(String password) {
130                 if (password == null) {
131                         password = ""; //$NON-NLS-1$
132                 }
133                 this.password = password;
134         }
135
136         /**
137          * Sets the username.
138          * @param username The username to set
139          */
140         public void setUsername(String username) {
141                 if (username == null) {
142                         username = ""; //$NON-NLS-1$
143                 }
144                 this.username = username;
145         }
146
147         /**
148          * Returns the name.
149          * @return String
150          */
151         public String getName() {
152                 return name;
153         }
154
155         /**
156          * Sets the name.
157          * @param name The name to set
158          */
159         public void setName(String name) {
160                 if (name == null) {
161                         name = ""; //$NON-NLS-1$
162                 }
163         if (!name.equals(this.name)) {
164          
165             String oldName = this.name;
166             this.name = name;
167             this.propertyChangeSupport.firePropertyChange("name", oldName, this.name);
168             this.changed = true;
169         }
170         }
171
172         public boolean isEmpty() {
173                 if (name.equals("") && //$NON-NLS-1$
174                 username.equals("") && //$NON-NLS-1$
175                 password.equals("") && //$NON-NLS-1$
176                 connectionUrl.equals("") && //$NON-NLS-1$
177                 driver.equals("") && //$NON-NLS-1$
178                 driver == null) {
179                         return true;
180                 }
181                 return false;
182         }
183         public String toString() {
184                 StringBuffer buffer = new StringBuffer();
185                 buffer.append("["); //$NON-NLS-1$
186                 buffer.append("name="); //$NON-NLS-1$
187                 buffer.append(name);
188                 buffer.append(", "); //$NON-NLS-1$
189                 buffer.append("username="); //$NON-NLS-1$
190                 buffer.append(username);
191                 buffer.append(", "); //$NON-NLS-1$
192                 buffer.append("password=****"); //$NON-NLS-1$
193                 buffer.append(", "); //$NON-NLS-1$
194                 buffer.append("connect="); //$NON-NLS-1$
195                 buffer.append(connectionUrl);
196                 buffer.append(", "); //$NON-NLS-1$
197                 buffer.append("driver="); //$NON-NLS-1$
198                 buffer.append(driver);
199                 buffer.append("]"); //$NON-NLS-1$
200                 return buffer.toString();
201         }
202         
203     public Connection connect(PasswordFinder passwordFinder) throws ConnectionException {
204         boolean isConnected = isConnected();
205         if (this.connection == null) {
206             this.connection = this.connectionEstablisher.connect(this, passwordFinder);
207         }
208         
209         if (isConnected() != isConnected) {
210             this.propertyChangeSupport.firePropertyChange(
211                 "connected", isConnected, isConnected());
212         }
213         return this.connection;
214     }
215
216     /**
217          * Returns the connection object. 
218          * @return the Connection object associated with the current JDBC source.
219          * 
220          */
221     public Connection getConnection() throws NotConnectedException {
222         if (this.connection == null) {
223             throw new NotConnectedException();
224         }
225         return this.connection;
226     }
227
228     /**
229          * @return true if the BookmarkNode is connected to a JDBC source
230          */
231     public boolean isConnected() {
232         return (connection != null);
233     }
234
235     /**
236          * Sets the connection member. From that moment on the BookmarkNode is "connected" (open)
237          * @param connection : a valid connection to a JDBC source
238          */
239     public void setConnection(Connection connection) {
240         this.connection = connection;
241     }
242
243     public void disconnect() throws SQLException {
244         boolean isConnected = isConnected();
245         try {
246             if (this.connection != null) {
247                 this.connectionEstablisher.disconnect(this.connection);
248             }
249         } finally {
250             this.connection = null;
251             this.database = null;
252             if (isConnected() != isConnected) {
253                 this.propertyChangeSupport.firePropertyChange(
254                     "connected", isConnected, isConnected());
255             }
256         }
257     }
258     public void addSchema(String schema) {
259         if (schema != null && schema.trim().length() > 0) {
260             addSchema(new Schema(schema));
261         }
262     }
263
264     public void addSchema(Schema qualifier) {
265         if (qualifier != null) {
266             this.schemas.add(qualifier);
267             this.changed = true;
268             this.propertyChangeSupport.firePropertyChange("schemas", null, null);
269         }
270     }
271
272     public void setSchemaSelections(Schema[] schemas) {
273         this.schemas.clear();
274         for (int i = 0, length = (schemas == null) ? 0 : schemas.length;
275             i < length;
276             i++) {
277             this.schemas.add(schemas[i]);
278             
279         }
280         this.changed = true;
281         this.propertyChangeSupport.firePropertyChange("schemas", null, null);
282     }
283
284     /**
285      * @return a list of all the schemas that have been set up.
286      */
287     public Schema[] getSchemaSelections() {
288         List list = new ArrayList(this.schemas);
289         Collections.sort(list);
290         return (Schema[]) list.toArray(new Schema[list.size()]);
291     }
292     
293     public Schema[] getSchemas() throws NotConnectedException, SQLException {
294         Schema[] schemas = null;
295         if (useUsernameAsSchema()) {
296                 // do nothing
297         } else if (useAllSchemas()) {
298                 schemas = getDatabase().getSchemas();
299         } else {
300                 schemas = verifySchemas(getSchemaSelections());
301         }
302         return (schemas == null || schemas.length == 0) 
303                                 ? new Schema[] { getDefaultSchema() } 
304                         : schemas;
305     }
306
307         /**
308          * @param schemaSelections
309          * @return
310          * @throws SQLException
311          * @throws NotConnectedException
312          */
313         private Schema[] verifySchemas(Schema[] schemaSelections) 
314                         throws NotConnectedException, SQLException {
315                 Schema[] schemasFromDatabase = getDatabase().getSchemas();
316                 List list = Arrays.asList(schemasFromDatabase);
317                 for (int i = 0, length = schemaSelections == null ? 0 : schemaSelections.length; 
318                                 i < length; i++) {
319                         schemaSelections[i].setExists(list.contains(schemaSelections[i]));
320                 }
321                 return schemaSelections;
322         }
323
324         /**
325          * @return
326          * @throws NotConnectedException
327          * @throws SQLException
328          */
329         private Schema getDefaultSchema() throws NotConnectedException, SQLException {
330                 String username = getDatabase().getUsername();
331                 String actual = getAdapter().getDefaultSchema(username);
332                 return new Schema(actual, username, true);
333         }
334
335         /**
336          * @see java.lang.Object#equals(java.lang.Object)
337          */
338         public boolean equals(Object obj) {
339                 if (!(obj instanceof Bookmark)) return false;
340                 String name = ((Bookmark)obj).getName();
341                 if (name.equals(this.getName())) return true;
342                 return false;
343         }
344
345     /**
346      * @param listener
347      */
348     public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
349         this.propertyChangeSupport.addPropertyChangeListener(listener);
350     }
351
352     /**
353      * @param listener
354      */
355     public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
356         this.propertyChangeSupport.removePropertyChangeListener(listener);
357     }
358
359     public void addQuickListEntry(String type, String schemaName, String name, boolean isSynonym) {
360         Entity entity = EntityFactory.getInstance().create(this, schemaName, name, type, isSynonym);
361         this.quickList.put(entity.getQualifiedName(), entity);
362         this.propertyChangeSupport.firePropertyChange("quickList", null, null);
363         this.changed = true;
364     }
365     
366     public void addQuickListEntry(Entity entity) {
367         addQuickListEntry(entity.getType(), entity.getSchema(), entity.getName(), entity.isSynonym());
368     }
369     
370     public void removeQuickListEntry(Entity entity) {
371         if (entity != null  && this.quickList.containsKey(entity.getQualifiedName())) {
372             this.quickList.remove(entity.getQualifiedName());
373             this.propertyChangeSupport.firePropertyChange("quickList", null, null);
374             this.changed = true;
375         }
376     }
377     
378     public Entity[] getQuickListEntries() {
379         return (Entity[]) this.quickList.values().toArray(new Entity[this.quickList.size()]);
380     }
381     
382     public boolean hasQuickList() {
383         return !this.quickList.isEmpty();
384     }
385     /**
386      * @return
387      */
388     public boolean isChanged() {
389         return changed;
390     }
391
392     /**
393      * @param b
394      */
395     public void setChanged(boolean b) {
396         changed = b;
397     }
398     
399     public Database getDatabase() throws NotConnectedException {
400         if (!isConnected()) {
401             throw new NotConnectedException();
402         }
403         if (this.database == null) {
404                 this.database = new Database(this);
405         }
406         return this.database;
407     }
408     
409     public DatabaseAdapter getAdapter() {
410         return this.driver == null 
411                                 ? null 
412                                 : AdapterFactory.getInstance().getAdapter(this.driver.getType());
413     }
414
415     public Entity[] getEntitiesForSchema(Schema schema, String type) throws SQLException {
416         try {
417             Entity[] entities = getDatabase().getEntities(this, schema, type);
418             return entities;
419         } catch (NotConnectedException e) {
420             return new Entity[0];
421         }
422     }
423     
424     public Entity getEntity(Schema schema, String name) throws SQLException {
425         Entity result = null;
426         if (schema != null && name != null) {
427             Entity[] entities = getEntitiesForSchema(schema, null);
428             for (int i = 0, length = (entities == null) ? 0 : entities.length;
429                 result == null && i < length;
430                 i++) {
431                 if (schema.equals(entities[i].getSchema()) &&
432                     name.equals(entities[i].getName())) {
433                     result = entities[i];
434                 }
435             }
436         }
437         return result;
438     }
439     
440     public boolean isInQuickList(Entity entity) {
441         return this.quickList.containsKey(entity.getQualifiedName());
442     }
443     
444     /**
445      * 
446      * @param queryString
447      */
448     public void addQuery(String queryString) {
449         if (this.queries.contains(queryString)) {
450             this.queries.remove(queryString);
451         }
452         this.queries.add(queryString);
453         
454         int size = getQueryHistorySize();
455         
456         while (this.queries.size() > size) {
457             this.queries.remove(0);
458         }
459         this.propertyChangeSupport.firePropertyChange("queries", null, null);
460         this.changed = true;
461     }
462     
463     public String[] getQueries() {
464         return (String[]) this.queries.toArray(new String[this.queries.size()]);
465     }
466     
467     private int getQueryHistorySize() {
468         IPreferenceStore store =
469             QuantumPlugin.getDefault().getPreferenceStore();
470         return store.getInt(getClass().getName() + ".queryHistorySize"); //$NON-NLS-1$
471     }
472     /**
473      * @return
474      */
475     public boolean getPromptForPassword() {
476         return promptForPassword;
477     }
478
479     /**
480      * @param b
481      */
482     public void setPromptForPassword(boolean b) {
483         promptForPassword = b;
484     }
485
486         /**
487          * @return
488          */
489         public boolean isAutoCommit() {
490                 return autoCommit;
491         }
492
493         /**
494          * @return
495          */
496         public String getAutoCommitPreference() {
497                 return autoCommitPreference;
498         }
499
500         /**
501          * @param b
502          */
503         public void setAutoCommit(boolean b) {
504                 autoCommit = b;
505         }
506
507         /**
508          * @param string
509          */
510         public void setAutoCommitPreference(String string) {
511                 autoCommitPreference = string;
512         }
513
514         // Returns true or false indicating whether this bookmark must be set to AutoCommit on connection or not 
515         public boolean getDefaultAutoCommit(){
516                 if (autoCommitPreference.equals(IQuantumConstants.autoCommitTrue)) return true;
517                 else if (autoCommitPreference.equals(IQuantumConstants.autoCommitFalse)) return false;
518                 else if (autoCommitPreference.equals(IQuantumConstants.autoCommitSaved)) return autoCommit;
519                 
520                 return true;    
521         }
522         
523         public void setJDBCDriver(JDBCDriver jdbcDriver) {
524                 this.driver = BookmarkCollection.getInstance().findDriver(jdbcDriver);
525         this.changed = true;
526         }
527         
528         public JDBCDriver getJDBCDriver() {
529                 return this.driver;
530         }
531         public boolean useAllSchemas() {
532                 return this.schemaRule == SCHEMA_RULE_USE_ALL;
533         }
534         public boolean useUsernameAsSchema() {
535                 return this.schemaRule == SCHEMA_RULE_USE_DEFAULT;
536         }
537         public boolean useSelectedSchemas() {
538                 return this.schemaRule == SCHEMA_RULE_USE_SELECTED;
539         }
540         public int getSchemaRule() {
541                 return this.schemaRule;
542         }
543         public void setSchemaRule(int schemaRule) {
544         if (this.schemaRule != schemaRule) {
545             this.schemaRule = schemaRule;
546             this.propertyChangeSupport.firePropertyChange("schemas", null, null);
547         }
548         }
549
550         public String getDisplayName() {
551                 return this.name;
552         }
553
554         /**
555          * @param query
556          */
557         public void removeQuery(String query) {
558                 if (this.queries.remove(query)) {
559                 this.propertyChangeSupport.firePropertyChange("queries", null, null);
560                 this.changed = true;
561                 }
562         }
563 }