package org.objectstyle.wolips.eomodeler.actions;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.objectstyle.wolips.baseforplugins.util.StringUtils;
import org.objectstyle.wolips.baseforuiplugins.utils.ErrorUtils;
import org.objectstyle.wolips.eomodeler.core.model.EODatabaseConfig;
import org.objectstyle.wolips.eomodeler.core.model.EOModel;
import org.objectstyle.wolips.eomodeler.core.model.IEOClassLoaderFactory;
import org.objectstyle.wolips.eomodeler.core.sql.IEOSQLGenerator;
import org.objectstyle.wolips.eomodeler.core.sql.IEOSQLGeneratorFactory;
import org.objectstyle.wolips.eomodeler.core.utils.SQLUtils;
public class GenerateSQLDialog extends Dialog {
private Button _dropDatabaseButton;
private Button _dropTablesButton;
private Button _dropPrimaryKeySupportButton;
private Button _dropIndexesButton;
private Button _createSelectedEntitiesButton;
private Button _createTablesButton;
private Button _createPrimaryKeySupportButton;
private Button _createPrimaryKeyConstraintsButton;
private Button _createForeignKeyConstraintsButton;
private Button _createDatabaseButton;
private Button _createIndexesButton;
private Button _runInEntityModelerButton;
private Text _sqlText;
private EOModel _model;
private List<String> _entityNames;
private Set<EODatabaseConfig> _databaseConfigs;
private ComboViewer _databaseConfigComboViewer;
private ClassLoader _eoModelClassLoader;
private FlagChangedHandler _flagChangeHander;
private boolean _cancel;
private Cursor _waitCursor;
private Button _executeSqlButton;
private boolean _createOnlySelectedEntities;
public GenerateSQLDialog(Shell parentShell, EOModel model, List<String> entityNames) {
super(parentShell);
setShellStyle(getShellStyle() | SWT.RESIZE);
_model = model;
_entityNames = entityNames;
_flagChangeHander = new FlagChangedHandler();
}
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("SQL Generation");
}
protected Control createDialogArea(Composite parent) {
Composite control = (Composite) super.createDialogArea(parent);
GridLayout layout = new GridLayout(1, true);
layout.marginTop = 10;
layout.marginLeft = 10;
layout.marginRight = 10;
layout.numColumns = 2;
control.setLayout(layout);
_databaseConfigs = _model.getDatabaseConfigs();
if (_databaseConfigs.size() > 1) {
_databaseConfigComboViewer = new ComboViewer(control, SWT.READ_ONLY);
GridData extraInfoData = new GridData(GridData.FILL_HORIZONTAL);
extraInfoData.horizontalSpan = 2;
_databaseConfigComboViewer.setContentProvider(new DatabaseConfigContentProvider());
_databaseConfigComboViewer.setLabelProvider(new DatabaseConfigLabelProvider());
_databaseConfigComboViewer.setInput(_databaseConfigs);
_databaseConfigComboViewer.getCombo().setLayoutData(extraInfoData);
EODatabaseConfig activeDatabaseConfig = _model.getActiveDatabaseConfig();
if (activeDatabaseConfig != null) {
_databaseConfigComboViewer.setSelection(new StructuredSelection(activeDatabaseConfig));
} else {
_databaseConfigComboViewer.setSelection(new StructuredSelection(_databaseConfigs.iterator().next()));
}
_databaseConfigComboViewer.addSelectionChangedListener(_flagChangeHander);
}
_dropDatabaseButton = new Button(control, SWT.CHECK);
_dropDatabaseButton.setText("Drop Database");
_dropDatabaseButton.addSelectionListener(_flagChangeHander);
_createDatabaseButton = new Button(control, SWT.CHECK);
_createDatabaseButton.setText("Create Database");
_createDatabaseButton.addSelectionListener(_flagChangeHander);
_dropTablesButton = new Button(control, SWT.CHECK);
_dropTablesButton.setText("Drop Tables");
_dropTablesButton.setSelection(true);
_dropTablesButton.addSelectionListener(_flagChangeHander);
_createTablesButton = new Button(control, SWT.CHECK);
_createTablesButton.setText("Create Tables");
_createTablesButton.setSelection(true);
_createTablesButton.addSelectionListener(_flagChangeHander);
_dropPrimaryKeySupportButton = new Button(control, SWT.CHECK);
_dropPrimaryKeySupportButton.setText("Drop Primary Keys");
_dropPrimaryKeySupportButton.setSelection(true);
_dropPrimaryKeySupportButton.addSelectionListener(_flagChangeHander);
_createPrimaryKeySupportButton = new Button(control, SWT.CHECK);
_createPrimaryKeySupportButton.setText("Create Primary Key Support");
_createPrimaryKeySupportButton.setSelection(true);
_createPrimaryKeySupportButton.addSelectionListener(_flagChangeHander);
_dropIndexesButton = new Button(control, SWT.CHECK);
_dropIndexesButton.setText("Drop Indexes");
_dropIndexesButton.setSelection(true);
_dropIndexesButton.addSelectionListener(_flagChangeHander);
_createIndexesButton = new Button(control, SWT.CHECK);
_createIndexesButton.setText("Create Indexes");
_createIndexesButton.setSelection(true);
_createIndexesButton.addSelectionListener(_flagChangeHander);
int entityCount = (_entityNames != null) ? _entityNames.size() : 0;
_createSelectedEntitiesButton = new Button(control, SWT.CHECK);
_createSelectedEntitiesButton.setText("Create Only Selected Entities");
_createSelectedEntitiesButton.setSelection(entityCount > 0);
_createSelectedEntitiesButton.addSelectionListener(_flagChangeHander);
_createSelectedEntitiesButton.setEnabled(entityCount > 0);
_createOnlySelectedEntities = (entityCount > 0);
_createPrimaryKeyConstraintsButton = new Button(control, SWT.CHECK);
_createPrimaryKeyConstraintsButton.setText("Primary Key Constraints");
_createPrimaryKeyConstraintsButton.setSelection(true);
_createPrimaryKeyConstraintsButton.addSelectionListener(_flagChangeHander);
_runInEntityModelerButton = new Button(control, SWT.CHECK);
_runInEntityModelerButton.setText("Single Transaction Compatible");
_runInEntityModelerButton.setSelection(true);
_runInEntityModelerButton.addSelectionListener(_flagChangeHander);
_createForeignKeyConstraintsButton = new Button(control, SWT.CHECK);
_createForeignKeyConstraintsButton.setText("Foreign Key Constraints");
_createForeignKeyConstraintsButton.setSelection(true);
_createForeignKeyConstraintsButton.addSelectionListener(_flagChangeHander);
new Label(control, SWT.NONE);
_sqlText = new Text(control, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL);
GridData sqlTextData = new GridData(GridData.FILL_BOTH);
sqlTextData.heightHint = 300;
sqlTextData.widthHint = 500;
sqlTextData.verticalIndent = 10;
sqlTextData.horizontalSpan = 2;
_sqlText.setLayoutData(sqlTextData);
_sqlText.setText("Generating SQL. Please Wait ...");
_waitCursor = new Cursor(getShell().getDisplay(), SWT.CURSOR_WAIT);
generateSqlInThread();
return control;
}
public boolean close() {
boolean close = super.close();
if (_waitCursor != null) {
_waitCursor.dispose();
_waitCursor = null;
}
return close;
}
protected Control createButtonBar(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 3;
layout.makeColumnsEqualWidth = true;
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
composite.setLayout(layout);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER);
composite.setLayoutData(data);
composite.setFont(parent.getFont());
Button closeButton = new Button(composite, SWT.PUSH);
closeButton.setText("Close");
closeButton.addSelectionListener(new CloseHandler());
_executeSqlButton = new Button(composite, SWT.PUSH);
_executeSqlButton.setText("Execute SQL");
_executeSqlButton.addSelectionListener(new ExecuteSqlHandler());
getShell().setDefaultButton(closeButton);
return composite;
}
protected String yesNo(Button button) {
return (button.getSelection()) ? "YES" : "NO";
}
protected Text getSqlText() {
return _sqlText;
}
protected EODatabaseConfig getSelectedDatabaseConfig() {
EODatabaseConfig selectedDatabaseConfig = null;
if (_databaseConfigComboViewer != null) {
IStructuredSelection selection = (IStructuredSelection) _databaseConfigComboViewer.getSelection();
selectedDatabaseConfig = (EODatabaseConfig) selection.getFirstElement();
} else {
selectedDatabaseConfig = _model.getActiveDatabaseConfig();
}
return selectedDatabaseConfig;
}
protected ClassLoader getEOModelClassLoader() throws Exception {
if (_eoModelClassLoader == null) {
_eoModelClassLoader = IEOClassLoaderFactory.Utility.createClassLoader(_model);
}
return _eoModelClassLoader;
}
public void generateSqlInThread() {
_createOnlySelectedEntities = _createSelectedEntitiesButton.getSelection();
final Map<String, String> flags = new HashMap<String, String>();
flags.put("dropTables", yesNo(_dropTablesButton));
flags.put("dropPrimaryKeySupport", yesNo(_dropPrimaryKeySupportButton));
flags.put("createTables", yesNo(_createTablesButton));
flags.put("createPrimaryKeySupport", yesNo(_createPrimaryKeySupportButton));
flags.put("primaryKeyConstraints", yesNo(_createPrimaryKeyConstraintsButton));
flags.put("foreignKeyConstraints", yesNo(_createForeignKeyConstraintsButton));
flags.put("createDatabase", yesNo(_createDatabaseButton));
flags.put("dropDatabase", yesNo(_dropDatabaseButton));
flags.put("createIndexes", yesNo(_createIndexesButton));
flags.put("dropIndexes", yesNo(_dropIndexesButton));
final EODatabaseConfig selectedDatabaseConfig = getSelectedDatabaseConfig();
final boolean runInEntityModeler = _runInEntityModelerButton.getSelection();
Thread generateSqlThread = new Thread(new Runnable() {
public void run() {
generateSql(flags, selectedDatabaseConfig, runInEntityModeler);
}
}, "Generate SQL");
generateSqlThread.start();
}
protected Button getExecuteSqlButton() {
return _executeSqlButton;
}
protected synchronized void generateSql(Map flags, EODatabaseConfig selectedDatabaseConfig, boolean runInEntityModeler) {
try {
Display.getDefault().syncExec(new Runnable() {
public void run() {
getShell().setCursor(getWaitCursor());
getExecuteSqlButton().setEnabled(false);
}
});
IEOSQLGenerator sqlGenerator = IEOSQLGeneratorFactory.Utility.sqlGeneratorFactory().sqlGenerator(_model, getEntityNames(), selectedDatabaseConfig, getEOModelClassLoader(), runInEntityModeler);
final String sqlScript = sqlGenerator.generateSchemaCreationScript(flags);
Display.getDefault().syncExec(new Runnable() {
public void run() {
getSqlText().setText(sqlScript);
getExecuteSqlButton().setEnabled(true);
}
});
} catch (final Throwable t) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
getSqlText().setText("Generation Failed.");
}
});
ErrorUtils.openErrorDialog(getShell(), t);
} finally {
Display.getDefault().syncExec(new Runnable() {
public void run() {
getShell().setCursor(null);
}
});
}
}
protected String getSqlString() {
return _sqlText.getText();
}
public void executeSqlInThread() {
_createOnlySelectedEntities = _createSelectedEntitiesButton.getSelection();
boolean confirmed = MessageDialog.openConfirm(getShell(), "Execute SQL", "Are you sure you want to execute this SQL?");
if (confirmed) {
final String sqlString = getSqlString();
final EODatabaseConfig selectedDatabaseConfig = getSelectedDatabaseConfig();
final boolean runInEntityModeler = _runInEntityModelerButton.getSelection();
Thread executeSqlThread = new Thread(new Runnable() {
public void run() {
executeSql(sqlString, selectedDatabaseConfig, runInEntityModeler);
}
}, "Execute SQL");
executeSqlThread.start();
}
}
protected void setCancel(boolean cancel) {
_cancel = cancel;
}
protected Cursor getWaitCursor() {
return _waitCursor;
}
protected List<String> getEntityNames() {
return (_createOnlySelectedEntities) ? _entityNames : null;
}
protected synchronized void executeSql(String allSql, EODatabaseConfig selectedDatabaseConfig, boolean runInEntityModeler) {
try {
Display.getDefault().syncExec(new Runnable() {
public void run() {
getShell().setCursor(getWaitCursor());
}
});
IEOSQLGenerator sqlGenerator = IEOSQLGeneratorFactory.Utility.sqlGeneratorFactory().sqlGenerator(_model, getEntityNames(), selectedDatabaseConfig, getEOModelClassLoader(), runInEntityModeler);
String url = selectedDatabaseConfig.getURL();
char commandSeparatorChar;
// yes. This sucks.
if (url != null && url.toLowerCase().contains("oracle")) {
commandSeparatorChar = '/';
} else {
commandSeparatorChar = ';';
}
List<String> statements = SQLUtils.splitSQLStatements(allSql, commandSeparatorChar);
setCancel(false);
for (int statementsNum = 0; !_cancel && statementsNum < statements.size(); statementsNum++) {
String statement = statements.get(statementsNum);
statement = statement.trim().replaceAll("[\n\r]", " ");
if (statement.length() > 0) {
try {
sqlGenerator.executeSQL(statement);
} catch (final Throwable t) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
MessageDialog dialog = new MessageDialog(getShell(), "Error", null, StringUtils.getErrorMessage(t) + "\n\nThere was an error, do you want to cancel the rest of the script?", MessageDialog.QUESTION, new String[] { "Cancel", "Continue" }, 0);
int results = dialog.open();
boolean cancel = (results == 0);
setCancel(cancel);
}
});
}
}
}
Display.getDefault().syncExec(new Runnable() {
public void run() {
MessageDialog.openInformation(getShell(), "Done", "SQL Execution Complete");
}
});
} catch (final Throwable t) {
ErrorUtils.openErrorDialog(getShell(), t);
} finally {
Display.getDefault().syncExec(new Runnable() {
public void run() {
getShell().setCursor(null);
}
});
}
}
public class FlagChangedHandler implements SelectionListener, ISelectionChangedListener {
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
public void widgetSelected(SelectionEvent event) {
GenerateSQLDialog.this.generateSqlInThread();
}
public void selectionChanged(SelectionChangedEvent event) {
GenerateSQLDialog.this.generateSqlInThread();
}
}
public class ExecuteSqlHandler implements SelectionListener {
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
public void widgetSelected(SelectionEvent event) {
GenerateSQLDialog.this.executeSqlInThread();
}
}
public class CloseHandler implements SelectionListener {
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
public void widgetSelected(SelectionEvent event) {
GenerateSQLDialog.this.close();
}
}
public static class DatabaseConfigLabelProvider implements ILabelProvider {
public void addListener(ILabelProviderListener listener) {
// DO NOTHING
}
public void dispose() {
// DO NOTHING
}
public Image getImage(Object element) {
return null;
}
public String getText(Object element) {
EODatabaseConfig config = (EODatabaseConfig) element;
StringBuffer text = new StringBuffer();
text.append(config.getName());
text.append(" (");
text.append(config.getUsername());
text.append(" @ ");
text.append(config.getURL());
text.append(")");
return text.toString();
}
public boolean isLabelProperty(Object element, String property) {
return true;
}
public void removeListener(ILabelProviderListener listener) {
// DO NOTHING
}
}
public static class DatabaseConfigContentProvider implements IStructuredContentProvider {
public void dispose() {
// DO NOTHING
}
public Object[] getElements(Object inputElement) {
return ((Collection) inputElement).toArray();
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// DO NOTHING
}
}
}