KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > persistence > wizard > fromdb > DBSchemaManager


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.j2ee.persistence.wizard.fromdb;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.io.BufferedOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.sql.Connection JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.List JavaDoc;
31 import javax.swing.SwingUtilities JavaDoc;
32 import org.netbeans.api.db.explorer.ConnectionManager;
33 import org.netbeans.api.db.explorer.DatabaseConnection;
34 import org.netbeans.modules.dbschema.DBException;
35 import org.netbeans.modules.dbschema.DBIdentifier;
36 import org.netbeans.modules.dbschema.SchemaElement;
37 import org.netbeans.modules.dbschema.SchemaElementUtil;
38 import org.netbeans.modules.dbschema.jdbcimpl.ConnectionProvider;
39 import org.netbeans.modules.dbschema.jdbcimpl.SchemaElementImpl;
40 import org.netbeans.modules.dbschema.util.NameUtil;
41 import org.netbeans.modules.j2ee.persistence.util.EventRequestProcessor;
42 import org.openide.ErrorManager;
43 import org.openide.filesystems.FileLock;
44 import org.openide.filesystems.FileObject;
45 import org.openide.filesystems.FileUtil;
46 import org.openide.util.NbBundle;
47 import org.openide.util.Utilities;
48
49 /**
50  *
51  * @author Andrei Badea
52  */

53 public class DBSchemaManager {
54
55     public static final String JavaDoc DBSCHEMA_EXT = "dbschema"; // NOI18N
56

57     private final EventRequestProcessor erp = new EventRequestProcessor();
58
59     private DatabaseConnection oldDBConn;
60     private boolean oldDBConnWasConnected;
61     private Connection JavaDoc conn;
62     private SchemaElement schemaElement;
63
64     private SQLException JavaDoc exception;
65
66     private FileObject schemaFileObject;
67     private SchemaElement fileSchemaElement;
68
69     public SchemaElement getSchemaElement(final DatabaseConnection dbconn) throws SQLException JavaDoc {
70         assert SwingUtilities.isEventDispatchThread();
71
72         if (oldDBConn == dbconn && schemaElement != null) {
73             return schemaElement;
74         }
75
76         schemaElement = null;
77
78         List JavaDoc<EventRequestProcessor.Action> actions = new ArrayList JavaDoc<EventRequestProcessor.Action>();
79
80         if (oldDBConn != null && oldDBConn != dbconn && !oldDBConnWasConnected) {
81             // need to disconnect the old connection
82
actions.add(new EventRequestProcessor.AsynchronousAction() {
83                 public void run(EventRequestProcessor.Context actionContext) {
84                     actionContext.getProgress().progress(NbBundle.getMessage(DBSchemaManager.class, "LBL_ClosingPreviousConnection"));
85
86                     ConnectionManager.getDefault().disconnect(oldDBConn);
87                     oldDBConn = null;
88                     conn = null;
89                 }
90             });
91         } else {
92             // no need to disconnect the old connection, just cleanup
93
// before connecting the new connection
94
oldDBConn = null;
95             conn = null;
96         }
97
98         actions.add(new EventRequestProcessor.SynchronousAction() {
99             public void run(EventRequestProcessor.Context actionContext) {
100                 ConnectionManager.getDefault().showConnectionDialog(dbconn);
101                 conn = dbconn.getJDBCConnection();
102             }
103
104             public boolean isEnabled() {
105                 conn = dbconn.getJDBCConnection();
106                 oldDBConnWasConnected = conn != null;
107                 return !oldDBConnWasConnected;
108             }
109         });
110
111         actions.add(new EventRequestProcessor.CancellableAction() {
112
113             private SchemaElementImpl schemaElementImpl;
114             private boolean cancelled;
115
116             public void run(final EventRequestProcessor.Context actionContext) {
117                 actionContext.getProgress().progress(NbBundle.getMessage(DBSchemaManager.class, "LBL_RetrievingSchema"));
118
119                 oldDBConn = dbconn;
120
121                 ConnectionProvider connectionProvider = null;
122                 try {
123                     connectionProvider = new ConnectionProvider(conn, dbconn.getDriverClass());
124                     connectionProvider.setSchema(dbconn.getSchema());
125                 } catch (SQLException JavaDoc e) {
126                     exception = e;
127                     return;
128                 }
129
130                 synchronized (this) {
131                     if (cancelled) {
132                         return;
133                     }
134                     schemaElementImpl = new SchemaElementImpl(connectionProvider);
135                 }
136
137                 try {
138                     schemaElementImpl.setName(DBIdentifier.create("dbschema")); // NOI18N
139
} catch (DBException e) {
140                     ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
141                     return;
142                 }
143                 schemaElement = new SchemaElement(schemaElementImpl);
144
145                 schemaElementImpl.addPropertyChangeListener(new PropertyChangeListener JavaDoc() {
146                     public void propertyChange(PropertyChangeEvent JavaDoc event) {
147                         String JavaDoc propertyName = event.getPropertyName();
148                         String JavaDoc message = null;
149
150                         if ("totalCount".equals(propertyName)) { // NOI18N
151
int workunits = ((Integer JavaDoc)event.getNewValue()).intValue();
152                             actionContext.getProgress().switchToDeterminate(workunits);
153                         } else if ("progress".equals(propertyName)) { // NOI18N
154
int workunit = ((Integer JavaDoc)event.getNewValue()).intValue();
155                             actionContext.getProgress().progress(workunit);
156                         } else if ("tableName".equals(propertyName)) { // NOI18N
157
message = NbBundle.getMessage(DBSchemaManager.class, "LBL_RetrievingTable", event.getNewValue());
158                         } else if ("viewName".equals(propertyName)) { // NOI18N
159
message = NbBundle.getMessage(DBSchemaManager.class, "LBL_RetrievingView", event.getNewValue());
160                         } else if ("FKt".equals(propertyName)) { // NOI18N
161
message = NbBundle.getMessage(DBSchemaManager.class, "LBL_RetrievingTableKeys", event.getNewValue());
162                         } else if ("FKv".equals(propertyName)) { // NOI18N
163
message = NbBundle.getMessage(DBSchemaManager.class, "LBL_RetrievingViewKeys", event.getNewValue());
164                         }
165
166                         if (message != null) {
167                             actionContext.getProgress().progress(message);
168                         }
169                     }
170                 });
171
172                 schemaElementImpl.initTables(connectionProvider);
173             }
174
175             public boolean getRunInEventThread() {
176                 return false;
177             }
178
179             public boolean isEnabled() {
180                 return conn != null;
181             }
182
183             public boolean cancel() {
184                 synchronized (this) {
185                     cancelled = true;
186                     if (schemaElementImpl != null) {
187                         schemaElementImpl.setStop(true);
188                     }
189                 }
190                 return true;
191             }
192         });
193
194         exception = null;
195         boolean success = erp.invoke(actions, true);
196         if (exception != null) {
197             throw exception;
198         }
199
200         if (!success) {
201             // the Cancel button was pressed
202
schemaElement = null;
203         }
204         return schemaElement;
205     }
206
207     public SchemaElement getSchemaElement(final FileObject fo) {
208         assert SwingUtilities.isEventDispatchThread();
209
210         if (fo == schemaFileObject) {
211             return fileSchemaElement;
212         }
213
214         schemaFileObject = null;
215         fileSchemaElement = null;
216
217         List JavaDoc<EventRequestProcessor.Action> actions = new ArrayList JavaDoc<EventRequestProcessor.Action>();
218
219         actions.add(new EventRequestProcessor.AsynchronousAction() {
220             public void run(EventRequestProcessor.Context actionContext) {
221                 actionContext.getProgress().progress(NbBundle.getMessage(DBSchemaManager.class, "LBL_ReadingSchemaFile"));
222
223                 schemaFileObject = fo;
224                 fileSchemaElement = SchemaElementUtil.forName(fo);
225             }
226         });
227
228         erp.invoke(actions);
229
230         return fileSchemaElement;
231     }
232
233     /**
234      * Updates the dbschema files in the given <code>DBSchemaFileList</code> instance
235      * with the contents of the <code>schemaElement</code>
236      * parameter if these dbschema files come from the same database URL
237      * and database schema as <code>schemaElement</code>. If there are no such
238      * dbschema files a new dbschema is written in <code>folder</code>.
239      */

240     public static FileObject updateDBSchemas(SchemaElement schemaElement, DBSchemaFileList dbschemaFileList, FileObject folder, String JavaDoc projectName) throws IOException JavaDoc {
241         FileObject result = updateDBSchemas(schemaElement, dbschemaFileList);
242         if (result == null) {
243             result = writeDBSchema(schemaElement, folder, projectName);
244         }
245         return result;
246     }
247
248     /*
249      * Updates the dbschema files according to the description of
250      * {@link #updateDBSchemas(SchemaElement, DBSchemaFileList, FileObject, String)}
251      * and returns the last one.
252      */

253     private static FileObject updateDBSchemas(SchemaElement schemaElement, DBSchemaFileList dbschemaFileList) throws IOException JavaDoc {
254         FileObject updatedDBSchemaFile = null;
255         DBIdentifier schemaFullName = schemaElement.getSchema();
256         String JavaDoc schemaName = schemaFullName != null ? schemaFullName.getName() : null;
257
258         for (FileObject dbschemaFile : dbschemaFileList.getFileList()) {
259             SchemaElement existingSchemaElement = SchemaElementUtil.forName(dbschemaFile);
260             DBIdentifier existingSchemaFullName = existingSchemaElement.getSchema();
261             String JavaDoc existingSchemaName = existingSchemaFullName != null ? existingSchemaFullName.getName() : null;
262
263             if (Utilities.compareObjects(existingSchemaElement.getUrl(), schemaElement.getUrl()) &&
264                     Utilities.compareObjects(existingSchemaName, schemaName)) {
265                 DBIdentifier existingDBSchemaName = existingSchemaElement.getName();
266                 overwriteDBSchema(schemaElement, dbschemaFile, existingDBSchemaName);
267                 updatedDBSchemaFile = dbschemaFile;
268             }
269         }
270
271         return updatedDBSchemaFile;
272     }
273
274     /**
275      * Writes <code>schemaElement</code> as a new dbschema file in <code>folder</code>.
276      */

277     private static FileObject writeDBSchema(SchemaElement schemaElement, FileObject folder, String JavaDoc projectName) throws IOException JavaDoc {
278         String JavaDoc schemaName = schemaElement.getSchema().getName();
279         String JavaDoc fileName = (schemaName != null && schemaName != "" ? schemaName + "_" : "") + projectName; // NOI18N
280
// #65887: the schema name should not contain the schema db element separator
281
fileName = fileName.replace(NameUtil.dbElementSeparator, '_'); // NOI18N
282

283         String JavaDoc freeFileName = FileUtil.findFreeFileName(folder, fileName, DBSCHEMA_EXT);
284         DBIdentifier dbschemaName = DBIdentifier.create(freeFileName);
285
286         try {
287             schemaElement.setName(dbschemaName);
288         } catch (DBException e) {
289             IOException JavaDoc ioe = new IOException JavaDoc(e.getMessage());
290             ioe.initCause(e);
291             throw ioe;
292         }
293
294         FileObject dbschemaFile = folder.createData(freeFileName, DBSCHEMA_EXT);
295         writeSchemaElement(schemaElement, dbschemaFile);
296
297         return dbschemaFile;
298     }
299
300     /**
301      * Overwrites <code>dbschemaFile</code> with the contents of
302      * <code>schemaElement</code>.
303      */

304     private static void overwriteDBSchema(SchemaElement schemaElement, FileObject dbschemaFile, DBIdentifier dbschemaName) throws IOException JavaDoc {
305         try {
306             schemaElement.setName(dbschemaName);
307         } catch (DBException e) {
308             IOException JavaDoc ioe = new IOException JavaDoc(e.getMessage());
309             ioe.initCause(e);
310             throw ioe;
311         }
312
313         // cannot just overwrite the file, DBSchemaDataObject would not
314
// notice the file has changed.
315
FileObject parent = dbschemaFile.getParent();
316         String JavaDoc fileName = dbschemaFile.getName();
317         String JavaDoc fileExt = dbschemaFile.getExt();
318         dbschemaFile.delete();
319         FileObject newDBSchemaFile = parent.createData(fileName, fileExt);
320
321         writeSchemaElement(schemaElement, newDBSchemaFile);
322     }
323
324     /**
325      * Writes the contents of <code>schemaElement</code> to the existing
326      * <code>dbschemaFile</code>.
327      */

328     private static void writeSchemaElement(SchemaElement schemaElement, FileObject dbschemaFile) throws IOException JavaDoc {
329         FileLock lock = dbschemaFile.lock();
330         try {
331             OutputStream JavaDoc os = new BufferedOutputStream JavaDoc(dbschemaFile.getOutputStream(lock));
332             try {
333                 schemaElement.save(os);
334             } finally {
335                 os.close();
336             }
337         } finally {
338             lock.releaseLock();
339         }
340     }
341 }
342
Popular Tags