/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.modelgenerator.ldap.ui.wizards.pages.definition; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.apache.directory.studio.connection.ui.RunnableContextRunner; import org.apache.directory.studio.ldapbrowser.core.jobs.FetchBaseDNsRunnable; import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.datatools.connectivity.IConnectionProfile; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.LabelProvider; 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.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.help.IWorkbenchHelpSystem; import org.teiid.core.designer.event.IChangeListener; import org.teiid.core.designer.event.IChangeNotifier; import org.teiid.core.designer.util.StringConstants; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.datatools.profiles.ldap.ILdapProfileConstants; import org.teiid.designer.datatools.ui.dialogs.ConnectionProfileWorker; import org.teiid.designer.datatools.ui.dialogs.IProfileChangedListener; import org.teiid.designer.modelgenerator.ldap.ui.ModelGeneratorLdapUiConstants; import org.teiid.designer.modelgenerator.ldap.ui.wizards.LdapImportWizard; import org.teiid.designer.modelgenerator.ldap.ui.wizards.LdapImportWizardManager; import org.teiid.designer.modelgenerator.ldap.ui.wizards.LdapPageUtils; import org.teiid.designer.ui.common.UiConstants.ConnectionProfileIds; import org.teiid.designer.ui.common.util.UiUtil; import org.teiid.designer.ui.common.util.WidgetFactory; import org.teiid.designer.ui.common.util.WidgetUtil; import org.teiid.designer.ui.common.util.WizardUtil; import org.teiid.designer.ui.viewsupport.ModelNameUtil; /** * Wizard page for specifying the connection parameters */ public class LdapDefinitionPage extends WizardPage implements IChangeListener, IProfileChangedListener, ModelGeneratorLdapUiConstants, ModelGeneratorLdapUiConstants.Images, ModelGeneratorLdapUiConstants.HelpContexts, ILdapProfileConstants, StringConstants { /** <code>IDialogSetting</code>s key for saved dialog height. */ private static final String DIALOG_HEIGHT = "dialogHeight"; //$NON-NLS-1$ /** <code>IDialogSetting</code>s key for saved dialog width. */ private static final String DIALOG_WIDTH = "dialogWidth"; //$NON-NLS-1$ /** <code>IDialogSetting</code>s key for saved dialog X position. */ private static final String DIALOG_X = "dialogX"; //$NON-NLS-1$ /** <code>IDialogSetting</code>s key for saved dialog Y position. */ private static final String DIALOG_Y = "dialogY"; //$NON-NLS-1$ private static final String EMPTY_STR = ""; //$NON-NLS-1$ /* The import manager. */ private final LdapImportWizardManager importManager; private Button newCPButton; private Button editCPButton; private Combo connectionProfilesCombo; private ILabelProvider profileLabelProvider; private ConnectionProfileWorker profileWorker; /** Source and target text fields */ private Text ldapURIText; private Combo baseDNCombo; private Button fetchBaseDnsButton; private SourceModelPanel sourceModelPanel; private boolean synchronising; /** * Constructs the page with the provided import manager * * @param theImportManager * the import manager object */ public LdapDefinitionPage(LdapImportWizardManager theImportManager) { super(LdapDefinitionPage.class.getSimpleName(), getString("title"), null); //$NON-NLS-1$ this.importManager = theImportManager; setImageDescriptor(LdapImportWizard.BANNER); this.importManager.addChangeListener(this); } private static String getString(String key, Object... properties) { return ModelGeneratorLdapUiConstants.UTIL.getString(LdapDefinitionPage.class.getSimpleName() + "_" + key, properties); //$NON-NLS-1$ } /** * @return the synchronising */ private boolean isSynchronising() { return this.synchronising; } /** * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ @Override public void createControl(Composite theParent) { // // create main container // this.profileWorker = new ConnectionProfileWorker(this.getShell(), ConnectionProfileIds.CATEGORY_LDAP_CONNECTION, this); Composite pnlMain = WidgetFactory.createPanel(theParent, SWT.NONE, GridData.FILL_BOTH); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(pnlMain); setControl(pnlMain); IWorkbenchHelpSystem helpSystem = UiUtil.getWorkbench().getHelpSystem(); helpSystem.setHelp(pnlMain, LDAP_SELECTION_PAGE); createSourceSelectionComposite(pnlMain); // Set the initial page status setPageStatus(); } /** * Constructs the source LDAP selection component panel. * * @param theParent * the parent container */ private void createSourceSelectionComposite(Composite theParent) { Composite pnl = WidgetFactory.createPanel(theParent, SWT.FILL, GridData.FILL_HORIZONTAL); GridLayoutFactory.fillDefaults().applyTo(pnl); // ================================================================================ Group profileGroup = WidgetFactory.createGroup(pnl, getString("profileLabel_text"), SWT.NONE, 2); //$NON-NLS-1$ GridLayoutFactory.fillDefaults().numColumns(3).margins(10, 5).applyTo(profileGroup); LdapPageUtils.setBackground(profileGroup, pnl); GridDataFactory.fillDefaults().grab(true, false).applyTo(profileGroup); profileLabelProvider = new LabelProvider() { @Override public String getText(final Object source) { return ((IConnectionProfile)source).getName(); } }; this.connectionProfilesCombo = WidgetFactory.createCombo(profileGroup, SWT.READ_ONLY, GridData.FILL_HORIZONTAL, profileWorker.getProfiles(), profileLabelProvider, true); LdapPageUtils.blueForeground(this.connectionProfilesCombo); this.connectionProfilesCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // Need to sync the worker with the current profile handleConnectionProfileSelected(); } }); connectionProfilesCombo.setVisibleItemCount(10); newCPButton = WidgetFactory.createButton(profileGroup, getString("new_label")); //$NON-NLS-1$ newCPButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent event) { profileWorker.create(); } }); editCPButton = WidgetFactory.createButton(profileGroup, getString("edit_label")); //$NON-NLS-1$ editCPButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent event) { profileWorker.edit(); } }); // options group Group ldapURIGroup = WidgetFactory.createGroup(pnl, getString("ldapLabel_title"), SWT.FILL, 2); //$NON-NLS-1$ GridLayoutFactory.fillDefaults().numColumns(3).margins(10, 5).applyTo(ldapURIGroup); GridDataFactory.fillDefaults().grab(true, false).applyTo(ldapURIGroup); LdapPageUtils.setBackground(ldapURIGroup, pnl); Label ldapURILabel = new Label(ldapURIGroup, SWT.NONE); ldapURILabel.setText(getString("ldapLabel_text")); //$NON-NLS-1$ LdapPageUtils.setBackground(ldapURILabel, pnl); GridDataFactory.fillDefaults().grab(false, false).align(SWT.BEGINNING, SWT.CENTER).applyTo(ldapURILabel); // LDAP URI used for information only. Extracted from the connection profile ldapURIText = new Text(ldapURIGroup, SWT.BORDER | SWT.SINGLE); ldapURIText.setToolTipText(getString("ldapURITextField_tooltip")); //$NON-NLS-1$ LdapPageUtils.blueForeground(ldapURIText); ldapURIText.setEditable(false); GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(ldapURIText); Label dnLabel = new Label(ldapURIGroup, SWT.NONE); dnLabel.setText(getString("dnLabel_text")); //$NON-NLS-1$ LdapPageUtils.setBackground(dnLabel, pnl); GridDataFactory.fillDefaults().grab(false, false).align(SWT.BEGINNING, SWT.CENTER).applyTo(dnLabel); baseDNCombo = new Combo(ldapURIGroup, SWT.DROP_DOWN); baseDNCombo.setToolTipText(getString("dnTextField_tooltip")); //$NON-NLS-1$ GridDataFactory.fillDefaults().grab(true, false).applyTo(baseDNCombo); baseDNCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IConnectionProfile profile = importManager.getConnectionProfile(); Properties properties = profile.getBaseProperties(); properties.setProperty(ILdapProfileConstants.BASE_DN, baseDNCombo.getText()); importManager.resetBrowserConnection(); } }); fetchBaseDnsButton = new Button(ldapURIGroup, SWT.PUSH); fetchBaseDnsButton.setEnabled(false); fetchBaseDnsButton.setText(getString("fetchBaseDNs" ) ); //$NON-NLS-1$ GridDataFactory.fillDefaults().applyTo(fetchBaseDnsButton); fetchBaseDnsButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IBrowserConnection browserConnection = importManager.getBrowserConnection(); if (browserConnection == null) return; FetchBaseDNsRunnable runnable = new FetchBaseDNsRunnable(browserConnection); IStatus status = RunnableContextRunner.execute(runnable, getContainer(), true); if (status.isOK()) { if (!runnable.getBaseDNs().isEmpty()) { List<String> baseDNs = runnable.getBaseDNs(); baseDNCombo.setItems(baseDNs.toArray(new String[baseDNs .size()])); baseDNCombo.select(0); } else { MessageDialog.openWarning(Display.getDefault() .getActiveShell(), getString("fetchBaseDNs"), //$NON-NLS-1$ getString("noBaseDNReturnedFromServer")); //$NON-NLS-1$ baseDNCombo.setItems(new String[0]); } } } }); // Defines Location and Name values for source model sourceModelPanel = new SourceModelPanel(pnl, this.importManager); } private void handleConnectionProfileSelected() { if (isSynchronising()) return; int selIndex = connectionProfilesCombo.getSelectionIndex(); if (selIndex >= 0) { String name = connectionProfilesCombo.getItem(selIndex); if (name != null) { IConnectionProfile profile = profileWorker.getProfile(name); profileWorker.setSelection(profile); setConnectionProfileInternal(profile); } } notifyChanged(); } /** * @see org.eclipse.jface.dialogs.IDialogPage#dispose() */ @Override public void dispose() { saveState(); } /** * Override to replace the ImportWizard settings with the section devoted to * the LDAP import Wizard. * * @see org.eclipse.jface.wizard.WizardPage#getDialogSettings() */ @Override protected IDialogSettings getDialogSettings() { IDialogSettings settings = super.getDialogSettings(); if (settings != null) { // get the right section of the NewModelWizard settings IDialogSettings temp = settings.getSection(DIALOG_SETTINGS_SECTION); if (temp == null) { settings = settings.addNewSection(DIALOG_SETTINGS_SECTION); } else { settings = temp; } } return settings; } /** * Determines if the supplied string is a valid formatted URI * * @param str * the supplied uri string * @return 'true' if the string is a valid format, 'false' if not. */ public boolean isValidUri(String str) { try { new org.apache.xerces.util.URI(str); } catch (org.apache.xerces.util.URI.MalformedURIException e) { return false; } return true; } /** * Persists dialog size and position. */ private void saveState() { IDialogSettings settings = getDialogSettings(); if (settings != null && getContainer() != null) { Shell shell = getContainer().getShell(); if (shell != null) { Rectangle r = shell.getBounds(); settings.put(DIALOG_X, r.x); settings.put(DIALOG_Y, r.y); settings.put(DIALOG_WIDTH, r.width); settings.put(DIALOG_HEIGHT, r.height); } } } /** * Refresh the ui state from the manager */ private void refreshUiFromManager() { synchronising = true; try { if (this.importManager == null) return; if (connectionProfilesCombo.getItems() == null || connectionProfilesCombo.getItems().length == 0) { if (profileWorker.getProfiles().isEmpty()) { setErrorMessage(getString("no_profiles_configured")); //$NON-NLS-1$ ldapURIText.setText(EMPTY_STR); baseDNCombo.setText(EMPTY_STR); return; } setErrorMessage(null); setMessage(getString("select_profile")); //$NON-NLS-1$ return; } if (connectionProfilesCombo.getSelectionIndex() < 0) return; String profileName = connectionProfilesCombo.getText(); IConnectionProfile profile = profileWorker.getProfile(profileName); if (profile == null) { // this should really never happen setMessage(null); setErrorMessage(getString("no_profile_match", profileName)); //$NON-NLS-1$ return; } Properties props = profile.getBaseProperties(); ldapURIText.setText(props.getProperty(ILdapProfileConstants.URL_PROP_ID)); setErrorMessage(null); setMessage(getString("select_profile")); //$NON-NLS-1$ } finally { synchronising = false; } } @Override public void profileChanged(IConnectionProfile profile) { resetCPComboItems(); selectConnectionProfile(profile.getName()); setConnectionProfileInternal(profile); notifyChanged(); } /** * Performs validation and sets the page status. */ private void setPageStatus() { IConnectionProfile connectionProfile = this.importManager.getConnectionProfile(); if (connectionProfile == null) { WizardUtil.setPageComplete(this, getString("no_profile_selected"), IMessageProvider.ERROR); //$NON-NLS-1$ return; } /* * Time-consuming check and only relevant to this page. * * Other pages will call this method through notifyChanged() but it is pointless to keep testing * the connection profile since this is the only page it is set from */ if (this.isCurrentPage()) { IStatus status = null; try { status = connectionProfile.connectWithoutJob(); if (! status.isOK()) { WizardUtil.setPageComplete(this, getString("no_connection_made"), IMessageProvider.ERROR); //$NON-NLS-1$ return; } } finally { if (status != null && status.isOK()) { /* * This has the potential to deadlock the UI due to disconnect * creating a job itself that joins to the JobManager. By putting * this inside its own job, at least it locks up the worker thread * rather than the UI thread. */ Job job = new Job("Disconnect connection profile") { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { IConnectionProfile connProfile = importManager.getConnectionProfile(); if (connProfile != null) connProfile.disconnect(); return Status.OK_STATUS; } }; job.setSystem(true); job.setUser(false); job.schedule(); } } } if( this.importManager.getSourceModelLocation() == null ) { WizardUtil.setPageComplete(this, getString("statusSourceModelLocationUndefined"), IMessageProvider.ERROR); //$NON-NLS-1$ return; } if (this.importManager.getSourceModelName() == null || this.importManager.getSourceModelName().length() == 0) { WizardUtil.setPageComplete(this, getString("statusSourceModelNameCannotBeNullOrEmpty"), IMessageProvider.ERROR); //$NON-NLS-1$ return; } else { IStatus status = ModelNameUtil.validate(this.importManager.getSourceModelName(), ModelerCore.MODEL_FILE_EXTENSION, null, ModelNameUtil.IGNORE_CASE ); if( status.getSeverity() == IStatus.ERROR ) { WizardUtil.setPageComplete(this, ModelNameUtil.MESSAGES.INVALID_MODEL_NAME + status.getMessage(), ERROR); return ; } } if (sourceModelPanel.sourceModelExists()) { if (!sourceModelPanel.sourceModelHasConnectionProfile()) { WizardUtil.setPageComplete(this, getString("statusExistingSourceModelHasNoProfile", importManager.getSourceModelName()), IMessageProvider.ERROR); //$NON-NLS-1$ return; } else if (!sourceModelPanel.sourceModelHasSameConnectionProfile()) { WizardUtil.setPageComplete(this, getString("statusExistingSourceModelHasWrongProfile", importManager.getSourceModelName()), IMessageProvider.ERROR); //$NON-NLS-1$ return; } } else { WizardUtil.setPageComplete(this, getString("statusSourceModelDoesNotExistAndWillBeCreated", importManager.getSourceModelName()), IMessageProvider.INFORMATION); //$NON-NLS-1$ return; } WizardUtil.setPageComplete(this); } void resetCPComboItems() { if (connectionProfilesCombo != null) { ArrayList profileList = new ArrayList(); for (IConnectionProfile prof : profileWorker.getProfiles()) { profileList.add(prof); } WidgetUtil.setComboItems(connectionProfilesCombo, profileList, profileLabelProvider, true); } } /** * Select the connection profile with the given name * * @param name * @return true if successfully selected */ public boolean selectConnectionProfile(String name) { if (name == null) { return false; } int cpIndex = -1; int i = 0; for (String item : connectionProfilesCombo.getItems()) { if (item != null && item.length() > 0) { if (item.toUpperCase().equalsIgnoreCase(name.toUpperCase())) { cpIndex = i; break; } } i++; } boolean profileChanged = false; if (cpIndex > -1) { connectionProfilesCombo.select(cpIndex); IConnectionProfile profile = profileWorker.getProfile(connectionProfilesCombo.getText()); this.profileWorker.setSelection(profile); IConnectionProfile currentProfile = this.importManager.getConnectionProfile(); if (profile != currentProfile) { profileChanged = true; setConnectionProfileInternal(profile); } } return profileChanged; } private void setConnectionProfileInternal(final IConnectionProfile profile) { this.importManager.setConnectionProfile(profile); this.fetchBaseDnsButton.setEnabled(importManager.getConnectionProfile() != null); } @Override public void setVisible(boolean visible) { super.setVisible(visible); if (! visible) return; if (this.importManager.getConnectionProfile() == null) return; boolean profileChanged = false; if (this.connectionProfilesCombo.getItemCount() > 0) { if (this.connectionProfilesCombo.getText() != null && this.connectionProfilesCombo.getText().equals(this.importManager.getConnectionProfile().getName())) { profileChanged = selectConnectionProfile(this.importManager.getConnectionProfile().getName()); } } else { if (this.connectionProfilesCombo.getSelectionIndex() < 0) { this.connectionProfilesCombo.select(0); profileChanged = true; } } refreshUiFromManager(); if (profileChanged) { handleConnectionProfileSelected(); } if (sourceModelPanel != null) { sourceModelPanel.refresh(); } setPageStatus(); } @Override public void stateChanged(IChangeNotifier theSource) { setPageStatus(); } private void notifyChanged() { refreshUiFromManager(); this.importManager.notifyChanged(); } }