001: package net.sourceforge.squirrel_sql.plugins.refactoring.commands;
002:
003: /*
004: * Copyright (C) 2006 Rob Manning
005: * manningr@users.sourceforge.net
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.sql.SQLException;
025:
026: import javax.swing.JOptionPane;
027:
028: import net.sourceforge.squirrel_sql.client.gui.db.ColumnDetailDialog;
029: import net.sourceforge.squirrel_sql.client.gui.db.ColumnListDialog;
030: import net.sourceforge.squirrel_sql.client.gui.mainframe.MainFrame;
031: import net.sourceforge.squirrel_sql.client.session.ISession;
032: import net.sourceforge.squirrel_sql.client.session.SQLExecuterTask;
033: import net.sourceforge.squirrel_sql.fw.dialects.DialectFactory;
034: import net.sourceforge.squirrel_sql.fw.dialects.HibernateDialect;
035: import net.sourceforge.squirrel_sql.fw.dialects.UserCancelledOperationException;
036: import net.sourceforge.squirrel_sql.fw.gui.ErrorDialog;
037: import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
038: import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
039: import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
040: import net.sourceforge.squirrel_sql.fw.util.StringManager;
041: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
042: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
043: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
044: import net.sourceforge.squirrel_sql.plugins.refactoring.DBUtil;
045:
046: import org.hibernate.HibernateException;
047:
048: /**
049: * Implements showing a list of columns for a selected table to the
050: * user and dropping the ones that are selected when the user presses the
051: * drop column(s) button.
052: *
053: * @author rmmannin
054: *
055: */
056: public class ModifyColumnCommand extends AbstractRefactoringCommand {
057:
058: /** Logger for this class. */
059: private final static ILogger log = LoggerController
060: .createLogger(RemoveColumnCommand.class);
061:
062: /** Internationalized strings for this class. */
063: private static final StringManager s_stringMgr = StringManagerFactory
064: .getStringManager(RemoveColumnCommand.class);
065:
066: private ColumnListDialog listDialog = null;
067:
068: private MainFrame mainFrame = null;
069:
070: private TableColumnInfo columnToModify = null;
071:
072: private HibernateDialect dialect = null;
073:
074: static interface i18n {
075: //i18n[ModifyColumnCommand.modifyOneColMsg=Exactly one column must be
076: //selected to modify]
077: String MODIFY_ONE_COL_MSG = s_stringMgr
078: .getString("ModifyColumnCommand.modifyOneColMsg");
079: }
080:
081: /**
082: * Ctor specifying the current session.
083: */
084: public ModifyColumnCommand(ISession session,
085: IDatabaseObjectInfo[] info) {
086: super (session, info);
087: }
088:
089: /**
090: * Execute this command. Save the session and selected objects in the plugin
091: * for use in paste command.
092: */
093: public void execute() {
094: if (!(_info[0] instanceof ITableInfo)) {
095: return;
096: }
097: //Show the user a dialog with a list of columns and ask them to select
098: // one or more columns to drop
099: try {
100: ITableInfo ti = (ITableInfo) _info[0];
101: TableColumnInfo[] columns = _session.getSQLConnection()
102: .getSQLMetaData().getColumnInfo(ti);
103:
104: // Don't show columns dialog if only one column exists to be modified
105: if (columns.length == 1) {
106: columnToModify = columns[0];
107: showColumnDetailsDialog();
108: return;
109: }
110:
111: if (listDialog == null) {
112: listDialog = new ColumnListDialog(columns,
113: ColumnListDialog.MODIFY_COLUMN_MODE);
114: ActionListener listener = new ColumnListSelectionActionListener();
115: listDialog.addColumnSelectionListener(listener);
116: mainFrame = _session.getApplication().getMainFrame();
117: listDialog.setLocationRelativeTo(mainFrame);
118: listDialog.setSingleSelection();
119: }
120: listDialog.setTableName(ti.getQualifiedName());
121: listDialog.setVisible(true);
122: } catch (SQLException e) {
123: log.error("Unexpected exception " + e.getMessage(), e);
124: }
125: }
126:
127: protected void getSQLFromDialog(SQLResultListener listener) {
128: TableColumnInfo to = columnDetailDialog.getColumnInfo();
129: String dbName = columnDetailDialog.getSelectedDBName();
130: HibernateDialect dialect = DialectFactory.getDialect(dbName);
131:
132: String[] result = null;
133: try {
134: result = DBUtil.getAlterSQLForColumnChange(columnToModify,
135: to, dialect);
136: } catch (HibernateException e1) {
137: String dataType = columnDetailDialog.getSelectedTypeName();
138: // TODO: I18N
139: JOptionPane.showMessageDialog(columnDetailDialog, "The "
140: + dialect.getDisplayName()
141: + " dialect doesn't support the type " + dataType,
142: "Missing Dialect Type Mapping",
143: JOptionPane.ERROR_MESSAGE);
144: } catch (UnsupportedOperationException e2) {
145: _session.showErrorMessage(e2.getMessage());
146: }
147: listener.finished(result);
148:
149: }
150:
151: private void showColumnDetailsDialog() {
152: try {
153: dialect = DialectFactory.getDialect(
154: DialectFactory.DEST_TYPE, _session.getApplication()
155: .getMainFrame(), _session.getMetaData());
156: String dbName = dialect.getDisplayName();
157: columnDetailDialog = new ColumnDetailDialog(
158: ColumnDetailDialog.MODIFY_MODE);
159: columnDetailDialog.setExistingColumnInfo(columnToModify);
160: columnDetailDialog
161: .setTableName(_info[0].getQualifiedName());
162: columnDetailDialog
163: .addShowSQLListener(new ShowSQLButtonListener());
164: columnDetailDialog
165: .addEditSQLListener(new EditSQLListener());
166: columnDetailDialog
167: .addExecuteListener(new OKButtonListener());
168: mainFrame = _session.getApplication().getMainFrame();
169: columnDetailDialog.setLocationRelativeTo(mainFrame);
170: columnDetailDialog.setSelectedDialect(dbName);
171: columnDetailDialog.setVisible(true);
172: } catch (UserCancelledOperationException ex) {
173: log.info("User cancelled the operation", ex);
174: }
175: }
176:
177: private class ColumnListSelectionActionListener implements
178: ActionListener {
179:
180: public void actionPerformed(ActionEvent e) {
181: if (listDialog == null) {
182: System.err.println("dialog was null");
183: return;
184: }
185: listDialog.setVisible(false);
186: TableColumnInfo[] colInfos = listDialog
187: .getSelectedColumnList();
188: if (colInfos == null || colInfos.length != 1) {
189: _session.showMessage(i18n.MODIFY_ONE_COL_MSG);
190: return;
191: }
192: columnToModify = colInfos[0];
193: showColumnDetailsDialog();
194: }
195: }
196:
197: private class OKButtonListener implements ActionListener,
198: SQLResultListener {
199:
200: public void finished(String[] sqls) {
201: CommandExecHandler handler = new CommandExecHandler(
202: _session);
203:
204: if (sqls == null || sqls.length == 0) {
205: // TODO: tell the user no changes
206: return;
207: }
208: for (int i = 0; i < sqls.length; i++) {
209: String sql = sqls[i];
210:
211: log.info("ModifyColumnCommand: executing SQL - " + sql);
212:
213: SQLExecuterTask executer = new SQLExecuterTask(
214: _session, sql, handler);
215:
216: // Execute the sql synchronously
217: executer.run();
218:
219: if (handler.exceptionEncountered()) {
220: // Stop processing statements
221: break;
222: }
223: }
224: columnDetailDialog.setVisible(false);
225: }
226:
227: /* (non-Javadoc)
228: * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
229: */
230: public void actionPerformed(ActionEvent e) {
231: getSQLFromDialog(this );
232: }
233:
234: }
235:
236: private class ShowSQLButtonListener implements ActionListener,
237: SQLResultListener {
238:
239: public void finished(String[] sqls) {
240: if (sqls == null || sqls.length == 0) {
241: // TODO: tell the user no changes
242: return;
243: }
244:
245: StringBuffer script = new StringBuffer();
246: for (int i = 0; i < sqls.length; i++) {
247: script.append(sqls[i]);
248: script.append(";\n\n");
249: }
250:
251: ErrorDialog sqldialog = new ErrorDialog(columnDetailDialog,
252: script.toString());
253: //i18n[ModifyColumnCommand.sqlDialogTitle=Modify column SQL]
254: String title = s_stringMgr
255: .getString("ModifyColumnCommand.sqlDialogTitle");
256: sqldialog.setTitle(title);
257: sqldialog.setVisible(true);
258: }
259:
260: /* (non-Javadoc)
261: * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
262: */
263: public void actionPerformed(ActionEvent e) {
264: getSQLFromDialog(this);
265: }
266:
267: }
268:
269: }
|