package org.nightlabs.jfire.auth.ui.ldap.editor; import java.lang.reflect.InvocationTargetException; import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; 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.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.forms.editor.IFormPage; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.statushandlers.StatusManager; import org.nightlabs.base.ui.composite.XComposite; import org.nightlabs.base.ui.editor.ToolBarSectionPart; import org.nightlabs.base.ui.entity.editor.EntityEditorUtil; import org.nightlabs.base.ui.form.NightlabsFormsToolkit; import org.nightlabs.base.ui.progress.ProgressMonitorWrapper; import org.nightlabs.base.ui.util.RCPUtil; import org.nightlabs.jfire.auth.ui.ldap.LdapUIPlugin; import org.nightlabs.jfire.auth.ui.ldap.editor.LDAPScriptSetHelper.NamedScript; import org.nightlabs.jfire.auth.ui.ldap.resource.Messages; import org.nightlabs.jfire.base.security.integration.ldap.LDAPScriptSet; import org.nightlabs.jfire.base.security.integration.ldap.LDAPScriptSetDAO; import org.nightlabs.jfire.base.security.integration.ldap.LDAPServer; import org.nightlabs.jfire.base.security.integration.ldap.scripts.ILDAPScriptProvider; import org.nightlabs.jseditor.ui.IJSEditor; import org.nightlabs.jseditor.ui.JSEditorFactory; /** * Section of {@link LDAPServerEditorScriptSetPage} for editing scripts in {@link LDAPServer}'s {@link LDAPScriptSet}. * * @author Denis Dudnik <deniska.dudnik[at]gmail{dot}com> * */ public class LDAPServerScriptSetSection extends ToolBarSectionPart { private LDAPServerScriptSetModel ldapScriptSetModel; private Label scriptDescriptionLabel; private CTabItem prevSelectedItem; private CTabFolder scriptsTabFolder; private XComposite jsEditorComposite; private IJSEditor jsEditor; // private JSEditorComposite jsEditorComposite; Map<String, NamedScript> namedScriptsLocal; /** * Set to <code>true</code> while automatic refreshing of UI elements * happens. Some listeners are enabled at this time. */ private boolean refreshing = false; private ScriptKeyListener scriptDirtyKeyListener = new ScriptKeyListener(); /** * When {@link LDAPScriptSet} is loaded and model is created we set initial selection to tab folder based on this index. */ private int selectItemWhenLoaded = 0; public LDAPServerScriptSetSection(IFormPage page, Composite parent) { super(page, parent, ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE, Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.sectionTitle")); //$NON-NLS-1$ createContents(getSection(), page.getEditor().getToolkit()); } /** * {@inheritDoc} */ @Override public boolean setFormInput(Object input) { if (!(input instanceof LDAPScriptSet)){ throw new IllegalArgumentException(Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.illegalFormInputExceptionText")); //$NON-NLS-1$ } this.ldapScriptSetModel = new LDAPServerScriptSetModel((LDAPScriptSet) input); return super.setFormInput(input); } /** * {@inheritDoc} */ @Override public void commit(boolean onSave) { if (ldapScriptSetModel != null && namedScriptsLocal != null && !namedScriptsLocal.isEmpty()){ if (scriptsTabFolder != null && !scriptsTabFolder.isDisposed()){ commitScriptTab(scriptsTabFolder.getSelection()); } ldapScriptSetModel.commitScriptContent(namedScriptsLocal); } super.commit(onSave); } /** * {@inheritDoc} */ @Override public void refresh() { refreshing = true; try{ if (ldapScriptSetModel != null){ initScriptTabs(); if (scriptsTabFolder.getSelection() == null){ scriptsTabFolder.setSelection(selectItemWhenLoaded); Event e = new Event(); e.widget = scriptsTabFolder.getSelection(); SelectionEvent selectionEvent = new SelectionEvent(e); scriptSelectionListener.widgetSelected(selectionEvent); } } }finally{ refreshing = false; } super.refresh(); } /** * Sets active tab (or tab index if model is not yet loaded) in a tab folder based on given script ID. * This script ID should be one of the constants defined in {@link ILDAPScriptProvider}. * * @param scriptID */ public void setActiveScriptTab(String scriptID){ if (scriptID == null || scriptID.isEmpty() || scriptsTabFolder == null || scriptsTabFolder.isDisposed()){ return; } if (scriptsTabFolder.getItemCount() == 0){ selectItemWhenLoaded = LDAPScriptSetHelper.getScriptIndexByID(scriptID); }else{ for (CTabItem tabItem : scriptsTabFolder.getItems()){ NamedScript namedScript = (NamedScript) tabItem.getData(); if (scriptID.equals(namedScript.getScriptID())){ scriptsTabFolder.setSelection(tabItem); Event e = new Event(); e.widget = tabItem; SelectionEvent selectionEvent = new SelectionEvent(e); scriptSelectionListener.widgetSelected(selectionEvent); } } } } private void createContents(Section section, FormToolkit toolkit){ section.setExpanded(true); section.setLayout(new GridLayout()); section.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite parent = EntityEditorUtil.createCompositeClient(toolkit, section, 2); GridLayout gLayout = (GridLayout) parent.getLayout(); gLayout.verticalSpacing = 10; final ExpandableComposite descriptionExpandable = toolkit.createExpandableComposite( parent, ExpandableComposite.CLIENT_INDENT | ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE ); gLayout = new GridLayout(1, false); gLayout.marginWidth = 0; gLayout.marginHeight = 0; descriptionExpandable.setLayout(gLayout); GridData gd = new GridData(); gd.verticalIndent = 15; gd.widthHint = 800; descriptionExpandable.setLayoutData(gd); descriptionExpandable.setExpanded(false); descriptionExpandable.setText(Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.showDescriptionExpanableLabel")); //$NON-NLS-1$ scriptDescriptionLabel = toolkit.createLabel(descriptionExpandable, "", SWT.WRAP); //$NON-NLS-1$ descriptionExpandable.setClient(scriptDescriptionLabel); descriptionExpandable.addExpansionListener(new ExpansionAdapter(){ @Override public void expansionStateChanged(ExpansionEvent e) { GridData gd = new GridData(); gd.verticalIndent = 15; gd.widthHint = 800; if (e.getState()){ gd.minimumHeight = 90; gd.heightHint = 90; descriptionExpandable.setText(Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.hideDescriptionExpanableLabel")); //$NON-NLS-1$ }else{ descriptionExpandable.setText(Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.showDescriptionExpanableLabel")); //$NON-NLS-1$ } descriptionExpandable.setLayoutData(gd); ((Control) e.getSource()).getParent().layout(); } }); Button resetScriptButton = toolkit.createButton(parent, Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.resetScriptButtonText"), SWT.NONE); //$NON-NLS-1$ resetScriptButton.setToolTipText(Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.resetScriptButtonTooltip")); //$NON-NLS-1$ resetScriptButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); resetScriptButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { if (MessageDialog.openConfirm(RCPUtil.getActiveShell(), Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.resetScriptConfirmTitle"), //$NON-NLS-1$ Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.resetScriptConfirmMessage"))){ //$NON-NLS-1$ CTabItem selectedItem = scriptsTabFolder.getSelection(); final String scriptID = ((NamedScript) selectedItem.getData()).getScriptID(); ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(RCPUtil.getActiveShell()); try { progressDialog.run(true, false, new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { final String inititalContent = LDAPScriptSetDAO.sharedInstance().getInitialScriptContent( ldapScriptSetModel.getLDAPScriptSetID(), scriptID, new ProgressMonitorWrapper(monitor)); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (inititalContent != null){ jsEditor.setDocumentText(inititalContent); markDirty(); }else{ StatusManager.getManager().handle( new Status( Status.ERROR, LdapUIPlugin.PLUGIN_ID, Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.scriptContentisNullErrorMessage")), //$NON-NLS-1$ StatusManager.SHOW); } } }); } }); } catch (Exception e) { StatusManager.getManager().handle( new Status( Status.ERROR, LdapUIPlugin.PLUGIN_ID, Messages.getString("org.nightlabs.jfire.auth.ui.ldap.editor.LDAPServerScriptSetSection.exceptionGettingScriptMessage"), e), //$NON-NLS-1$ StatusManager.SHOW); } } } }); scriptsTabFolder = new CTabFolder(parent, SWT.TOP); gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; scriptsTabFolder.setLayoutData(gd); scriptsTabFolder.addSelectionListener(scriptSelectionListener); jsEditorComposite = new XComposite(scriptsTabFolder, SWT.NONE); jsEditorComposite.setLayout(new GridLayout(1, false)); jsEditorComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); jsEditorComposite.setToolkit(new NightlabsFormsToolkit(toolkit.getColors())); jsEditorComposite.adaptToToolkit(); jsEditor = JSEditorFactory.createJSEditor(jsEditorComposite); jsEditor.addKeyListener(scriptDirtyKeyListener); } private void initScriptTabs(){ int i = 0; boolean itemsExist = scriptsTabFolder.getItemCount() > 0; namedScriptsLocal = new LinkedHashMap<String, LDAPScriptSetHelper.NamedScript>(); for (NamedScript namedScript : LDAPScriptSetHelper.getNamedScripts()){ NamedScript localNamedScript = namedScript.clone(); String scriptIDLocal = localNamedScript.getScriptID(); localNamedScript.setScriptContent(new String(ldapScriptSetModel.getScriptContentById(scriptIDLocal))); CTabItem tabItem = null; if (itemsExist){ tabItem = scriptsTabFolder.getItem(i); }else{ tabItem = new CTabItem(scriptsTabFolder, SWT.NONE); } tabItem.setText(localNamedScript.getScriptName()); tabItem.setData(localNamedScript); i++; namedScriptsLocal.put(scriptIDLocal, localNamedScript); } } private void commitScriptTab(CTabItem tabItem){ NamedScript namedScript = (NamedScript) tabItem.getData(); namedScript.setScriptContent(jsEditor.getDocumentText()); } private SelectionListener scriptSelectionListener = new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (prevSelectedItem != null){ commitScriptTab(prevSelectedItem); prevSelectedItem.setControl(null); } CTabItem selectedItem = scriptsTabFolder.getSelection(); NamedScript namedScript = (NamedScript) selectedItem.getData(); jsEditor.setDocumentText(namedScript.getScriptContent()); scriptDirtyKeyListener.setInitialValue(namedScript.getScriptContent()); scriptDescriptionLabel.setText(namedScript.getScriptDescription()); selectedItem.setControl(jsEditorComposite); prevSelectedItem = selectedItem; }; }; class ScriptKeyListener extends KeyAdapter{ private String previousValue; public void setInitialValue(String initialValue){ this.previousValue = initialValue; } @Override public void keyPressed(KeyEvent keyevent) { if (!refreshing && !jsEditor.getDocumentText().equals(previousValue)){ markDirty(); previousValue = jsEditor.getDocumentText(); } } } }