Author: jfuerth
Date: Wed Nov 5 11:55:24 2008
New Revision: 2813
Modified:
trunk/src/ca/sqlpower/architect/swingui/CompareDMPanel.java
trunk/src/ca/sqlpower/architect/swingui/SQLScriptDialog.java
Log:
Fix for bugs 1334 and 1661: the compare DM panel now explains why the start
button is disabled, and it does allow you to create an upgrade script even
when the older item is not a physical database.
This also includes a related prerequisite fix: I removed a useless debug
statement in the SQL Script Dialog that was causing an NPE when trying to
show the script dialog with a null target database. The SQL Script Dialog
was designed to allow this usage in the first place, so now that it's
working again, I added doc comments to make it explicit.
Modified: trunk/src/ca/sqlpower/architect/swingui/CompareDMPanel.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/CompareDMPanel.java (original)
+++ trunk/src/ca/sqlpower/architect/swingui/CompareDMPanel.java Wed Nov 5
11:55:24 2008
@@ -78,6 +78,9 @@
import ca.sqlpower.swingui.ProgressWatcher;
import ca.sqlpower.swingui.SPSUtils;
import ca.sqlpower.swingui.SPSwingWorker;
+import ca.sqlpower.validation.Status;
+import ca.sqlpower.validation.ValidateResult;
+import ca.sqlpower.validation.swingui.StatusComponent;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.debug.FormDebugPanel;
@@ -171,6 +174,16 @@
private JLabel statusLabel;
+ /**
+ * The status component that explains why the start compare action is
disabled.
+ * <p>
+ * <b>Very important note</b> that you should heed carefully:
CompareDMPanel
+ * uses the SQL Power validation API in a non-standard way because it has
been
+ * retrofit over an old ad-hoc approach to validation. Do not emulate
this approach
+ * to validation in new code!
+ */
+ private StatusComponent statusComponent = new StatusComponent();
+
private StartCompareAction startCompareAction;
private SwapSourceTargetAction swapSourceTargetAction;
@@ -859,17 +872,29 @@
* XXX: this is really similar to the getObjectToCompare()
method,
* except that it doesn't try to load the file (so it runs
quicker)
*/
- private boolean isThisPartStartable() {
+ private ValidateResult getStartabilityStatus() {
+ ValidateResult result;
+ String sourceOrTarget = isSource() ? "Older" : "Newer";
if (playPenRadio.isSelected()) {
- return true;
+ result = null;
} else if (physicalRadio.isSelected()) {
- return databaseDropdown.getSelectedItem() !=
null;
+ if (databaseDropdown.getSelectedItem() == null)
{
+ result = ValidateResult.createValidateResult(Status.FAIL,
sourceOrTarget + " physical database selection incomplete");
+ } else {
+ result = null;
+ }
} else if (loadRadio.isSelected()) {
- return new
File(loadFilePath.getText()).canRead();
+ if (new File(loadFilePath.getText()).canRead()) {
+ result = null;
+ } else {
+ result = ValidateResult.createValidateResult(Status.FAIL,
sourceOrTarget + " project file not readable");
+ }
} else {
throw new IllegalStateException(
Messages.getString("CompareDMPanel.noRadioButtonsSelected"));
//$NON-NLS-1$
}
+
+ return result;
}
/**
@@ -943,13 +968,24 @@
* Returns true iff the comparison process can start given the current
state
* of the GUI form.
*/
- public boolean isStartable() {
+ private boolean isStartable() {
logger.debug("isStartable is checking..."); //$NON-NLS-1$
- boolean startable = true;
- if (sqlButton.isSelected()) {
- startable = source.physicalRadio.isSelected() &&
sqlTypeDropdown.getSelectedItem() != null;
+ ValidateResult result = null;
+ if (sqlButton.isSelected() && sqlTypeDropdown.getSelectedItem() == null)
{
+ result = ValidateResult.createValidateResult(Status.FAIL, "Please
choose an SQL dialect");
}
- return source.isThisPartStartable() && target.isThisPartStartable()
&& startable;
+
+ if (result == null) {
+ result = source.getStartabilityStatus();
+ }
+
+ if (result == null) {
+ result = target.getStartabilityStatus();
+ }
+
+ statusComponent.setResult(result);
+
+ return result == null;
}
public Action getStartCompareAction() {
@@ -969,6 +1005,7 @@
this.parentDialog = ownerDialog;
buildUI(target.new SchemaPopulator(session),target.new
CatalogPopulator(session),
source.new SchemaPopulator(session),source.new
CatalogPopulator(session));
+ startCompareAction.setEnabled(isStartable());
addAncestorListener(playpenNameRefreshHandler);
}
@@ -986,6 +1023,11 @@
sqlTypeDropdown.setName("sqlTypeDropDown"); //$NON-NLS-1$
OutputChoiceListener listener = new
OutputChoiceListener(sqlTypeDropdown);
sqlTypeDropdown.setEnabled(false);
+ sqlTypeDropdown.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ startCompareAction.setEnabled(isStartable());
+ }
+ });
sqlButton = new JRadioButton();
sqlButton.setName(OUTPUT_SQL);
sqlButton.setActionCommand(OUTPUT_SQL);
@@ -1027,6 +1069,9 @@
CellConstraints cc = new CellConstraints();
+ builder.append(statusComponent, 11);
+ builder.nextLine();
+
builder.appendSeparator(Messages.getString("CompareDMPanel.olderSeparator"));
//$NON-NLS-1$
builder.nextLine();
builder.append(""); // takes up blank space //$NON-NLS-1$
Modified: trunk/src/ca/sqlpower/architect/swingui/SQLScriptDialog.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/SQLScriptDialog.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/SQLScriptDialog.java Wed Nov 5
11:55:24 2008
@@ -72,6 +72,12 @@
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
+/**
+ * A collection of components that present a series of SQL statements (a
+ * "script") to the user, and allows the user to execute the script
against a
+ * pre-arranged target database, copy it to the system clipboard, or save
it to
+ * a file.
+ */
public class SQLScriptDialog extends JDialog {
private static final Logger logger =
Logger.getLogger(SQLScriptDialog.class);
@@ -95,6 +101,38 @@
private MonitorableWorker executeTask;
+ /**
+ * Creates and packs a new SQL script dialog, but does not display it.
Call
+ * setVisible(true) to show the dialog, which will appear over or near
the
+ * given owner.
+ *
+ * @param owner
+ * The dialog that owns this dialog. Can be null only if
this
+ * dialog is not modal.
+ * @param title
+ * The text to show in the dialog's title bar.
+ * @param header
+ * The text to show inside the dialog body above the SQL
+ * statements.
+ * @param modal
+ * Incidates if the generated dialog should be
application-modal.
+ * If this is true, the owner parameter must not be null.
+ * @param gen
+ * The DDL generator that supplies the SQL script. The
script
+ * will be obtained by a call to
+ * [EMAIL PROTECTED] DDLGenerator#getDdlStatements()}.
+ * XXX: this should be a List of DDLStatement instead
+ * @param targetDataSource
+ * The database to execute the statements in. This can be
null,
+ * in which case the execute button will not function. Save
and
+ * copy will still work.
+ * @param closeParent
+ * If true, this dialog's owner will be closed when this
dialog
+ * closes. XXX: this is probably not the best place for
this feature
+ * @param session
+ * The session that provides the SPSwingWorkerRegistry.
+ * XXX: this should be specified as a SwingWorkerRegistry
+ */
public SQLScriptDialog(Dialog owner, String title, String header, boolean
modal,
DDLGenerator gen, SPDataSource targetDataSource,
boolean closeParent, ArchitectSwingSession session )
@@ -149,8 +187,6 @@
Action copy = new CopyAction(sqlDoc);
Action execute = null;
- logger.debug(targetDataSource.get(SPDataSource.PL_UID));
//$NON-NLS-1$
-
execute = new AbstractAction(){
public void actionPerformed(ActionEvent e) {
if (targetDataSource.get(SPDataSource.PL_UID) !=
null) {
@@ -338,9 +374,9 @@
logger.info("Starting DDL Generation at " + new
java.util.Date(System.currentTimeMillis())); //$NON-NLS-1$
logger.info("Database Target: " + target.getDataSource());
//$NON-NLS-1$
logger.info("Playpen Dump: " +
target.getDataSource()); //$NON-NLS-1$
- Iterator it = statements.iterator();
+ Iterator<DDLStatement> it =
statements.iterator();
while (it.hasNext() && !finished &&
!isCancelled()) {
- DDLStatement ddlStmt = (DDLStatement)
it.next();
+ DDLStatement ddlStmt = it.next();
try {
stmtsTried++;
logger.info("executing: " +
ddlStmt.getSQLText()); //$NON-NLS-1$