1 package com.quantum.model;
3 import java.beans.PropertyChangeListener;
4 import java.beans.PropertyChangeSupport;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.HashSet;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Properties;
15 import java.util.Vector;
17 import org.w3c.dom.Element;
18 import org.w3c.dom.Node;
19 import org.w3c.dom.NodeList;
21 import com.quantum.IQuantumConstants;
22 import com.quantum.Messages;
23 import com.quantum.adapters.AdapterFactory;
24 import com.quantum.model.xml.ModelToXMLConverter;
25 import com.quantum.sql.metadata.MetaDataXMLInterface;
26 import com.quantum.util.JarUtil;
29 * The collection of database bookmarks that the Quantum plug-in knows about.
30 * This collection is loaded by the QuantumPlugin class before any Quantum plugin
31 * extension is invoked.
35 public class BookmarkCollection {
38 private static final String SUN_JDBC_ODBC_DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver";
39 private static BookmarkCollection instance = new BookmarkCollection();
40 private List bookmarks = new Vector();
41 private boolean changed = false;
42 private PropertyChangeSupport support = new PropertyChangeSupport(this);
43 private Set drivers = Collections.synchronizedSet(new HashSet());
45 private BookmarkCollection() {
51 public static BookmarkCollection getInstance() {
52 return BookmarkCollection.instance;
56 * Imports the bookmars from a properties file. This load method is
57 * provided for backwards compatability only; we no longer persist
58 * bookmarks as properties files.
61 public void load(File file) throws IOException {
62 Properties props = new Properties();
63 FileInputStream in = new FileInputStream(file);
66 fromProperties(true, props);
69 private void fromProperties(boolean overwrite, Properties props) {
70 List newBookmarks = new Vector();
73 Bookmark bookmark = new Bookmark();
74 String name = props.getProperty(i + ".name"); //$NON-NLS-1$
78 bookmark.setName(name);
79 bookmark.setUsername(props.getProperty(i + ".username")); //$NON-NLS-1$
80 bookmark.setPassword(props.getProperty(i + ".password")); //$NON-NLS-1$
81 bookmark.setConnect(props.getProperty(i + ".connect")); //$NON-NLS-1$
82 String schema = props.getProperty(i + ".schema"); //$NON-NLS-1$
84 bookmark.addSchema(schema);
86 if (!bookmark.isEmpty()) {
87 newBookmarks.add(bookmark);
90 String driver = props.getProperty(i + ".driver"); //$NON-NLS-1$
91 String driverFile = props.getProperty(i + ".driverLocation"); //$NON-NLS-1$
92 String type = props.getProperty(i + ".type"); //$NON-NLS-1$
93 this.drivers.add(new JDBCDriver(driver, new String[] { driverFile }, type));
96 this.bookmarks = newBookmarks;
98 this.bookmarks.addAll(newBookmarks);
102 * Finds a Bookmark with the specified name.
105 * @return the bookmark with the specified name, or null if no bookmark can be found
107 public Bookmark find(String name){
108 Bookmark result = null;
110 for (Iterator i = this.bookmarks.iterator(); result == null && i.hasNext(); ) {
111 Bookmark temp = (Bookmark) i.next();
112 if (name.equals(temp.getName())) {
121 * Exports a Bookmark data to an XMLDocument Element
122 * The complementary function is importXML()
123 * @param root The Element to fill up with the bookmark info
125 public void exportXML(Element root) {
126 System.out.println("Bookmarks: Saving to Element"); //$NON-NLS-1$
127 Element bookmarkRoot = MetaDataXMLInterface.createElementText(root,"bookmarks", ""); //$NON-NLS-1$ //$NON-NLS-2$
128 for (Iterator i = this.drivers.iterator(); i.hasNext(); ) {
129 JDBCDriver driver = (JDBCDriver) i.next();
130 ModelToXMLConverter.getInstance().convert(bookmarkRoot, driver);
132 for (int i = 0; i < bookmarks.size(); i++) {
133 Bookmark b = (Bookmark) bookmarks.get(i);
134 ModelToXMLConverter.getInstance().convert(bookmarkRoot, b);
139 * Imports a Bookmark data from an XMLDocument Element
140 * The complementary function is exportXML()
141 * @param root The Element from which to load
143 public void importXML(Element root) {
145 System.out.println("Bookmarks: Loading from Element"); //$NON-NLS-1$
147 Vector newBookmarks = importBookmarks(root);
148 this.bookmarks.addAll(newBookmarks);
149 this.support.firePropertyChange("bookmarks", null, null);
156 private void importDrivers(Element root) {
157 NodeList nodes = root.getElementsByTagName("jdbcDriver"); //$NON-NLS-1$
158 for (int i = 0; i < nodes.getLength(); i++) {
159 Element driver = (Element) nodes.item(i);
161 List jarFileNames = new ArrayList();
162 String jarFileName = driver.getAttribute("jarFileName");
163 if (jarFileName != null && jarFileName.trim().length() > 0) {
164 jarFileNames.add(jarFileName);
166 NodeList jars = driver.getElementsByTagName("jar");
167 for (int j = 0; j < jars.getLength(); j++) {
168 String fileName = ((Element) jars.item(j)).getAttribute("fileName");
169 if (fileName != null && fileName.trim().length() > 0) {
170 jarFileNames.add(fileName);
174 if (!isQuantum232Notation(driver)) {
175 addDriver(new JDBCDriver(
176 driver.getAttribute("className"),
177 (String[]) jarFileNames.toArray(new String[jarFileNames.size()]),
178 driver.getAttribute("type"),
179 driver.getAttribute("name"),
180 driver.getAttribute("version")));
183 addStandardDrivers();
187 * An earlier version of the Quantum XML format omitted the
193 private boolean isQuantum232Notation(Element driver) {
194 return "".equals(driver.getAttribute("type"));
200 private void addStandardDrivers() {
201 if (JarUtil.loadDriver(null, SUN_JDBC_ODBC_DRIVER) != null) {
202 addDriver(new JDBCDriver(SUN_JDBC_ODBC_DRIVER, new String[0],
203 AdapterFactory.JDBC_ODBC_BRIDGE));
210 public void addDriver(JDBCDriver driver) {
211 if (!this.drivers.contains(driver)) {
212 this.drivers.add(driver);
213 this.support.firePropertyChange("drivers", null, driver);
221 private Vector importBookmarks(Element root) {
222 Vector newBookmarks = new Vector();
223 NodeList nodes = root.getElementsByTagName("bookmark"); //$NON-NLS-1$
224 for (int i = 0; i < nodes.getLength(); i++) {
225 Bookmark bookmark = new Bookmark();
226 Element column = (Element) nodes.item(i);
228 String name = MetaDataXMLInterface.getElementText(column,"name"); //$NON-NLS-1$
229 if (name == null) break;
230 bookmark.setName(name);
232 MetaDataXMLInterface.getElementText(column,"name"); //$NON-NLS-1$
233 bookmark.setUsername(MetaDataXMLInterface.getElementText(column,"username")); //$NON-NLS-1$
234 bookmark.setPassword(MetaDataXMLInterface.getElementText(column,"password")); //$NON-NLS-1$
235 bookmark.setPromptForPassword(Boolean.TRUE.toString().equalsIgnoreCase(
236 MetaDataXMLInterface.getElementText(column,"prompt"))); //$NON-NLS-1$
237 bookmark.setConnect(MetaDataXMLInterface.getElementText(column,"connect")); //$NON-NLS-1$
238 bookmark.setAutoCommit(Boolean.TRUE.toString().equalsIgnoreCase(
239 MetaDataXMLInterface.getElementText(column,"autoCommit", "True"))); //$NON-NLS-1$
240 bookmark.setAutoCommitPreference(MetaDataXMLInterface.getElementText(column,"autoCommitPreference", IQuantumConstants.autoCommitTrue)); //$NON-NLS-1$
242 backwardCompatibility(bookmark, column);
244 String driverClassName = MetaDataXMLInterface.getElementText(column,"driver"); //$NON-NLS-1$
246 List jarFiles = new ArrayList();
247 NodeList driverLocations = column.getElementsByTagName("driverLocation");
248 for (int j = 0, length = driverLocations == null
249 ? 0 : driverLocations.getLength(); j < length; j++) {
250 String jarFileName = MetaDataXMLInterface.extractText((Element) driverLocations.item(j), "");
251 if (jarFileName != null && jarFileName.trim().length() > 0) {
252 jarFiles.add(jarFileName);
255 String type = MetaDataXMLInterface.getElementText(column,"type"); //$NON-NLS-1$
257 bookmark.setJDBCDriver(new JDBCDriver(driverClassName,
258 (String[]) jarFiles.toArray(new String[jarFiles.size()]),
261 NodeList children = column.getElementsByTagName("Other_Schemas");
262 if (children.getLength() > 0) {
263 importSchemas((Element) children.item(0), bookmark);
267 System.out.println(bookmark.toString());
268 if (!bookmark.isEmpty()) {
269 newBookmarks.addElement(bookmark);
271 importQuickList(bookmark, column);
272 importQueryList(bookmark, column);
278 * Earlier versions of the xml file expected one schema element under the
279 * bookmark element. This method sees if it exists.
284 private void backwardCompatibility(Bookmark bookmark, Element element) {
285 NodeList children = element.getChildNodes();
286 for (int i = 0, length = children.getLength(); i < length; i++) {
287 Node node = children.item(i);
288 if (node.getNodeType() == Node.ELEMENT_NODE &&
289 "schema".equals(((Element) node).getTagName())) {
290 String schema = MetaDataXMLInterface.extractText(element,"");
291 if (schema != null && schema.trim().length() > 0) {
292 bookmark.addSchema(schema);
298 private void importSchemas(Element otherSchemas, Bookmark bookmark) {
299 List list = new ArrayList();
300 NodeList children = otherSchemas.getChildNodes();
301 for (int i = 0, length = children.getLength(); i < length; i++) {
302 Node node = children.item(i);
303 if (node.getNodeType() == Node.ELEMENT_NODE
304 && "schema".equalsIgnoreCase(((Element) node).getTagName())) {
306 MetaDataXMLInterface.extractText((Element) node, "")));
310 String schemaRule = otherSchemas.getAttribute("schemaRule");
311 if ("useAll".equals(schemaRule)) {
312 bookmark.setSchemaRule(Bookmark.SCHEMA_RULE_USE_ALL);
313 } else if ("useDefault".equals(schemaRule)) {
314 bookmark.setSchemaRule(Bookmark.SCHEMA_RULE_USE_DEFAULT);
316 bookmark.setSchemaRule(Bookmark.SCHEMA_RULE_USE_SELECTED);
318 bookmark.setSchemaSelections((Schema[]) list.toArray(new Schema[list.size()]));
321 private void importQuickList(Bookmark bookmark, Element bookmarkElement) {
322 NodeList quickList = bookmarkElement.getElementsByTagName("quickList");
324 length = (quickList == null) ? 0 : quickList.getLength();
328 Element element = (Element) quickList.item(j);
329 NodeList childNodes = element.getChildNodes();
332 length2 = (childNodes == null) ? 0 : childNodes.getLength();
335 if (Node.ELEMENT_NODE == childNodes.item(k).getNodeType()) {
336 Element entity = (Element) childNodes.item(k);
337 bookmark.addQuickListEntry(entity.getTagName(),
338 entity.getAttribute("schema"), entity.getAttribute("name"));
344 private void importQueryList(Bookmark bookmark, Element bookmarkElement) {
345 NodeList queryList = bookmarkElement.getElementsByTagName("queryList");
347 length = (queryList == null) ? 0 : queryList.getLength();
351 Element element = (Element) queryList.item(i);
352 NodeList childNodes = element.getElementsByTagName("query");
355 length2 = (childNodes == null) ? 0 : childNodes.getLength();
359 Element query = (Element) childNodes.item(k);
360 bookmark.addQuery(MetaDataXMLInterface.getElementText(query,"queryString"));
366 public void addBookmark(Bookmark b) {
368 if (!bookmarks.contains(b)) {
369 Bookmark[] original = getBookmarks();
371 this.support.firePropertyChange("bookmarks", original, getBookmarks());
374 public void removeBookmark(Bookmark b) {
376 if (bookmarks.contains(b)) {
377 Bookmark[] original = getBookmarks();
379 this.support.firePropertyChange("bookmarks", original, getBookmarks());
383 public Bookmark[] getBookmarks() {
384 return (Bookmark[]) this.bookmarks.toArray(new Bookmark[this.bookmarks.size()]);
387 public JDBCDriver[] getJDBCDrivers() {
388 if (this.drivers.isEmpty()) {
389 addStandardDrivers();
392 List list = new ArrayList(this.drivers);
393 Collections.sort(list);
394 return (JDBCDriver[]) list.toArray(new JDBCDriver[list.size()]);
399 public boolean isAnythingChanged() {
400 boolean anythingChanged = this.changed;
401 for (Iterator i = this.bookmarks.iterator(); !anythingChanged && i.hasNext();) {
402 Bookmark bookmark = (Bookmark) i.next();
403 anythingChanged |= bookmark.isChanged();
405 return anythingChanged;
408 public boolean isChanged() {
415 public void setChanged(boolean changed) {
416 this.changed = changed;
422 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
423 this.support.addPropertyChangeListener(listener);
429 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
430 this.support.removePropertyChangeListener(listener);
437 public String getCopyName(String name) {
439 String copyName = Messages.getString("BookmarkView.CopyOf") + name;
441 while (find(copyName) != null)
443 copyName = Messages.getString("BookmarkView.CopyOf") + name + "(" + String.valueOf(i) + ")";
454 public JDBCDriver findDriver(String driverClassName, String[] driverFiles, String type) {
455 JDBCDriver temp = new JDBCDriver(driverClassName, driverFiles, type);
456 return findDriver(temp);
463 public JDBCDriver findDriver(JDBCDriver temp) {
464 JDBCDriver result = null;
465 for (Iterator i = this.drivers.iterator(); result == null && i.hasNext();) {
466 JDBCDriver driver = (JDBCDriver) i.next();
467 if (temp.equals(driver)) {
471 if (result == null) {
481 public boolean removeDriver(JDBCDriver driver) {
482 boolean found = false;
483 for (Iterator i = this.bookmarks.iterator();
484 !found && driver != null && i.hasNext();) {
485 Bookmark bookmark = (Bookmark) i.next();
486 found |= driver.equals(bookmark.getJDBCDriver());
489 if (!found && driver != null && !SUN_JDBC_ODBC_DRIVER.equals(driver.getClassName())) {
490 boolean deleted = this.drivers.remove(driver);
492 this.support.firePropertyChange("drivers", null, null);