1 56 package org.objectstyle.cayenne.modeler.dialog.db; 57 58 import java.sql.Connection ; 59 import java.sql.SQLException ; 60 import java.util.Arrays ; 61 import java.util.Collection ; 62 import java.util.List ; 63 64 import javax.swing.JFrame ; 65 import javax.swing.JOptionPane ; 66 import javax.swing.SwingUtilities ; 67 68 import org.apache.log4j.Logger; 69 import org.objectstyle.cayenne.CayenneException; 70 import org.objectstyle.cayenne.CayenneRuntimeException; 71 import org.objectstyle.cayenne.access.DbLoader; 72 import org.objectstyle.cayenne.access.DbLoaderDelegate; 73 import org.objectstyle.cayenne.dba.DbAdapter; 74 import org.objectstyle.cayenne.map.DataMap; 75 import org.objectstyle.cayenne.map.DbEntity; 76 import org.objectstyle.cayenne.map.ObjEntity; 77 import org.objectstyle.cayenne.map.event.DataMapEvent; 78 import org.objectstyle.cayenne.map.event.EntityEvent; 79 import org.objectstyle.cayenne.map.event.MapEvent; 80 import org.objectstyle.cayenne.modeler.Application; 81 import org.objectstyle.cayenne.modeler.ProjectController; 82 import org.objectstyle.cayenne.modeler.event.DataMapDisplayEvent; 83 import org.objectstyle.cayenne.modeler.util.LongRunningTask; 84 import org.objectstyle.cayenne.project.NamedObjectFactory; 85 import org.objectstyle.cayenne.util.Util; 86 87 92 public class DbLoaderHelper { 93 94 private static final Logger logObj = Logger.getLogger(DbLoaderHelper.class); 95 96 private static final Collection EXCLUDED_TABLES = Arrays.asList(new Object [] { 99 "AUTO_PK_SUPPORT", "auto_pk_support" 100 }); 101 102 static DbLoaderMergeDialog mergeDialog; 103 104 protected boolean overwritePreferenceSet; 105 protected boolean overwritingEntities; 106 protected boolean stoppingReverseEngineering; 107 protected boolean existingMap; 108 109 protected ProjectController mediator; 110 protected String dbUserName; 111 protected DbLoader loader; 112 protected DataMap dataMap; 113 protected String schemaName; 114 protected String tableNamePattern; 115 protected boolean loadProcedures; 116 protected String procedureNamePattern; 117 protected List schemas; 118 119 protected String loadStatusNote; 120 121 static synchronized DbLoaderMergeDialog getMergeDialogInstance() { 122 if (mergeDialog == null) { 123 mergeDialog = new DbLoaderMergeDialog(Application.getFrame()); 124 } 125 126 return mergeDialog; 127 } 128 129 public DbLoaderHelper(ProjectController mediator, Connection connection, 130 DbAdapter adapter, String dbUserName) { 131 this.dbUserName = dbUserName; 132 this.mediator = mediator; 133 this.loader = new DbLoader(connection, adapter, new LoaderDelegate()); 134 } 135 136 public void setOverwritingEntities(boolean overwritePreference) { 137 this.overwritingEntities = overwritePreference; 138 } 139 140 public void setOverwritePreferenceSet(boolean overwritePreferenceSet) { 141 this.overwritePreferenceSet = overwritePreferenceSet; 142 } 143 144 public void setStoppingReverseEngineering(boolean stopReverseEngineering) { 145 this.stoppingReverseEngineering = stopReverseEngineering; 146 } 147 148 public boolean isOverwritePreferenceSet() { 149 return overwritePreferenceSet; 150 } 151 152 public boolean isOverwritingEntities() { 153 return overwritingEntities; 154 } 155 156 public boolean isStoppingReverseEngineering() { 157 return stoppingReverseEngineering; 158 } 159 160 164 public void execute() { 165 stoppingReverseEngineering = false; 166 167 LongRunningTask loadSchemasTask = new LoadSchemasTask(Application 169 .getFrame(), "Loading Schemas"); 170 171 loadSchemasTask.startAndWait(); 172 173 if (stoppingReverseEngineering) { 174 return; 175 } 176 177 final DbLoaderOptionsDialog dialog = new DbLoaderOptionsDialog( 178 schemas, 179 dbUserName, 180 false); 181 182 try { 183 SwingUtilities.invokeAndWait(new Runnable () { 186 187 public void run() { 188 dialog.setVisible(true); 189 dialog.dispose(); 190 } 191 }); 192 } 193 catch (Throwable th) { 194 processException(th, "Error Reengineering Database"); 195 return; 196 } 197 198 if (dialog.getChoice() == DbLoaderOptionsDialog.CANCEL) { 199 return; 200 } 201 202 this.schemaName = dialog.getSelectedSchema(); 203 this.tableNamePattern = dialog.getTableNamePattern(); 204 this.loadProcedures = dialog.isLoadingProcedures(); 205 this.procedureNamePattern = dialog.getProcedureNamePattern(); 206 207 LongRunningTask loadDataMapTask = new LoadDataMapTask(Application 209 .getFrame(), "Reengineering DB"); 210 loadDataMapTask.startAndWait(); 211 } 212 213 protected void processException(final Throwable th, final String message) { 214 logObj.info("Exception on reverse engineering", Util.unwindException(th)); 215 cleanup(); 216 SwingUtilities.invokeLater(new Runnable () { 217 218 public void run() { 219 JOptionPane.showMessageDialog(Application.getFrame(), th 220 .getMessage(), message, JOptionPane.ERROR_MESSAGE); 221 } 222 }); 223 } 224 225 protected void cleanup() { 226 loadStatusNote = "Closing connection..."; 227 try { 228 if (loader.getCon() != null) { 229 loader.getCon().close(); 230 } 231 } 232 catch (SQLException e) { 233 logObj.warn("Error closing connection.", e); 234 } 235 } 236 237 final class LoaderDelegate implements DbLoaderDelegate { 238 239 public boolean overwriteDbEntity(DbEntity ent) throws CayenneException { 240 checkCanceled(); 241 242 if (!overwritePreferenceSet) { 243 DbLoaderMergeDialog dialog = DbLoaderHelper.getMergeDialogInstance(); 244 dialog.initFromModel(DbLoaderHelper.this, ent.getName()); 245 dialog.centerWindow(); 246 dialog.setVisible(true); 247 dialog.setVisible(false); 248 } 249 250 if (stoppingReverseEngineering) { 251 throw new CayenneException("Should stop DB import."); 252 } 253 254 return overwritingEntities; 255 } 256 257 public void dbEntityAdded(DbEntity entity) { 258 checkCanceled(); 259 260 loadStatusNote = "Importing table '" + entity.getName() + "'..."; 261 262 if (EXCLUDED_TABLES.contains(entity.getName()) && entity.getDataMap() != null) { 265 entity.getDataMap().removeDbEntity(entity.getName()); 266 } 267 else if (existingMap) { 268 mediator 269 .fireDbEntityEvent(new EntityEvent(this, entity, EntityEvent.ADD)); 270 } 271 } 272 273 public void objEntityAdded(ObjEntity entity) { 274 checkCanceled(); 275 276 loadStatusNote = "Creating ObjEntity '" + entity.getName() + "'..."; 277 278 if (existingMap) { 279 mediator 280 .fireObjEntityEvent(new EntityEvent(this, entity, EntityEvent.ADD)); 281 } 282 } 283 284 public void dbEntityRemoved(DbEntity entity) { 285 checkCanceled(); 286 287 if (existingMap) { 288 mediator.fireDbEntityEvent(new EntityEvent( 289 Application.getFrame(), 290 entity, 291 EntityEvent.REMOVE)); 292 } 293 } 294 295 public void objEntityRemoved(ObjEntity entity) { 296 checkCanceled(); 297 298 if (existingMap) { 299 mediator.fireObjEntityEvent(new EntityEvent(Application 300 .getFrame(), entity, EntityEvent.REMOVE)); 301 } 302 } 303 304 void checkCanceled() { 305 if (isStoppingReverseEngineering()) { 306 throw new CayenneRuntimeException("Reengineering was canceled."); 307 } 308 } 309 } 310 311 abstract class DbLoaderTask extends LongRunningTask { 312 313 public DbLoaderTask(JFrame frame, String title) { 314 super(frame, title); 315 setMinValue(0); 316 setMaxValue(10); 317 } 318 319 protected String getCurrentNote() { 320 return loadStatusNote; 321 } 322 323 protected int getCurrentValue() { 324 return getMinValue(); 325 } 326 327 protected boolean isIndeterminate() { 328 return true; 329 } 330 331 public boolean isCanceled() { 332 return isStoppingReverseEngineering(); 333 } 334 335 public void setCanceled(boolean b) { 336 if (b) { 337 loadStatusNote = "Canceling.."; 338 } 339 340 setStoppingReverseEngineering(b); 341 } 342 } 343 344 final class LoadSchemasTask extends DbLoaderTask { 345 346 public LoadSchemasTask(JFrame frame, String title) { 347 super(frame, title); 348 } 349 350 protected void execute() { 351 loadStatusNote = "Loading available schemas..."; 352 353 try { 354 schemas = loader.getSchemas(); 355 } 356 catch (Throwable th) { 357 processException(th, "Error Loading Schemas"); 358 } 359 } 360 } 361 362 final class LoadDataMapTask extends DbLoaderTask { 363 364 public LoadDataMapTask(JFrame frame, String title) { 365 super(frame, title); 366 } 367 368 protected void execute() { 369 370 loadStatusNote = "Preparing..."; 371 372 DbLoaderHelper.this.dataMap = mediator.getCurrentDataMap(); 373 DbLoaderHelper.this.existingMap = dataMap != null; 374 375 if (!existingMap) { 376 dataMap = (DataMap) NamedObjectFactory.createObject(DataMap.class, null); 377 dataMap.setName(NamedObjectFactory.createName(DataMap.class, mediator 378 .getCurrentDataDomain())); 379 dataMap.setDefaultSchema(schemaName); 380 } 381 382 if (isCanceled()) { 383 return; 384 } 385 386 loadStatusNote = "Importing tables..."; 387 388 try { 389 loader.loadDataMapFromDB(schemaName, tableNamePattern, dataMap); 390 } 391 catch (Throwable th) { 392 if (!isCanceled()) { 393 processException(th, "Error Reengineering Database"); 394 } 395 } 396 397 if (loadProcedures) { 398 loadStatusNote = "Importing procedures..."; 399 try { 400 loader 401 .loadProceduresFromDB( 402 schemaName, 403 procedureNamePattern, 404 dataMap); 405 } 406 catch (Throwable th) { 407 if (!isCanceled()) { 408 processException(th, "Error Reengineering Database"); 409 } 410 } 411 } 412 413 cleanup(); 414 415 loadStatusNote = "Updating view..."; 417 if (mediator.getCurrentDataMap() != null) { 418 mediator.fireDataMapEvent(new DataMapEvent( 419 Application.getFrame(), 420 dataMap, 421 MapEvent.CHANGE)); 422 mediator.fireDataMapDisplayEvent(new DataMapDisplayEvent( 423 Application.getFrame(), 424 dataMap, 425 mediator.getCurrentDataDomain(), 426 mediator.getCurrentDataNode())); 427 } 428 else { 429 mediator.addDataMap(Application.getFrame(), dataMap); 430 } 431 } 432 } 433 } | Popular Tags |