Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.apache.directory.studio.ldapbrowser.common.wizards; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import org.apache.commons.lang.ArrayUtils; import org.apache.directory.api.ldap.model.constants.SchemaConstants; import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; import org.apache.directory.api.ldap.model.name.Ava; import org.apache.directory.api.ldap.model.name.Dn; import org.apache.directory.api.ldap.model.name.Rdn; import org.apache.directory.api.ldap.model.schema.AttributeType; import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils; import org.apache.directory.studio.common.ui.widgets.WidgetModifyEvent; import org.apache.directory.studio.common.ui.widgets.WidgetModifyListener; import org.apache.directory.studio.connection.ui.RunnableContextRunner; import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator; import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants; import org.apache.directory.studio.ldapbrowser.common.widgets.DnBuilderWidget; import org.apache.directory.studio.ldapbrowser.common.widgets.ListContentProposalProvider; import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry; import org.apache.directory.studio.ldapbrowser.core.jobs.ReadEntryRunnable; import org.apache.directory.studio.ldapbrowser.core.model.IAttribute; import org.apache.directory.studio.ldapbrowser.core.model.IEntry; import org.apache.directory.studio.ldapbrowser.core.model.IValue; import org.apache.directory.studio.ldapbrowser.core.model.impl.Attribute; import org.apache.directory.studio.ldapbrowser.core.model.impl.DummyEntry; import org.apache.directory.studio.ldapbrowser.core.model.impl.Value; import org.apache.directory.studio.ldapbrowser.core.model.schema.SchemaUtils; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.fieldassist.ComboContentAdapter; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; /** * The NewEntryDnWizardPage is used to compose the new entry's * distinguished name. * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public class NewEntryDnWizardPage extends WizardPage implements WidgetModifyListener { /** The wizard. */ private NewEntryWizard wizard; /** The Dn builder widget. */ private DnBuilderWidget dnBuilderWidget; /** The context entry Dn combo. */ private Combo contextEntryDnCombo; /** The content proposal adapter for the context entry Dn combo. */ private ContentProposalAdapter contextEntryDnComboCPA; /** * Creates a new instance of NewEntryDnWizardPage. * * @param pageName the page name * @param wizard the wizard */ public NewEntryDnWizardPage(String pageName, NewEntryWizard wizard) { super(pageName); setTitle(Messages.getString("NewEntryDnWizardPage.DistinguishedName")); //$NON-NLS-1$ if (wizard.isNewContextEntry()) { setDescription(Messages.getString("NewEntryDnWizardPage.EnterDN")); //$NON-NLS-1$ } else { setDescription(Messages.getString("NewEntryDnWizardPage.SelectParent")); //$NON-NLS-1$ } setImageDescriptor( BrowserCommonActivator.getDefault().getImageDescriptor(BrowserCommonConstants.IMG_ENTRY_WIZARD)); setPageComplete(false); this.wizard = wizard; } /** * {@inheritDoc} */ public void dispose() { if (dnBuilderWidget != null) { dnBuilderWidget.removeWidgetModifyListener(this); dnBuilderWidget.dispose(); dnBuilderWidget = null; } super.dispose(); } /** * Validates the input fields. */ private void validate() { if (wizard.isNewContextEntry() && !"".equals(contextEntryDnCombo.getText()) //$NON-NLS-1$ && Dn.isValid(contextEntryDnCombo.getText())) { setPageComplete(true); saveState(); } else if (!wizard.isNewContextEntry() && dnBuilderWidget.getRdn() != null && dnBuilderWidget.getParentDn() != null) { setPageComplete(true); saveState(); } else { setPageComplete(false); } } /** * Initializes the Dn builder widget with the Dn of * the prototype entry. Called when this page becomes visible. */ private void loadState() { DummyEntry newEntry = wizard.getPrototypeEntry(); if (wizard.isNewContextEntry()) { IAttribute attribute = wizard.getSelectedConnection().getRootDSE() .getAttribute(SchemaConstants.NAMING_CONTEXTS_AT); if (attribute != null) { String[] values = attribute.getStringValues(); // content proposals contextEntryDnComboCPA.setContentProposalProvider(new ListContentProposalProvider(values)); // fill namingContext values into combo contextEntryDnCombo.setItems(values); // preset combo text if (Arrays.asList(values).contains(newEntry.getDn().getName())) { contextEntryDnCombo.setText(newEntry.getDn().getName()); } } } else { Collection<AttributeType> atds = SchemaUtils.getAllAttributeTypeDescriptions(newEntry); String[] attributeNames = SchemaUtils.getNames(atds).toArray(ArrayUtils.EMPTY_STRING_ARRAY); Dn parentDn = null; boolean hasSelectedEntry = wizard.getSelectedEntry() != null; boolean newEntryParentDnNotNullOrEmpty = !Dn.isNullOrEmpty(newEntry.getDn().getParent()); if (hasSelectedEntry) { boolean newEntryDnEqualsSelectedEntryDn = newEntry.getDn() .equals(wizard.getSelectedEntry().getDn()); if (newEntryDnEqualsSelectedEntryDn && newEntryParentDnNotNullOrEmpty) { parentDn = newEntry.getDn().getParent(); } else { parentDn = wizard.getSelectedEntry().getDn(); } } else if (newEntryParentDnNotNullOrEmpty) { parentDn = newEntry.getDn().getParent(); } Rdn rdn = newEntry.getRdn(); dnBuilderWidget.setInput(wizard.getSelectedConnection(), attributeNames, rdn, parentDn); } } /** * Saves the Dn of the Dn builder widget to the prototype entry. */ private void saveState() { DummyEntry newEntry = wizard.getPrototypeEntry(); try { EventRegistry.suspendEventFiringInCurrentThread(); // remove old Rdn if (newEntry.getRdn().size() > 0) { Iterator<Ava> atavIterator = newEntry.getRdn().iterator(); while (atavIterator.hasNext()) { Ava atav = atavIterator.next(); IAttribute attribute = newEntry.getAttribute(atav.getType()); if (attribute != null) { IValue[] values = attribute.getValues(); for (int v = 0; v < values.length; v++) { if (values[v].getStringValue().equals(atav.getValue().getNormalized())) { attribute.deleteValue(values[v]); } } // If we have removed all the values of the attribute, // then we also need to remove this attribute from the // entry. // This test has been added to fix DIRSTUDIO-222 if (attribute.getValueSize() == 0) { newEntry.deleteAttribute(attribute); } } } } // set new Dn Dn dn; if (wizard.isNewContextEntry()) { try { dn = new Dn(contextEntryDnCombo.getText()); } catch (LdapInvalidDnException e) { dn = Dn.EMPTY_DN; } } else { try { dn = dnBuilderWidget.getParentDn().add(dnBuilderWidget.getRdn()); } catch (LdapInvalidDnException lide) { // Do nothing dn = Dn.EMPTY_DN; } } newEntry.setDn(dn); // add new Rdn if (dn.getRdn().size() > 0) { Iterator<Ava> atavIterator = dn.getRdn().iterator(); while (atavIterator.hasNext()) { Ava atav = atavIterator.next(); IAttribute rdnAttribute = newEntry.getAttribute(atav.getType()); if (rdnAttribute == null) { rdnAttribute = new Attribute(newEntry, atav.getType()); newEntry.addAttribute(rdnAttribute); } Object rdnValue = atav.getValue().getNormalized(); String[] stringValues = rdnAttribute.getStringValues(); if (!Arrays.asList(stringValues).contains(rdnValue)) { rdnAttribute.addValue(new Value(rdnAttribute, rdnValue)); } } } } finally { EventRegistry.resumeEventFiringInCurrentThread(); } } /** * {@inheritDoc} * * This implementation initializes Dn builder widghet with the * Dn of the protoype entry. */ public void setVisible(boolean visible) { super.setVisible(visible); if (visible) { loadState(); validate(); if (wizard.isNewContextEntry()) { contextEntryDnCombo.setFocus(); } } } /** * {@inheritDoc} * * This implementation just checks if this page is complete. It * doesn't call {@link #getNextPage()} to avoid unneeded * invokings of {@link ReadEntryRunnable}s. */ @Override public boolean canFlipToNextPage() { return isPageComplete(); } /** * {@inheritDoc} * * This implementation invokes a {@link ReadEntryRunnable} to check if an * entry with the composed Dn already exists. */ @Override public IWizardPage getNextPage() { if (!wizard.isNewContextEntry()) { dnBuilderWidget.validate(); Rdn rdn = dnBuilderWidget.getRdn(); Dn parentDn = dnBuilderWidget.getParentDn(); try { final Dn dn = parentDn.add(rdn); // check if parent exists ReadEntryRunnable readEntryRunnable1 = new ReadEntryRunnable(wizard.getSelectedConnection(), parentDn); RunnableContextRunner.execute(readEntryRunnable1, getContainer(), false); IEntry parentEntry = readEntryRunnable1.getReadEntry(); if (parentEntry == null) { getShell().getDisplay().syncExec(() -> { MessageDialog.openError(getShell(), Messages.getString("NewEntryDnWizardPage.Error"), //$NON-NLS-1$ NLS.bind(Messages.getString("NewEntryDnWizardPage.ParentDoesNotExist"), //$NON-NLS-1$ dnBuilderWidget.getParentDn().toString())); }); return null; } // check that new entry does not exists yet ReadEntryRunnable readEntryRunnable2 = new ReadEntryRunnable(wizard.getSelectedConnection(), dn); RunnableContextRunner.execute(readEntryRunnable2, getContainer(), false); IEntry entry = readEntryRunnable2.getReadEntry(); if (entry != null) { getShell().getDisplay().syncExec(() -> { MessageDialog.openError(getShell(), Messages.getString("NewEntryDnWizardPage.Error"), //$NON-NLS-1$ NLS.bind(Messages.getString("NewEntryDnWizardPage.EntryAlreadyExists"), //$NON-NLS-1$ dn.toString())); }); return null; } } catch (LdapInvalidDnException lide) { return null; } } else { try { final Dn dn = new Dn(contextEntryDnCombo.getText()); // check that new entry does not exists yet ReadEntryRunnable readEntryRunnable2 = new ReadEntryRunnable(wizard.getSelectedConnection(), dn); RunnableContextRunner.execute(readEntryRunnable2, getContainer(), false); IEntry entry = readEntryRunnable2.getReadEntry(); if (entry != null) { getShell().getDisplay().syncExec(() -> { MessageDialog.openError(getShell(), Messages.getString("NewEntryDnWizardPage.Error"), //$NON-NLS-1$ NLS.bind(Messages.getString("NewEntryDnWizardPage.EntryAlreadyExists"), //$NON-NLS-1$ dn.toString())); }); return null; } } catch (LdapInvalidDnException e) { return null; } } return super.getNextPage(); } /** * {@inheritDoc} */ public void createControl(Composite parent) { if (wizard.isNewContextEntry()) { // the combo Composite composite = BaseWidgetUtils.createColumnContainer(parent, 1, 1); contextEntryDnCombo = BaseWidgetUtils.createCombo(composite, ArrayUtils.EMPTY_STRING_ARRAY, 0, 1); contextEntryDnCombo.addModifyListener(event -> validate()); // attach content proposal behavior contextEntryDnComboCPA = new ContentProposalAdapter(contextEntryDnCombo, new ComboContentAdapter(), null, null, null); contextEntryDnComboCPA.setFilterStyle(ContentProposalAdapter.FILTER_NONE); contextEntryDnComboCPA.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); setControl(composite); } else { dnBuilderWidget = new DnBuilderWidget(true, true); dnBuilderWidget.addWidgetModifyListener(this); Composite composite = dnBuilderWidget.createContents(parent); setControl(composite); } } /** * {@inheritDoc} */ public void widgetModified(WidgetModifyEvent event) { validate(); } /** * Saves the dialogs settings. */ public void saveDialogSettings() { if (!wizard.isNewContextEntry()) { dnBuilderWidget.saveDialogSettings(); } } }