/*******************************************************************************
* Copyright © 2012, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.ide.ui.internal.wizards;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.datatools.connectivity.IConnectionProfile;
import org.eclipse.datatools.connectivity.IManagedConnection;
import org.eclipse.datatools.connectivity.ProfileManager;
import org.eclipse.datatools.connectivity.drivers.jdbc.IJDBCDriverDefinitionConstants;
import org.eclipse.datatools.connectivity.sqm.core.connection.ConnectionInfo;
import org.eclipse.datatools.connectivity.sqm.core.internal.ui.util.resources.ImagePath;
import org.eclipse.datatools.connectivity.sqm.internal.core.util.ConnectionUtil;
import org.eclipse.datatools.connectivity.ui.actions.AddProfileViewAction;
import org.eclipse.datatools.modelbase.sql.schema.Catalog;
import org.eclipse.datatools.modelbase.sql.schema.Database;
import org.eclipse.datatools.modelbase.sql.schema.Schema;
import org.eclipse.datatools.modelbase.sql.tables.Table;
import org.eclipse.edt.ide.internal.sql.util.RDBConnectionUtility;
import org.eclipse.edt.ide.sql.SQLPlugin;
import org.eclipse.edt.ide.ui.internal.dialogs.StatusInfo;
import org.eclipse.edt.ide.ui.internal.dialogs.StatusUtil;
import org.eclipse.edt.ide.ui.internal.record.NewRecordWizardMessages;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
public class DTOConfigPage extends WizardPage implements SelectionListener, ICheckStateListener {
private IStatus fCurrStatus;
private boolean fPageVisible;
private Combo dbConnectionCombo;
private Link newDatabaseConnectionLink;
private CheckboxTreeViewer dbTableViewer;
private Label numSelectedLabel;
private Button qualifyTableNamesCheckbox;
private Button saveConnectionToDDCheckbox;
// Page Validation
private StatusInfo databaseStatus, connectionStatus, tableStatus;
private boolean confirmOverwrite = false;
private DTOConfiguration configuration;
private Hashtable existingConnections;
protected boolean isBidi = false; // @bd1a
/**
* Constructor for SampleNewWizardPage.
*
* @param pageName
*/
public DTOConfigPage(DTOConfiguration config) {
super(DTOConfigPage.class.getName());
setTitle(NewWizardMessages.FromSqlDatabasePage_Title);
this.configuration = config;
databaseStatus = new StatusInfo();
connectionStatus = new StatusInfo();
tableStatus = new StatusInfo();
fPageVisible = false;
fCurrStatus = new StatusInfo();
}
public void createControl(Composite parent) {
initializeDialogUnits(parent);
// Create main composite
Composite composite = new Composite(parent, SWT.NONE);
composite.setFont(parent.getFont());
GridLayout layout = new GridLayout();
layout.numColumns = 1;
composite.setLayout(layout);
createDatabaseControls(composite);
createTableControls(composite);
qualifyTableNamesCheckbox = new Button(composite, SWT.CHECK);
qualifyTableNamesCheckbox.setText(NewWizardMessages.FromSqlDatabasePage_QualifyTableNames);
GridData data = new GridData();
data.horizontalSpan = 2;
qualifyTableNamesCheckbox.setLayoutData(data);
qualifyTableNamesCheckbox.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
boolean isSelected = ((Button)e.widget).getSelection();
configuration.setQualifiedTableNames(isSelected);
}
});
saveConnectionToDDCheckbox = new Button(composite, SWT.CHECK);
saveConnectionToDDCheckbox.setText(NewWizardMessages.FromSqlDatabasePage_SaveConnectionToDD);
data = new GridData();
data.horizontalSpan = 2;
saveConnectionToDDCheckbox.setLayoutData(data);
saveConnectionToDDCheckbox.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
boolean isSelected = ((Button)e.widget).getSelection();
configuration.setSaveConnectionToDeploymentDescriptor(isSelected);
}
});
setErrorMessage(null);
setMessage(null);
setControl(composite);
validatePage();
Dialog.applyDialogFont(parent);
}
public IWizardPage getNextPage() {
IWizardPage page = super.getNextPage();
return page;
}
private void createDatabaseControls(Composite composite) {
// Create the composite for the database controls
Composite dbComposite = new Composite(composite, SWT.NONE);
dbComposite.setFont(composite.getFont());
GridLayout dbLayout = new GridLayout();
dbLayout.marginWidth = dbLayout.marginHeight = 0;
dbLayout.numColumns = 2;
GridData dbData = new GridData(GridData.FILL_HORIZONTAL);
dbComposite.setLayout(dbLayout);
dbComposite.setLayoutData(dbData);
// Create the database controls
Label dbLabel = new Label(dbComposite, SWT.NONE);
dbLabel.setText(NewWizardMessages.FromSqlDatabasePage_DBConnectionlabel);
dbConnectionCombo = new Combo(dbComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
dbConnectionCombo.setLayoutData(gd);
dbConnectionCombo.addSelectionListener(this);
new Label(dbComposite, SWT.NONE);
newDatabaseConnectionLink = new Link(dbComposite, SWT.PUSH);
newDatabaseConnectionLink.setText(NewWizardMessages.FromSqlDatabasePage_CreateDBLink);
newDatabaseConnectionLink.addSelectionListener(this);
gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
newDatabaseConnectionLink.setLayoutData(gd);
initializeDatabaseValues();
}
private void createTableControls(Composite composite) {
// Create the composite for the table controls
Composite tableComposite = new Composite(composite, SWT.NONE);
tableComposite.setFont(composite.getFont());
GridLayout tableLayout = new GridLayout(1, false);
tableLayout.marginWidth = tableLayout.marginHeight = 0;
GridData tableData = new GridData(GridData.FILL_BOTH);
tableComposite.setLayout(tableLayout);
tableComposite.setLayoutData(tableData);
Label tableLabel = new Label(tableComposite, SWT.NONE);
tableLabel.setText(NewWizardMessages.FromSqlDatabasePage_TablesLabel);
dbTableViewer = new CheckboxTreeViewer(tableComposite);
dbTableViewer.setContentProvider(new DatabaseTableContentProvider());
dbTableViewer.setLabelProvider(new DatabaseTableLabelProvider());
tableData = new GridData(GridData.FILL_BOTH);
tableData.verticalSpan = 2;
dbTableViewer.getTree().setLayoutData(tableData);
dbTableViewer.setInput(configuration.getDatabaseConnection());
dbTableViewer.addCheckStateListener(this);
numSelectedLabel = new Label(tableComposite, 0);
tableData = new GridData(GridData.HORIZONTAL_ALIGN_END);
tableData.horizontalSpan = 2;
numSelectedLabel.setLayoutData(tableData);
}
private void initializeDatabaseValues() {
dbConnectionCombo.removeAll();
IConnectionProfile[] allProfiles = ProfileManager.getInstance().getProfiles();
ArrayList<IConnectionProfile> profiles = new ArrayList<IConnectionProfile>();
for (int profileCount = 0; profileCount < allProfiles.length; profileCount++) {
IConnectionProfile profile = allProfiles[profileCount];
Map factories = allProfiles[profileCount].getProvider().getConnectionFactories();
if ((factories == null) || (!factories.containsKey("java.sql.Connection"))) {
continue;
} else {
profiles.add(profile);
}
}
if (profiles != null) {
existingConnections = new Hashtable();
sortConnections(profiles);
Iterator connections = profiles.iterator();
while (connections.hasNext()) {
IConnectionProfile con = (IConnectionProfile) connections.next();
existingConnections.put(con.getName(), con);
dbConnectionCombo.add(con.getName());
}
}
}
private void sortConnections(java.util.List connections) {
Comparator c = new Comparator() {
public int compare(Object o1, Object o2) {
String s1 = ((IConnectionProfile) o1).getName();
String s2 = ((IConnectionProfile) o2).getName();
return s1.compareToIgnoreCase(s2);
}
};
Collections.sort(connections, c);
}
private void validatePage() {
databaseStatus.setOK();
tableStatus.setOK();
IConnectionProfile databaseConnection = configuration.getDatabaseConnection();
List tableContents = configuration.getSelectedTables();
String strMessage = null, strErrorMessage = null;
validateDatabaseConnection(databaseConnection, databaseStatus);
validateTables(tableContents, tableStatus);
updateStatus(new IStatus[] { connectionStatus, databaseStatus, tableStatus });
}
public void setVisible(boolean visible) {
super.setVisible(visible);
fPageVisible = visible;
if (visible && fCurrStatus.matches(IStatus.ERROR)) {
StatusInfo status = new StatusInfo();
status.setError(""); //$NON-NLS-1$
fCurrStatus = status;
}
updateStatus(fCurrStatus);
}
private void validatePageConnections() {
updateStatus(new IStatus[] { connectionStatus, databaseStatus, tableStatus });
}
public void widgetDefaultSelected(SelectionEvent e) {
}
public void widgetSelected(SelectionEvent e) {
if (e.getSource() == dbConnectionCombo) {
String connectionName = dbConnectionCombo.getText();
updateDatabaseCombo(connectionName);
if (confirmOverwrite)
confirmOverwrite = false;
} else if (e.getSource() == newDatabaseConnectionLink) {
IConnectionProfile profile = createNewProfile();
if (profile != null) {
dbConnectionCombo.add(profile.getName());
existingConnections.put(profile.getName(), profile);
dbConnectionCombo.select(dbConnectionCombo.indexOf(profile.getName()));
updateDatabaseCombo(dbConnectionCombo.getText());
}
}
//EGLDataPartsPagesMainPage
validatePage();
if (e.getSource() == dbConnectionCombo || e.getSource() == newDatabaseConnectionLink) {
validatePageConnections();
}
}
protected IConnectionProfile createNewProfile() {
AddProfileViewAction action = new AddProfileViewAction();
action.run();
return action.getAddedProfile();
}
private void updateDatabaseCombo(String connectionName) {
final IConnectionProfile selectedConnection = ((IConnectionProfile)existingConnections.get(connectionName));
configuration.setDatabaseConnection(selectedConnection); //This step must be done before inputChanged() is called
if(selectedConnection != null) {
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException {
monitor.beginTask(NewWizardMessages.FromSqlDatabasePage_RetrievingTablesTask, 1);
if(selectedConnection!=null) {
dbTableViewer.setInput(selectedConnection);
}
monitor.worked(1);
}
};
try {
new ProgressMonitorDialog(getControl().getShell()).run(false, false, runnable);
} catch(InterruptedException exp) {
} catch(InvocationTargetException exp) {
}
}
}
public void checkStateChanged(CheckStateChangedEvent event) {
if (event.getSource() == dbTableViewer) {
if (event.getChecked()) {
// . . . check all its children
dbTableViewer.setSubtreeChecked(event.getElement(), true);
} else {
dbTableViewer.setSubtreeChecked(event.getElement(), false);
}
handleTablesSelected();
}
validatePage();
}
private void handleTablesSelected() {
List selectedTables = new ArrayList();
for (Object o : dbTableViewer.getCheckedElements()) {
if (o instanceof Table) {
selectedTables.add(o);
}
}
configuration.setSelectedTables(selectedTables);
Integer tableSelected = new Integer(selectedTables.size());
numSelectedLabel.setText(NewRecordWizardMessages.bind(NewWizardMessages.FromSqlDatabasePage_TablesSelected,new String[] {tableSelected.toString()}));
//numSelectedLabel.setText(selectedTables.size() + " table(s) selected.");
numSelectedLabel.getParent().layout();
}
protected void validateDatabaseConnection(IConnectionProfile dbConnection, StatusInfo status) {
if (dbConnection == null) {
status.setError(NewWizardMessages.FromSqlDatabasePage_Validation_NoConnection);
}
}
protected void validateTables(List selectedTables, StatusInfo status) {
if (selectedTables == null || selectedTables.isEmpty()) {
status.setError(NewWizardMessages.FromSqlDatabasePage_Validation_NoTable);
}
for(int i = 0; i < selectedTables.size(); i++){
Table table1 = (Table)selectedTables.get(i);
for(int j = i + 1; j < selectedTables.size(); j ++){
Table table2 = (Table)selectedTables.get(j);
if(table1.getName().equalsIgnoreCase(table2.getName())){
status.setError(NewWizardMessages.bind(NewWizardMessages.FromSqlDatabasePage_Validation_DuplicateTable, table1.getName()));
}
}
}
}
/**
* Updates the status line and the ok button according to the given status
*
* @param status
* status to apply
*/
protected void updateStatus(IStatus status) {
fCurrStatus = status;
setPageComplete(!status.matches(IStatus.ERROR));
if (fPageVisible) {
StatusUtil.applyToStatusLine(this, status);
}
}
/**
* Updates the status line and the ok button according to the status
* evaluate from an array of status. The most severe error is taken. In case
* that two status with the same severity exists, the status with lower
* index is taken.
*
* @param status
* the array of status
*/
protected void updateStatus(IStatus[] status) {
updateStatus(StatusUtil.getMostSevere(status));
}
public class DatabaseTableLabelProvider implements ILabelProvider {
private Image schemaImage;
private Image tableImage;
public DatabaseTableLabelProvider() {
try {
URL url = new URL(ImagePath.CORE_UI_ICONS_FOLDER_URL + ImagePath.TABLE);
tableImage = ImageDescriptor.createFromURL(url).createImage();
url = new URL(ImagePath.CORE_UI_ICONS_FOLDER_URL + ImagePath.SCHEMA);
schemaImage = ImageDescriptor.createFromURL(url).createImage();
} catch (Exception ex) {
}
}
public void addListener(ILabelProviderListener listener) {
}
public void removeListener(ILabelProviderListener listener) {
}
public void dispose() {
if (schemaImage != null)
schemaImage.dispose();
if (tableImage != null)
tableImage.dispose();
}
public boolean isLabelProperty(Object element, String property) {
return true;
}
public Image getImage(Object element) {
if (element instanceof Schema) {
return schemaImage;
} else if (element instanceof org.eclipse.datatools.modelbase.sql.tables.Table) {
return tableImage;
} else {
return null;
}
}
public String getText(Object element) {
if (element instanceof org.eclipse.datatools.modelbase.sql.tables.Table) {
String tableName = ((org.eclipse.datatools.modelbase.sql.tables.Table) element).getName();
// TODO: need to figure out where bidisettings is declared
// @bd1a start
/*
* if (isBidi && null != bidiSettings.getOptions() &&
* (bidiSettings.getOptions().size() > 0)) { tableName =
* BidiUtils.bidiConvert(tableName, bidiSettings.getOptions());
* }
*/
// @bd1a end
return tableName; //$NON-NLS-1$
} else if (element instanceof Schema) {
return ((Schema) element).getName();
}
return ""; //$NON-NLS-1$
}
}
public class DatabaseTableContentProvider implements ITreeContentProvider {
IConnectionProfile model = null;
EList allSchemas;
public Object[] getElements(Object inputElement) { //inputElement should be a ConnectionInfo (may be null)
if (allSchemas != null) {
return allSchemas.toArray();
}
return null;
}
@Override
public Object[] getChildren(Object arg0) {
List ret = new ArrayList();
if (arg0 instanceof Schema) {
Schema schema = (Schema) arg0;
Iterator tableIterator = ((EList) schema.getTables()).iterator();
while (tableIterator.hasNext()) {
// may be a view
Object potentialTable = tableIterator.next();
if (potentialTable instanceof org.eclipse.datatools.modelbase.sql.tables.Table)
ret.add(((org.eclipse.datatools.modelbase.sql.tables.Table) potentialTable));
}
}
return ret.toArray();
}
@Override
public Object getParent(Object arg0) {
if (arg0 instanceof org.eclipse.datatools.modelbase.sql.tables.Table) {
return ((org.eclipse.datatools.modelbase.sql.tables.Table) arg0).getSchema();
} else {
return null;
}
}
@Override
public boolean hasChildren(Object arg0) {
if (arg0 instanceof Schema) {
Schema schema = (Schema) arg0;
// return schema.getTables().size() > 0;
return true;
} else {
return false;
}
}
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if(newInput instanceof IConnectionProfile) {
model = ((IConnectionProfile)newInput);
updateTableModel();
}
}
private void updateTableModel() {
Database database = null;
if (model != null) {
try {
if (ensureConnection()) {
if (model.getConnectionState() == IConnectionProfile.CONNECTED_STATE) {
IManagedConnection managedConnection = model.getManagedConnection(ConnectionUtil.CONNECTION_TYPE);
if (managedConnection != null) {
ConnectionInfo info = (ConnectionInfo) managedConnection.getConnection().getRawConnection();
database = info.getSharedDatabase();
// retrieve schemas, tables, and columns.
EList schemas = getSchemas(database);
allSchemas = new BasicEList();
Iterator schemaInterator = schemas.listIterator();
while (schemaInterator.hasNext()) {
Schema schema = (Schema) schemaInterator.next();
if (schema.getTables().size() > 0) {
allSchemas.add(schema);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private EList getSchemas(Database database) {
EList allSchemas = new BasicEList();
EList catalogs = database.getCatalogs();
if (catalogs != null && catalogs.size() > 0) {
Iterator itCatalogs = catalogs.iterator();
while (itCatalogs.hasNext()){
Catalog catalog = (Catalog) itCatalogs.next();
if (catalog.getSchemas() != null && catalog.getSchemas().size() > 0){
for (Iterator it = catalog.getSchemas().iterator(); it.hasNext();)
{
allSchemas.add(it.next());
}
}
}
} else {
EList schemas = database.getSchemas();
if (schemas != null && schemas.size() > 0) {
allSchemas.addAll(schemas);
}
}
return allSchemas;
}
}
public static String getSQLDatabaseVendorPreference(IConnectionProfile profile) {
String name = "";
if (profile != null) {
name = (String) profile.getBaseProperties().get(IJDBCDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID);
}
return name;
}
public static String getSQLJDBCDriverClassPreference(IConnectionProfile profile) {
String name = "";
if (profile != null) {
name = profile.getBaseProperties().getProperty(IJDBCDriverDefinitionConstants.DRIVER_CLASS_PROP_ID);
}
return name;
}
public static String getSQLDatabasePreference(IConnectionProfile profile) {
String name = "";
if (profile != null) {
name = profile.getBaseProperties().getProperty(IJDBCDriverDefinitionConstants.DATABASE_NAME_PROP_ID);
}
return name;
}
public static String getSQLConnectionURLPreference(IConnectionProfile profile) {
String name = "";
if (profile != null) {
name = profile.getBaseProperties().getProperty(IJDBCDriverDefinitionConstants.URL_PROP_ID);
}
return name;
}
private boolean ensureConnection() {
boolean isConnected = false;
IConnectionProfile profile = configuration.getDatabaseConnection();
if (profile == null) {
connectionStatus.setError(NewWizardMessages.FromSqlDatabasePage_Validation_UnableToConnect);
isConnected = false;
} else {
if (profile.getConnectionState() == IConnectionProfile.CONNECTED_STATE) {
isConnected = true;
} else {
IStatus status = RDBConnectionUtility.connectWithPromptIfNeeded(profile, SQLPlugin.getPlugin().getSQLPromptDialogOption());
if (!status.isOK()) {
connectionStatus.setError(NewWizardMessages.FromSqlDatabasePage_Validation_UnableToConnect);
} else {
isConnected = true;
}
}
}
if (isConnected) {
connectionStatus.setOK();
}
return isConnected;
}
}