| | |
| | | |
| | | package org.opends.guitools.controlpanel.ui; |
| | | |
| | | import static org.opends.messages.AdminToolMessages.*; |
| | | import static org.opends.messages.QuickSetupMessages.*; |
| | | |
| | | import static com.forgerock.opendj.cli.Utils.*; |
| | | |
| | | import java.awt.Component; |
| | | import java.awt.GridBagConstraints; |
| | | import java.awt.GridBagLayout; |
| | |
| | | import java.util.Enumeration; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.util.ServerConstants; |
| | | |
| | | import static com.forgerock.opendj.cli.Utils.*; |
| | | |
| | | import static org.opends.messages.AdminToolMessages.*; |
| | | import static org.opends.messages.QuickSetupMessages.*; |
| | | |
| | | /** |
| | | * The abstract class used to refactor some code. The classes that extend this |
| | | * The abstract class used to refactor some code. The classes that extend this |
| | | * class are the 'Browse Entries' panel and the panel of the dialog we display |
| | | * when the user can choose a set of entries (for instance when the user adds |
| | | * a member to a group in the 'New Group' dialog). |
| | | * |
| | | * when the user can choose a set of entries (for instance when the user adds a |
| | | * member to a group in the 'New Group' dialog). |
| | | */ |
| | | public abstract class AbstractBrowseEntriesPanel extends StatusGenericPanel |
| | | implements BackendPopulatedListener |
| | | public abstract class AbstractBrowseEntriesPanel extends StatusGenericPanel implements BackendPopulatedListener |
| | | { |
| | | private static final long serialVersionUID = -6063927039968115236L; |
| | | private JComboBox baseDNs; |
| | | /** |
| | | * The combo box containing the different filter types. |
| | | */ |
| | | protected JComboBox filterAttribute; |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | /** |
| | | * The text field of the filter. |
| | | */ |
| | | /** LDAP filter message. */ |
| | | protected static final LocalizableMessage LDAP_FILTER = INFO_CTRL_PANEL_LDAP_FILTER.get(); |
| | | /** User filter message. */ |
| | | protected static final LocalizableMessage USER_FILTER = INFO_CTRL_PANEL_USERS_FILTER.get(); |
| | | /** Group filter message. */ |
| | | protected static final LocalizableMessage GROUP_FILTER = INFO_CTRL_PANEL_GROUPS_FILTER.get(); |
| | | private static final LocalizableMessage OTHER_BASE_DN = INFO_CTRL_PANEL_OTHER_BASE_DN.get(); |
| | | |
| | | private static final String ALL_BASE_DNS = "All Base DNs"; |
| | | private static final int MAX_NUMBER_ENTRIES = 5000; |
| | | private static final int MAX_NUMBER_OTHER_BASE_DNS = 10; |
| | | private static final String[] CONTAINER_CLASSES = { "organization", "organizationalUnit" }; |
| | | static final String[] SYSTEM_INDEXES = { "aci", "dn2id", "ds-sync-hist", "entryUUID", "id2children", "id2subtree" }; |
| | | |
| | | |
| | | private JComboBox<String> baseDNs; |
| | | |
| | | /** The combo box containing the different filter types. */ |
| | | protected JComboBox<?> filterAttribute; |
| | | /** The text field of the filter. */ |
| | | protected FilterTextField filter; |
| | | |
| | | private JButton applyButton; |
| | | |
| | | private JButton okButton; |
| | | private JButton cancelButton; |
| | | private JButton closeButton; |
| | |
| | | private JLabel lBaseDN; |
| | | private JLabel lFilter; |
| | | private JLabel lLimit; |
| | | |
| | | private JLabel lNumberOfEntries; |
| | | |
| | | private JLabel lNoMatchFound; |
| | | |
| | | private InitialLdapContext createdUserDataCtx; |
| | | |
| | | /** |
| | | * The tree pane contained in this panel. |
| | | */ |
| | | /** The tree pane contained in this panel. */ |
| | | protected TreePanel treePane; |
| | | |
| | | /** |
| | | * The browser controller used to update the LDAP entry tree. |
| | | */ |
| | | /** The browser controller used to update the LDAP entry tree. */ |
| | | protected BrowserController controller; |
| | | |
| | | private NumberOfEntriesUpdater numberEntriesUpdater; |
| | | |
| | | private BaseDNPanel otherBaseDNPanel; |
| | | private GenericDialog otherBaseDNDlg; |
| | | |
| | | private boolean firstTimeDisplayed = true; |
| | | private Object lastSelectedBaseDN; |
| | | private boolean ignoreBaseDNEvents; |
| | | |
| | | /** |
| | | * LDAP filter message. |
| | | */ |
| | | protected static final LocalizableMessage LDAP_FILTER = |
| | | INFO_CTRL_PANEL_LDAP_FILTER.get(); |
| | | |
| | | /** |
| | | * User filter message. |
| | | */ |
| | | protected static final LocalizableMessage USER_FILTER = |
| | | INFO_CTRL_PANEL_USERS_FILTER.get(); |
| | | |
| | | /** |
| | | * Group filter message. |
| | | */ |
| | | protected static final LocalizableMessage GROUP_FILTER = |
| | | INFO_CTRL_PANEL_GROUPS_FILTER.get(); |
| | | |
| | | private final LocalizableMessage OTHER_BASE_DN = |
| | | INFO_CTRL_PANEL_OTHER_BASE_DN.get(); |
| | | |
| | | private ArrayList<DN> otherBaseDns = new ArrayList<DN>(); |
| | | |
| | | private static final String ALL_BASE_DNS = "All Base DNs"; |
| | | |
| | | private static final int MAX_NUMBER_ENTRIES = 5000; |
| | | |
| | | private static final int MAX_NUMBER_OTHER_BASE_DNS = 10; |
| | | |
| | | private final String[] CONTAINER_CLASSES = { |
| | | "organization", |
| | | "organizationalUnit" |
| | | }; |
| | | |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | private List<DN> otherBaseDns = new ArrayList<>(); |
| | | |
| | | /** |
| | | * Default constructor. |
| | | * |
| | | */ |
| | | public AbstractBrowseEntriesPanel() |
| | | { |
| | |
| | | createLayout(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean requiresBorder() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean requiresScroll() |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean callConfigurationChangedInBackground() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void setInfo(ControlPanelInfo info) |
| | | { |
| | |
| | | info.addBackendPopulatedListener(this); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final GenericDialog.ButtonType getButtonType() |
| | | { |
| | |
| | | /** |
| | | * Since these panel has a special layout, we cannot use the layout of the |
| | | * GenericDialog and we return ButtonType.NO_BUTTON in the method |
| | | * getButtonType. We use this method to be able to add some progress |
| | | * getButtonType. We use this method to be able to add some progress |
| | | * information to the left of the buttons. |
| | | * |
| | | * @return the button type of the panel. |
| | | */ |
| | | protected abstract GenericDialog.ButtonType getBrowseButtonType(); |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void toBeDisplayed(boolean visible) |
| | | { |
| | |
| | | Window w = Utilities.getParentDialog(this); |
| | | if (w instanceof GenericDialog) |
| | | { |
| | | ((GenericDialog)w).getRootPane().setDefaultButton(null); |
| | | ((GenericDialog) w).getRootPane().setDefaultButton(null); |
| | | } |
| | | else if (w instanceof GenericFrame) |
| | | { |
| | | ((GenericFrame)w).getRootPane().setDefaultButton(null); |
| | | ((GenericFrame) w).getRootPane().setDefaultButton(null); |
| | | } |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | protected void setEnabledOK(boolean enable) |
| | | { |
| | | okButton.setEnabled(enable); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | protected void setEnabledCancel(boolean enable) |
| | | { |
| | | cancelButton.setEnabled(enable); |
| | | } |
| | | |
| | | /** |
| | | * Creates the layout of the panel (but the contents are not populated here). |
| | | * |
| | | */ |
| | | /** Creates the layout of the panel (but the contents are not populated here). */ |
| | | @SuppressWarnings("unchecked") |
| | | private void createLayout() |
| | | { |
| | | setBackground(ColorAndFontConstants.greyBackground); |
| | |
| | | mb.append("<br><br>"); |
| | | mb.append(getStartServerHTML()); |
| | | LocalizableMessage details = mb.toMessage(); |
| | | updateErrorPane(errorPane, title, ColorAndFontConstants.errorTitleFont, |
| | | details, |
| | | ColorAndFontConstants.defaultFont); |
| | | updateErrorPane(errorPane, title, ColorAndFontConstants.errorTitleFont, details, ColorAndFontConstants.defaultFont); |
| | | errorPane.setVisible(true); |
| | | errorPane.setFocusable(true); |
| | | |
| | | gbc.insets = new Insets(10, 10, 0, 10); |
| | | gbc.gridy ++; |
| | | gbc.gridy++; |
| | | gbc.gridwidth = 1; |
| | | gbc.weightx = 0; |
| | | gbc.fill = GridBagConstraints.NONE; |
| | |
| | | gbc.insets.left = 5; |
| | | baseDNs = Utilities.createComboBox(); |
| | | |
| | | DefaultComboBoxModel model = new DefaultComboBoxModel(); |
| | | DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(); |
| | | model.addElement("dc=dn to be displayed"); |
| | | baseDNs.setModel(model); |
| | | baseDNs.setRenderer(new CustomComboBoxCellRenderer(baseDNs)); |
| | | baseDNs.addItemListener(new ItemListener() |
| | | { |
| | | @SuppressWarnings("rawtypes") |
| | | @Override |
| | | public void itemStateChanged(ItemEvent ev) |
| | | { |
| | | if (ignoreBaseDNEvents || (ev.getStateChange() != ItemEvent.SELECTED)) |
| | | if (ignoreBaseDNEvents || ev.getStateChange() != ItemEvent.SELECTED) |
| | | { |
| | | return; |
| | | } |
| | |
| | | if (lastSelectedBaseDN == null) |
| | | { |
| | | // Look for the first element that is not a category |
| | | for (int i=0; i<baseDNs.getModel().getSize(); i++) |
| | | for (int i = 0; i < baseDNs.getModel().getSize(); i++) |
| | | { |
| | | Object item = baseDNs.getModel().getElementAt(i); |
| | | if (item instanceof CategorizedComboBoxElement |
| | | && !isCategory(item)) |
| | | if (item instanceof CategorizedComboBoxElement && !isCategory(item)) |
| | | { |
| | | lastSelectedBaseDN = item; |
| | | break; |
| | |
| | | if (otherBaseDNDlg == null) |
| | | { |
| | | otherBaseDNPanel = new BaseDNPanel(); |
| | | otherBaseDNDlg = new GenericDialog( |
| | | Utilities.getFrame(AbstractBrowseEntriesPanel.this), |
| | | otherBaseDNPanel); |
| | | otherBaseDNDlg = new GenericDialog(Utilities.getFrame(AbstractBrowseEntriesPanel.this), otherBaseDNPanel); |
| | | otherBaseDNDlg.setModal(true); |
| | | Utilities.centerGoldenMean(otherBaseDNDlg, |
| | | Utilities.getParentDialog(AbstractBrowseEntriesPanel.this)); |
| | | Utilities.centerGoldenMean(otherBaseDNDlg, Utilities.getParentDialog(AbstractBrowseEntriesPanel.this)); |
| | | } |
| | | otherBaseDNDlg.setVisible(true); |
| | | String newBaseDn = otherBaseDNPanel.getBaseDn(); |
| | | DefaultComboBoxModel model = (DefaultComboBoxModel)baseDNs.getModel(); |
| | | DefaultComboBoxModel model = (DefaultComboBoxModel) baseDNs.getModel(); |
| | | if (newBaseDn != null) |
| | | { |
| | | Object newElement = null; |
| | |
| | | try |
| | | { |
| | | DN dn = DN.valueOf(newBaseDn); |
| | | newElement = new CategorizedComboBoxElement( |
| | | Utilities.unescapeUtf8(dn.toString()), |
| | | CategorizedComboBoxElement.Type.REGULAR); |
| | | newElement = |
| | | new CategorizedComboBoxElement(Utilities.unescapeUtf8(dn.toString()), |
| | | CategorizedComboBoxElement.Type.REGULAR); |
| | | if (!otherBaseDns.contains(dn)) |
| | | { |
| | | otherBaseDns.add(0, dn); |
| | |
| | | if (otherBaseDns.size() > MAX_NUMBER_OTHER_BASE_DNS) |
| | | { |
| | | ignoreBaseDNEvents = true; |
| | | for (int i=otherBaseDns.size() - 1; |
| | | i >= MAX_NUMBER_OTHER_BASE_DNS; i--) |
| | | for (int i = otherBaseDns.size() - 1; i >= MAX_NUMBER_OTHER_BASE_DNS; i--) |
| | | { |
| | | DN dnToRemove = otherBaseDns.get(i); |
| | | otherBaseDns.remove(i); |
| | | Object elementToRemove = new CategorizedComboBoxElement( |
| | | Utilities.unescapeUtf8(dnToRemove.toString()), |
| | | CategorizedComboBoxElement.Type.REGULAR); |
| | | Object elementToRemove = |
| | | new CategorizedComboBoxElement(Utilities.unescapeUtf8(dnToRemove.toString()), |
| | | CategorizedComboBoxElement.Type.REGULAR); |
| | | model.removeElement(elementToRemove); |
| | | } |
| | | ignoreBaseDNEvents = false; |
| | |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | throw new RuntimeException("Unexpected error decoding dn "+ |
| | | newBaseDn, t); |
| | | throw new RuntimeException("Unexpected error decoding dn " + newBaseDn, t); |
| | | } |
| | | if (newElement != null) |
| | | { |
| | | model.setSelectedItem(newElement); |
| | | } |
| | | } |
| | | else |
| | | else if (lastSelectedBaseDN != null) |
| | | { |
| | | if (lastSelectedBaseDN != null) |
| | | { |
| | | ignoreBaseDNEvents = true; |
| | | model.setSelectedItem(lastSelectedBaseDN); |
| | | ignoreBaseDNEvents = false; |
| | | } |
| | | ignoreBaseDNEvents = true; |
| | | model.setSelectedItem(lastSelectedBaseDN); |
| | | ignoreBaseDNEvents = false; |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | add(baseDNs, gbc); |
| | | |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | gbc.fill = GridBagConstraints.VERTICAL; |
| | | gbc.insets.left = 10; |
| | | add(new JSeparator(SwingConstants.VERTICAL), gbc); |
| | | gbc.fill = GridBagConstraints.HORIZONTAL; |
| | | lFilter = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_FILTER_LABEL.get()); |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | add(lFilter, gbc); |
| | | |
| | | filterAttribute = Utilities.createComboBox(); |
| | | filterAttribute.setModel( |
| | | new DefaultComboBoxModel(new Object[]{ |
| | | USER_FILTER, |
| | | GROUP_FILTER, |
| | | COMBO_SEPARATOR, |
| | | "attributetobedisplayed", |
| | | COMBO_SEPARATOR, |
| | | LDAP_FILTER})); |
| | | filterAttribute.setModel(new DefaultComboBoxModel(new Object[] { |
| | | USER_FILTER, GROUP_FILTER, COMBO_SEPARATOR, "attributetobedisplayed", COMBO_SEPARATOR, LDAP_FILTER })); |
| | | filterAttribute.setRenderer(new CustomListCellRenderer(filterAttribute)); |
| | | filterAttribute.addItemListener(new IgnoreItemListener(filterAttribute)); |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | gbc.insets.left = 5; |
| | | add(filterAttribute, gbc); |
| | | |
| | | filter = new FilterTextField(); |
| | | filter.setToolTipText( |
| | | INFO_CTRL_PANEL_SUBSTRING_SEARCH_INLINE_HELP.get().toString()); |
| | | filter.setToolTipText(INFO_CTRL_PANEL_SUBSTRING_SEARCH_INLINE_HELP.get().toString()); |
| | | filter.addKeyListener(new KeyAdapter() |
| | | { |
| | | @Override |
| | | public void keyReleased(KeyEvent e) |
| | | { |
| | | if ((e.getKeyCode() == KeyEvent.VK_ENTER) && applyButton.isEnabled()) |
| | | if (e.getKeyCode() == KeyEvent.VK_ENTER && applyButton.isEnabled()) |
| | | { |
| | | filter.displayRefreshIcon(true); |
| | | applyButtonClicked(); |
| | |
| | | }); |
| | | |
| | | gbc.weightx = 1.0; |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | add(filter, gbc); |
| | | |
| | | gbc.insets.top = 10; |
| | | applyButton = |
| | | Utilities.createButton(INFO_CTRL_PANEL_APPLY_BUTTON_LABEL.get()); |
| | | applyButton = Utilities.createButton(INFO_CTRL_PANEL_APPLY_BUTTON_LABEL.get()); |
| | | gbc.insets.right = 10; |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | gbc.weightx = 0.0; |
| | | add(applyButton, gbc); |
| | | applyButton.addActionListener(new ActionListener() |
| | |
| | | }); |
| | | gbc.insets = new Insets(10, 0, 0, 0); |
| | | gbc.gridx = 0; |
| | | gbc.gridy ++; |
| | | gbc.gridy++; |
| | | gbc.weightx = 1.0; |
| | | gbc.weighty = 1.0; |
| | | gbc.fill = GridBagConstraints.BOTH; |
| | | gbc.gridwidth = 7; |
| | | add(createMainPanel(), gbc); |
| | | |
| | | // The button panel |
| | | gbc.gridy ++; |
| | | // The button panel |
| | | gbc.gridy++; |
| | | gbc.weighty = 0.0; |
| | | gbc.insets = new Insets(0, 0, 0, 0); |
| | | add(createButtonsPanel(), gbc); |
| | |
| | | |
| | | /** |
| | | * Returns the panel that contains the buttons of type OK, CANCEL, etc. |
| | | * |
| | | * @return the panel that contains the buttons of type OK, CANCEL, etc. |
| | | */ |
| | | private JPanel createButtonsPanel() |
| | |
| | | gbc.gridwidth = 1; |
| | | gbc.gridy = 0; |
| | | lLimit = Utilities.createDefaultLabel(); |
| | | Utilities.setWarningLabel(lLimit, |
| | | INFO_CTRL_PANEL_MAXIMUM_CHILDREN_DISPLAYED.get(MAX_NUMBER_ENTRIES)); |
| | | Utilities.setWarningLabel(lLimit, INFO_CTRL_PANEL_MAXIMUM_CHILDREN_DISPLAYED.get(MAX_NUMBER_ENTRIES)); |
| | | gbc.weighty = 0.0; |
| | | gbc.gridy ++; |
| | | gbc.gridy++; |
| | | lLimit.setVisible(false); |
| | | lNumberOfEntries = Utilities.createDefaultLabel(); |
| | | gbc.insets = new Insets(10, 10, 10, 10); |
| | | buttonsPanel.add(lNumberOfEntries, gbc); |
| | | buttonsPanel.add(lLimit, gbc); |
| | | gbc.weightx = 1.0; |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | buttonsPanel.add(Box.createHorizontalGlue(), gbc); |
| | | buttonsPanel.setOpaque(true); |
| | | buttonsPanel.setBackground(ColorAndFontConstants.greyBackground); |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | gbc.weightx = 0.0; |
| | | if (getBrowseButtonType() == GenericDialog.ButtonType.CLOSE) |
| | | { |
| | | closeButton = |
| | | Utilities.createButton(INFO_CTRL_PANEL_CLOSE_BUTTON_LABEL.get()); |
| | | closeButton = Utilities.createButton(INFO_CTRL_PANEL_CLOSE_BUTTON_LABEL.get()); |
| | | closeButton.setOpaque(false); |
| | | buttonsPanel.add(closeButton, gbc); |
| | | closeButton.addActionListener(new ActionListener() |
| | |
| | | okClicked(); |
| | | } |
| | | }); |
| | | cancelButton = |
| | | Utilities.createButton(INFO_CTRL_PANEL_CANCEL_BUTTON_LABEL.get()); |
| | | cancelButton = Utilities.createButton(INFO_CTRL_PANEL_CANCEL_BUTTON_LABEL.get()); |
| | | cancelButton.setOpaque(false); |
| | | gbc.insets.right = 10; |
| | | gbc.insets.left = 5; |
| | | gbc.gridx ++; |
| | | gbc.gridx++; |
| | | buttonsPanel.add(cancelButton, gbc); |
| | | cancelButton.addActionListener(new ActionListener() |
| | | { |
| | |
| | | }); |
| | | } |
| | | |
| | | |
| | | buttonsPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, |
| | | ColorAndFontConstants.defaultBorderColor)); |
| | | buttonsPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, ColorAndFontConstants.defaultBorderColor)); |
| | | |
| | | return buttonsPanel; |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * The method that is called when the user clicks on Apply. Basically it |
| | | * will update the BrowserController with the new base DN and filter specified |
| | | * by the user. The method assumes that is being called from the event |
| | | * thread. |
| | | * |
| | | * The method that is called when the user clicks on Apply. Basically it will |
| | | * update the BrowserController with the new base DN and filter specified by |
| | | * the user. The method assumes that is being called from the event thread. |
| | | */ |
| | | protected void applyButtonClicked() |
| | | { |
| | | ArrayList<LocalizableMessage> errors = new ArrayList<LocalizableMessage>(); |
| | | List<LocalizableMessage> errors = new ArrayList<>(); |
| | | setPrimaryValid(lFilter); |
| | | String s = getBaseDN(); |
| | | boolean displayAll = false; |
| | |
| | | lNumberOfEntries.setVisible(true); |
| | | controller.removeAllUnderRoot(); |
| | | controller.setFilter(filterValue); |
| | | controller.setAutomaticExpand(!filterValue.equals( |
| | | BrowserController.ALL_OBJECTS_FILTER)); |
| | | SortedSet<String> allSuffixes = new TreeSet<String>(); |
| | | controller.setAutomaticExpand(!BrowserController.ALL_OBJECTS_FILTER.equals(filterValue)); |
| | | SortedSet<String> allSuffixes = new TreeSet<>(); |
| | | if (controller.getConfigurationConnection() != null) |
| | | { |
| | | treePane.getTree().setRootVisible(displayAll); |
| | | treePane.getTree().setShowsRootHandles(!displayAll); |
| | | boolean added = false; |
| | | for (BackendDescriptor backend : |
| | | getInfo().getServerDescriptor().getBackends()) |
| | | for (BackendDescriptor backend : getInfo().getServerDescriptor().getBackends()) |
| | | { |
| | | for (BaseDNDescriptor baseDN : backend.getBaseDns()) |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | BasicNode rootNode = |
| | | (BasicNode)controller.getTree().getModel().getRoot(); |
| | | BasicNode rootNode = (BasicNode) controller.getTree().getModel().getRoot(); |
| | | if (controller.findChildNode(rootNode, s) == -1) |
| | | { |
| | | controller.addNodeUnderRoot(s); |
| | |
| | | { |
| | | try |
| | | { |
| | | return theDN.equals( |
| | | DN.valueOf(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT)); |
| | | return theDN.equals(DN.valueOf(ServerConstants.DN_EXTERNAL_CHANGELOG_ROOT)); |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | |
| | | |
| | | /** |
| | | * Returns the LDAP filter built based in the parameters provided by the user. |
| | | * |
| | | * @return the LDAP filter built based in the parameters provided by the user. |
| | | */ |
| | | private String getFilter() |
| | | { |
| | | String returnValue; |
| | | String s = filter.getText(); |
| | | if (s.length() == 0) |
| | | String filterText = filter.getText(); |
| | | if (filterText.length() == 0) |
| | | { |
| | | returnValue = BrowserController.ALL_OBJECTS_FILTER; |
| | | return BrowserController.ALL_OBJECTS_FILTER; |
| | | } |
| | | |
| | | Object attr = filterAttribute.getSelectedItem(); |
| | | if (LDAP_FILTER.equals(attr)) |
| | | { |
| | | filterText = filterText.trim(); |
| | | if (filterText.length() == 0) |
| | | { |
| | | return BrowserController.ALL_OBJECTS_FILTER; |
| | | } |
| | | |
| | | return filterText; |
| | | } |
| | | else if (USER_FILTER.equals(attr)) |
| | | { |
| | | if ("*".equals(filterText)) |
| | | { |
| | | return "(objectClass=person)"; |
| | | } |
| | | |
| | | return "(&(objectClass=person)(|" + "(cn=" + filterText + ")(sn=" + filterText + ")(uid=" + filterText + ")))"; |
| | | } |
| | | else if (GROUP_FILTER.equals(attr)) |
| | | { |
| | | if ("*".equals(filterText)) |
| | | { |
| | | return "(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))"; |
| | | } |
| | | |
| | | return "(&(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))" + "(cn=" + filterText + "))"; |
| | | } |
| | | else if (attr != null) |
| | | { |
| | | try |
| | | { |
| | | return new LDAPFilter(SearchFilter.createFilterFromString("(" + attr + "=" + filterText + ")")).toString(); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | // Try this alternative: |
| | | AttributeType attrType = |
| | | getInfo().getServerDescriptor().getSchema().getAttributeType(attr.toString().toLowerCase()); |
| | | return new LDAPFilter(SearchFilter.createEqualityFilter(attrType, ByteString.valueOf(filterText))).toString(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Object attr = filterAttribute.getSelectedItem(); |
| | | if (LDAP_FILTER.equals(attr)) |
| | | { |
| | | s = s.trim(); |
| | | if (s.length() == 0) |
| | | { |
| | | returnValue = BrowserController.ALL_OBJECTS_FILTER; |
| | | } |
| | | else |
| | | { |
| | | returnValue = s; |
| | | } |
| | | } |
| | | else if (USER_FILTER.equals(attr)) |
| | | { |
| | | if ("*".equals(s)) |
| | | { |
| | | returnValue = "(objectClass=person)"; |
| | | } |
| | | else |
| | | { |
| | | returnValue = "(&(objectClass=person)(|"+ |
| | | "(cn="+s+")(sn="+s+")(uid="+s+")))"; |
| | | } |
| | | } |
| | | else if (GROUP_FILTER.equals(attr)) |
| | | { |
| | | if ("*".equals(s)) |
| | | { |
| | | returnValue = |
| | | "(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))"; |
| | | } |
| | | else |
| | | { |
| | | returnValue = |
| | | "(&(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))"+ |
| | | "(cn="+s+"))"; |
| | | } |
| | | } |
| | | else if (attr != null) |
| | | { |
| | | try |
| | | { |
| | | LDAPFilter ldapFilter = |
| | | new LDAPFilter(SearchFilter.createFilterFromString( |
| | | "("+attr+"="+s+")")); |
| | | returnValue = ldapFilter.toString(); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | // Try this alternative: |
| | | AttributeType attrType = |
| | | getInfo().getServerDescriptor().getSchema().getAttributeType( |
| | | attr.toString().toLowerCase()); |
| | | LDAPFilter ldapFilter = |
| | | new LDAPFilter(SearchFilter.createEqualityFilter( attrType, ByteString.valueOf(s))); |
| | | returnValue = ldapFilter.toString(); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | returnValue = BrowserController.ALL_OBJECTS_FILTER; |
| | | } |
| | | return BrowserController.ALL_OBJECTS_FILTER; |
| | | } |
| | | return returnValue; |
| | | } |
| | | |
| | | /** |
| | | * Returns the component that will be displayed between the filtering options |
| | | * and the buttons panel. This component must contain the tree panel. |
| | | * and the buttons panel. This component must contain the tree panel. |
| | | * |
| | | * @return the component that will be displayed between the filtering options |
| | | * and the buttons panel. |
| | | * and the buttons panel. |
| | | */ |
| | | protected abstract Component createMainPanel(); |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void backendPopulated(BackendPopulatedEvent ev) |
| | |
| | | { |
| | | treePane.getTree().setRootVisible(displayAll); |
| | | treePane.getTree().setShowsRootHandles(!displayAll); |
| | | BasicNode rootNode = |
| | | (BasicNode)controller.getTree().getModel().getRoot(); |
| | | BasicNode rootNode = (BasicNode) controller.getTree().getModel().getRoot(); |
| | | boolean isSubordinate = false; |
| | | for (BackendDescriptor backend : ev.getBackends()) |
| | | { |
| | |
| | | TreeNode node = rootNode.getChildAt(index); |
| | | if (node != null) |
| | | { |
| | | TreePath path = new TreePath( |
| | | controller.getTreeModel().getPathToRoot(node)); |
| | | controller.startRefresh( |
| | | controller.getNodeInfoFromPath(path)); |
| | | TreePath path = new TreePath(controller.getTreeModel().getPathToRoot(node)); |
| | | controller.startRefresh(controller.getNodeInfoFromPath(path)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (IllegalArgumentException iae) |
| | | { |
| | | // The suffix node exists but is not a suffix node. |
| | | // Simply log a message. |
| | | logger.warn(LocalizableMessage.raw("Suffix: "+dn+ |
| | | " added as a non suffix node. Exception: "+iae, iae)); |
| | | // The suffix node exists but is not a suffix node. Simply log a message. |
| | | logger.warn( |
| | | LocalizableMessage.raw("Suffix: " + dn + " added as a non suffix node. Exception: " + iae, iae)); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void configurationChanged(ConfigurationChangeEvent ev) |
| | | { |
| | | final ServerDescriptor desc = ev.getNewDescriptor(); |
| | | |
| | | updateCombos(desc); |
| | | |
| | | updateBrowserControllerAndErrorPane(desc); |
| | | } |
| | | |
| | | /** |
| | | * Creates and returns the tree panel. |
| | | * |
| | | * @return the tree panel. |
| | | */ |
| | | protected JComponent createTreePane() |
| | | { |
| | | treePane = new TreePanel(); |
| | | |
| | | lNoMatchFound = Utilities.createDefaultLabel( |
| | | INFO_CTRL_PANEL_NO_MATCHES_FOUND_LABEL.get()); |
| | | lNoMatchFound = Utilities.createDefaultLabel(INFO_CTRL_PANEL_NO_MATCHES_FOUND_LABEL.get()); |
| | | lNoMatchFound.setVisible(false); |
| | | |
| | | // Calculate default size |
| | | JTree tree = treePane.getTree(); |
| | | DefaultMutableTreeNode root = new DefaultMutableTreeNode( |
| | | "myserver.mydomain.com:389"); |
| | | DefaultMutableTreeNode root = new DefaultMutableTreeNode("myserver.mydomain.com:389"); |
| | | DefaultTreeModel model = new DefaultTreeModel(root); |
| | | tree.setModel(model); |
| | | tree.setShowsRootHandles(false); |
| | |
| | | return p; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Creates the browser controller object. |
| | | * @param info the ControlPanelInfo to be used to create the browser |
| | | * controller. |
| | | * |
| | | * @param info |
| | | * the ControlPanelInfo to be used to create the browser controller. |
| | | */ |
| | | protected void createBrowserController(ControlPanelInfo info) |
| | | { |
| | | controller = new BrowserController(treePane.getTree(), |
| | | info.getConnectionPool(), |
| | | info.getIconPool()); |
| | | controller = new BrowserController(treePane.getTree(), info.getConnectionPool(), info.getIconPool()); |
| | | controller.setContainerClasses(CONTAINER_CLASSES); |
| | | controller.setShowContainerOnly(false); |
| | | controller.setMaxChildren(MAX_NUMBER_ENTRIES); |
| | |
| | | }); |
| | | controller.getTreeModel().addTreeModelListener(new TreeModelListener() |
| | | { |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void treeNodesChanged(TreeModelEvent e) |
| | | { |
| | | } |
| | | /** {@inheritDoc} */ |
| | | |
| | | @Override |
| | | public void treeNodesInserted(TreeModelEvent e) |
| | | { |
| | | checkRootNode(); |
| | | } |
| | | /** {@inheritDoc} */ |
| | | |
| | | @Override |
| | | public void treeNodesRemoved(TreeModelEvent e) |
| | | { |
| | | checkRootNode(); |
| | | } |
| | | /** {@inheritDoc} */ |
| | | |
| | | @Override |
| | | public void treeStructureChanged(TreeModelEvent e) |
| | | { |
| | |
| | | }); |
| | | } |
| | | |
| | | static final String[] systemIndexes = {"aci", "dn2id", "ds-sync-hist", |
| | | "entryUUID", "id2children", "id2subtree"}; |
| | | |
| | | private static boolean displayIndex(String name) |
| | | { |
| | | boolean displayIndex = true; |
| | | for (String systemIndex : systemIndexes) |
| | | for (String systemIndex : SYSTEM_INDEXES) |
| | | { |
| | | if (systemIndex.equalsIgnoreCase(name)) |
| | | { |
| | |
| | | |
| | | /** |
| | | * Updates the contents of the combo boxes with the provided ServerDescriptor. |
| | | * @param desc the server descriptor to be used to update the combo boxes. |
| | | * |
| | | * @param desc |
| | | * the server descriptor to be used to update the combo boxes. |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | private void updateCombos(ServerDescriptor desc) |
| | | { |
| | | final SortedSet<String> newElements = new TreeSet<String>(); |
| | | final SortedSet<String> newElements = new TreeSet<>(); |
| | | for (BackendDescriptor backend : desc.getBackends()) |
| | | { |
| | | for (IndexDescriptor index : backend.getIndexes()) |
| | |
| | | } |
| | | } |
| | | } |
| | | final DefaultComboBoxModel model = |
| | | (DefaultComboBoxModel)filterAttribute.getModel(); |
| | | final DefaultComboBoxModel model = (DefaultComboBoxModel) filterAttribute.getModel(); |
| | | boolean changed = newElements.size() != model.getSize() - 2; |
| | | if (!changed) |
| | | { |
| | |
| | | { |
| | | SwingUtilities.invokeLater(new Runnable() |
| | | { |
| | | /** {@inheritDoc} */ |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | public void run() |
| | | { |
| | |
| | | }); |
| | | } |
| | | |
| | | LinkedHashSet<Object> baseDNNewElements = new LinkedHashSet<Object>(); |
| | | SortedSet<String> backendIDs = new TreeSet<String>(); |
| | | HashMap<String, SortedSet<String>> hmBaseDNs = |
| | | new HashMap<String, SortedSet<String>>(); |
| | | Set<Object> baseDNNewElements = new LinkedHashSet<>(); |
| | | SortedSet<String> backendIDs = new TreeSet<>(); |
| | | Map<String, SortedSet<String>> hmBaseDNs = new HashMap<>(); |
| | | |
| | | boolean allAdded = false; |
| | | HashMap<String, BaseDNDescriptor> hmBaseDNWithEntries = |
| | | new HashMap<String, BaseDNDescriptor>(); |
| | | Map<String, BaseDNDescriptor> hmBaseDNWithEntries = new HashMap<>(); |
| | | |
| | | BaseDNDescriptor baseDNWithEntries = null; |
| | | for (BackendDescriptor backend : desc.getBackends()) |
| | |
| | | { |
| | | String backendID = backend.getBackendID(); |
| | | backendIDs.add(backendID); |
| | | SortedSet<String> someBaseDNs = new TreeSet<String>(); |
| | | SortedSet<String> someBaseDNs = new TreeSet<>(); |
| | | for (BaseDNDescriptor baseDN : backend.getBaseDns()) |
| | | { |
| | | try |
| | |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | throw new RuntimeException("Unexpected error: "+t, t); |
| | | throw new RuntimeException("Unexpected error: " + t, t); |
| | | } |
| | | if (baseDN.getEntries() > 0) |
| | | { |
| | | hmBaseDNWithEntries.put( |
| | | Utilities.unescapeUtf8(baseDN.getDn().toString()), baseDN); |
| | | hmBaseDNWithEntries.put(Utilities.unescapeUtf8(baseDN.getDn().toString()), baseDN); |
| | | } |
| | | } |
| | | hmBaseDNs.put(backendID, someBaseDNs); |
| | |
| | | |
| | | if (!allAdded) |
| | | { |
| | | baseDNNewElements.add(new CategorizedComboBoxElement(ALL_BASE_DNS, |
| | | CategorizedComboBoxElement.Type.REGULAR)); |
| | | baseDNNewElements.add(new CategorizedComboBoxElement(ALL_BASE_DNS, CategorizedComboBoxElement.Type.REGULAR)); |
| | | allAdded = true; |
| | | } |
| | | for (String backendID : backendIDs) |
| | | { |
| | | baseDNNewElements.add(new CategorizedComboBoxElement(backendID, |
| | | CategorizedComboBoxElement.Type.CATEGORY)); |
| | | baseDNNewElements.add(new CategorizedComboBoxElement(backendID, CategorizedComboBoxElement.Type.CATEGORY)); |
| | | SortedSet<String> someBaseDNs = hmBaseDNs.get(backendID); |
| | | for (String baseDN : someBaseDNs) |
| | | { |
| | | baseDNNewElements.add(new CategorizedComboBoxElement(baseDN, |
| | | CategorizedComboBoxElement.Type.REGULAR)); |
| | | baseDNNewElements.add(new CategorizedComboBoxElement(baseDN, CategorizedComboBoxElement.Type.REGULAR)); |
| | | if (baseDNWithEntries == null) |
| | | { |
| | | baseDNWithEntries = hmBaseDNWithEntries.get(baseDN); |
| | |
| | | baseDNNewElements.add(COMBO_SEPARATOR); |
| | | } |
| | | baseDNNewElements.add(new CategorizedComboBoxElement( |
| | | Utilities.unescapeUtf8(dn.toString()), |
| | | CategorizedComboBoxElement.Type.REGULAR)); |
| | | Utilities.unescapeUtf8(dn.toString()), CategorizedComboBoxElement.Type.REGULAR)); |
| | | } |
| | | if (allAdded) |
| | | { |
| | |
| | | { |
| | | ignoreBaseDNEvents = true; |
| | | } |
| | | updateComboBoxModel(baseDNNewElements, |
| | | (DefaultComboBoxModel)baseDNs.getModel()); |
| | | updateComboBoxModel(baseDNNewElements, (DefaultComboBoxModel) baseDNs.getModel()); |
| | | // Select the element in the combo box. |
| | | if (firstTimeDisplayed && baseDNWithEntries != null) |
| | | { |
| | | final Object toSelect = new CategorizedComboBoxElement( |
| | | Utilities.unescapeUtf8(baseDNWithEntries.getDn().toString()), |
| | | CategorizedComboBoxElement.Type.REGULAR); |
| | | Utilities.unescapeUtf8(baseDNWithEntries.getDn().toString()), CategorizedComboBoxElement.Type.REGULAR); |
| | | SwingUtilities.invokeLater(new Runnable() |
| | | { |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void run() |
| | | { |
| | |
| | | |
| | | /** |
| | | * Updates the contents of the error pane and the browser controller with the |
| | | * provided ServerDescriptor. It checks that the server is running and that |
| | | * we are authenticated, that the connection to the server has not changed, |
| | | * etc. |
| | | * @param desc the server descriptor to be used to update the error pane and |
| | | * browser controller. |
| | | * provided ServerDescriptor. It checks that the server is running and that we |
| | | * are authenticated, that the connection to the server has not changed, etc. |
| | | * |
| | | * @param desc |
| | | * the server descriptor to be used to update the error pane and |
| | | * browser controller. |
| | | */ |
| | | private void updateBrowserControllerAndErrorPane(ServerDescriptor desc) |
| | | { |
| | |
| | | if (!desc.isAuthenticated()) |
| | | { |
| | | LocalizableMessageBuilder mb = new LocalizableMessageBuilder(); |
| | | mb.append( |
| | | INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_TO_BROWSE_SUMMARY.get()); |
| | | mb.append(INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_TO_BROWSE_SUMMARY.get()); |
| | | mb.append("<br><br>").append(getAuthenticateHTML()); |
| | | errorDetails = mb.toMessage(); |
| | | errorTitle = INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_SUMMARY.get(); |
| | |
| | | if (getInfo().getUserDataDirContext() == null) |
| | | { |
| | | InitialLdapContext ctxUserData = |
| | | createUserDataDirContext(ConnectionUtils.getBindDN(ctx), |
| | | ConnectionUtils.getBindPassword(ctx)); |
| | | createUserDataDirContext(ConnectionUtils.getBindDN(ctx), ConnectionUtils.getBindPassword(ctx)); |
| | | getInfo().setUserDataDirContext(ctxUserData); |
| | | } |
| | | final NamingException[] fNe = {null}; |
| | | final NamingException[] fNe = { null }; |
| | | Runnable runnable = new Runnable() |
| | | { |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void run() |
| | | { |
| | | try |
| | | { |
| | | controller.setConnections(getInfo().getServerDescriptor(), |
| | | getInfo().getDirContext(), |
| | | getInfo().getUserDataDirContext()); |
| | | controller.setConnections( |
| | | getInfo().getServerDescriptor(), getInfo().getDirContext(), getInfo().getUserDataDirContext()); |
| | | applyButtonClicked(); |
| | | } |
| | | catch (NamingException ne) |
| | |
| | | { |
| | | SwingUtilities.invokeAndWait(runnable); |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | } |
| | | catch (Throwable t) {} |
| | | } |
| | | else |
| | | { |
| | |
| | | else if (status == ServerDescriptor.ServerStatus.NOT_CONNECTED_TO_REMOTE) |
| | | { |
| | | LocalizableMessageBuilder mb = new LocalizableMessageBuilder(); |
| | | mb.append(INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get( |
| | | desc.getHostname())); |
| | | mb.append(INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname())); |
| | | mb.append("<br><br>").append(getAuthenticateHTML()); |
| | | errorDetails = mb.toMessage(); |
| | | errorTitle = INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_SUMMARY.get(); |
| | |
| | | { |
| | | errorTitle = INFO_CTRL_PANEL_SERVER_NOT_RUNNING_SUMMARY.get(); |
| | | LocalizableMessageBuilder mb = new LocalizableMessageBuilder(); |
| | | mb.append( |
| | | INFO_CTRL_PANEL_AUTHENTICATION_SERVER_MUST_RUN_TO_BROWSE_SUMMARY.get()); |
| | | mb.append(INFO_CTRL_PANEL_AUTHENTICATION_SERVER_MUST_RUN_TO_BROWSE_SUMMARY.get()); |
| | | mb.append("<br><br>"); |
| | | mb.append(getStartServerHTML()); |
| | | errorDetails = mb.toMessage(); |
| | |
| | | final LocalizableMessage fErrorDetails = errorDetails; |
| | | SwingUtilities.invokeLater(new Runnable() |
| | | { |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public void run() |
| | | { |
| | |
| | | if (fDisplayErrorPane) |
| | | { |
| | | updateErrorPane(errorPane, fErrorTitle, |
| | | ColorAndFontConstants.errorTitleFont, fErrorDetails, |
| | | ColorAndFontConstants.defaultFont); |
| | | ColorAndFontConstants.errorTitleFont, fErrorDetails, ColorAndFontConstants.defaultFont); |
| | | } |
| | | else if (fDisplayNodes) |
| | | { |
| | |
| | | boolean displayAll = false; |
| | | if (s != null) |
| | | { |
| | | displayAll = s.equals(ALL_BASE_DNS); |
| | | displayAll = ALL_BASE_DNS.equals(s); |
| | | if (!displayAll) |
| | | { |
| | | try |
| | |
| | | if (s != null) |
| | | { |
| | | boolean added = false; |
| | | for (BackendDescriptor backend : |
| | | getInfo().getServerDescriptor().getBackends()) |
| | | for (BackendDescriptor backend : getInfo().getServerDescriptor().getBackends()) |
| | | { |
| | | for (BaseDNDescriptor baseDN : backend.getBaseDns()) |
| | | { |
| | | boolean isBaseDN = false; |
| | | String dn = Utilities.unescapeUtf8(baseDN.getDn().toString()); |
| | | if ((theDN != null) && baseDN.getDn().equals(theDN)) |
| | | if (theDN != null && baseDN.getDn().equals(theDN)) |
| | | { |
| | | isBaseDN = true; |
| | | } |
| | |
| | | { |
| | | try |
| | | { |
| | | if ((displayAll || isBaseDN) |
| | | && !controller.hasSuffix(dn)) |
| | | if ((displayAll || isBaseDN) && !controller.hasSuffix(dn)) |
| | | { |
| | | controller.addSuffix(dn, null); |
| | | added = true; |
| | |
| | | } |
| | | catch (IllegalArgumentException iae) |
| | | { |
| | | // The suffix node exists but is not a suffix node. |
| | | // Simply log a message. |
| | | logger.warn(LocalizableMessage.raw("Suffix: "+dn+ |
| | | " added as a non suffix node. Exception: "+iae, iae)); |
| | | // The suffix node exists but is not a suffix node. Simply log a message. |
| | | logger.warn(LocalizableMessage.raw( |
| | | "Suffix: " + dn + " added as a non suffix node. Exception: " + iae, iae)); |
| | | } |
| | | } |
| | | } |
| | | if (!added && !displayAll) |
| | | { |
| | | BasicNode rootNode = |
| | | (BasicNode)controller.getTree().getModel().getRoot(); |
| | | BasicNode rootNode = (BasicNode) controller.getTree().getModel().getRoot(); |
| | | if (controller.findChildNode(rootNode, s) == -1) |
| | | { |
| | | controller.addNodeUnderRoot(s); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | if (!fDisplayNodes) |
| | | { |
| | | controller.removeAllUnderRoot(); |
| | |
| | | |
| | | /** |
| | | * Returns the base DN specified by the user. |
| | | * |
| | | * @return the base DN specified by the user. |
| | | */ |
| | | private String getBaseDN() |
| | |
| | | Object o = baseDNs.getSelectedItem(); |
| | | if (o instanceof String) |
| | | { |
| | | dn = (String)o; |
| | | dn = (String) o; |
| | | } |
| | | else if (o instanceof CategorizedComboBoxElement) |
| | | { |
| | | dn = ((CategorizedComboBoxElement)o).getValue().toString(); |
| | | dn = ((CategorizedComboBoxElement) o).getValue().toString(); |
| | | } |
| | | else |
| | | { |
| | |
| | | /** |
| | | * Creates the context to be used to retrieve user data for some given |
| | | * credentials. |
| | | * @param bindDN the bind DN. |
| | | * @param bindPassword the bind password. |
| | | * |
| | | * @param bindDN |
| | | * the bind DN. |
| | | * @param bindPassword |
| | | * the bind password. |
| | | * @return the context to be used to retrieve user data for some given |
| | | * credentials. |
| | | * @throws NamingException if an error occurs connecting to the server. |
| | | * @throws ConfigReadException if an error occurs reading the configuration. |
| | | * credentials. |
| | | * @throws NamingException |
| | | * if an error occurs connecting to the server. |
| | | * @throws ConfigReadException |
| | | * if an error occurs reading the configuration. |
| | | */ |
| | | private InitialLdapContext createUserDataDirContext( |
| | | final String bindDN, final String bindPassword) |
| | | throws NamingException, ConfigReadException |
| | | private InitialLdapContext createUserDataDirContext(final String bindDN, final String bindPassword) |
| | | throws NamingException, ConfigReadException |
| | | { |
| | | createdUserDataCtx = null; |
| | | try |
| | | { |
| | | createdUserDataCtx = Utilities.getUserDataDirContext(getInfo(), |
| | | bindDN, bindPassword); |
| | | createdUserDataCtx = Utilities.getUserDataDirContext(getInfo(), bindDN, bindPassword); |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | if (isCertificateException(ne)) |
| | | { |
| | | ApplicationTrustManager.Cause cause = |
| | | getInfo().getTrustManager().getLastRefusedCause(); |
| | | ApplicationTrustManager.Cause cause = getInfo().getTrustManager().getLastRefusedCause(); |
| | | |
| | | logger.info(LocalizableMessage.raw("Certificate exception cause: "+cause)); |
| | | logger.info(LocalizableMessage.raw("Certificate exception cause: " + cause)); |
| | | UserDataCertificateException.Type excType = null; |
| | | if (cause == ApplicationTrustManager.Cause.NOT_TRUSTED) |
| | | { |
| | | excType = UserDataCertificateException.Type.NOT_TRUSTED; |
| | | } |
| | | else if (cause == |
| | | ApplicationTrustManager.Cause.HOST_NAME_MISMATCH) |
| | | else if (cause == ApplicationTrustManager.Cause.HOST_NAME_MISMATCH) |
| | | { |
| | | excType = UserDataCertificateException.Type.HOST_NAME_MISMATCH; |
| | | } |
| | |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | logger.warn(LocalizableMessage.raw( |
| | | "Error parsing ldap url of ldap url.", t)); |
| | | logger.warn(LocalizableMessage.raw("Error parsing ldap url of ldap url.", t)); |
| | | h = INFO_NOT_AVAILABLE_LABEL.get().toString(); |
| | | p = -1; |
| | | } |
| | | final UserDataCertificateException udce = |
| | | new UserDataCertificateException(null, |
| | | INFO_CERTIFICATE_EXCEPTION.get(h, p), |
| | | ne, h, p, |
| | | getInfo().getTrustManager().getLastRefusedChain(), |
| | | getInfo().getTrustManager().getLastRefusedAuthType(), |
| | | excType); |
| | | final UserDataCertificateException udce = new UserDataCertificateException( |
| | | null, INFO_CERTIFICATE_EXCEPTION.get(h, p), ne, h, p, getInfo().getTrustManager().getLastRefusedChain(), |
| | | getInfo().getTrustManager().getLastRefusedAuthType(), excType); |
| | | |
| | | if (SwingUtilities.isEventDispatchThread()) |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | final ConfigReadException[] fcre = {null}; |
| | | final NamingException[] fne = {null}; |
| | | final ConfigReadException[] fcre = { null }; |
| | | final NamingException[] fne = { null }; |
| | | try |
| | | { |
| | | SwingUtilities.invokeAndWait(new Runnable() |
| | |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | throw new IllegalArgumentException("Unexpected error: "+t, t); |
| | | throw new IllegalArgumentException("Unexpected error: " + t, t); |
| | | } |
| | | if (fcre[0] != null) |
| | | { |
| | |
| | | /** |
| | | * Displays a dialog asking the user to accept a certificate if the user |
| | | * accepts it, we update the trust manager and simulate a click on "OK" to |
| | | * re-check the authentication. |
| | | * This method assumes that we are being called from the event thread. |
| | | * @param bindDN the bind DN. |
| | | * @param bindPassword the bind password. |
| | | * re-check the authentication. This method assumes that we are being called |
| | | * from the event thread. |
| | | * |
| | | * @param bindDN |
| | | * the bind DN. |
| | | * @param bindPassword |
| | | * the bind password. |
| | | */ |
| | | private void handleCertificateException(UserDataCertificateException ce, |
| | | String bindDN, String bindPassword) |
| | | throws NamingException, ConfigReadException |
| | | private void handleCertificateException(UserDataCertificateException ce, String bindDN, String bindPassword) |
| | | throws NamingException, ConfigReadException |
| | | { |
| | | CertificateDialog dlg = new CertificateDialog(null, ce); |
| | | dlg.pack(); |
| | | Utilities.centerGoldenMean(dlg, Utilities.getParentDialog(this)); |
| | | dlg.setVisible(true); |
| | | if (dlg.getUserAnswer() != |
| | | CertificateDialog.ReturnType.NOT_ACCEPTED) |
| | | if (dlg.getUserAnswer() != CertificateDialog.ReturnType.NOT_ACCEPTED) |
| | | { |
| | | X509Certificate[] chain = ce.getChain(); |
| | | String authType = ce.getAuthType(); |
| | |
| | | |
| | | if (chain != null && authType != null && host != null) |
| | | { |
| | | logger.info(LocalizableMessage.raw("Accepting certificate presented by host "+host)); |
| | | logger.info(LocalizableMessage.raw("Accepting certificate presented by host " + host)); |
| | | getInfo().getTrustManager().acceptCertificate(chain, authType, host); |
| | | createdUserDataCtx = createUserDataDirContext(bindDN, bindPassword); |
| | | } |
| | |
| | | { |
| | | if (chain == null) |
| | | { |
| | | logger.warn(LocalizableMessage.raw( |
| | | "The chain is null for the UserDataCertificateException")); |
| | | logger.warn(LocalizableMessage.raw("The chain is null for the UserDataCertificateException")); |
| | | } |
| | | if (authType == null) |
| | | { |
| | | logger.warn(LocalizableMessage.raw( |
| | | "The auth type is null for the UserDataCertificateException")); |
| | | logger.warn(LocalizableMessage.raw("The auth type is null for the UserDataCertificateException")); |
| | | } |
| | | if (host == null) |
| | | { |
| | | logger.warn(LocalizableMessage.raw( |
| | | "The host is null for the UserDataCertificateException")); |
| | | logger.warn(LocalizableMessage.raw("The host is null for the UserDataCertificateException")); |
| | | } |
| | | } |
| | | } |
| | | if (dlg.getUserAnswer() == |
| | | CertificateDialog.ReturnType.ACCEPTED_PERMANENTLY) |
| | | if (dlg.getUserAnswer() == CertificateDialog.ReturnType.ACCEPTED_PERMANENTLY) |
| | | { |
| | | X509Certificate[] chain = ce.getChain(); |
| | | if (chain != null) |
| | |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | logger.warn(LocalizableMessage.raw("Error accepting certificate: "+t, t)); |
| | | logger.warn(LocalizableMessage.raw("Error accepting certificate: " + t, t)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * This class is used simply to avoid an inset on the left for the |
| | | * 'All Base DNs' item. |
| | | * Since this item is a CategorizedComboBoxElement of type |
| | | * CategorizedComboBoxElement.Type.REGULAR, it has by default an inset on |
| | | * the left. The class simply handles this particular case to not to have |
| | | * that inset for the 'All Base DNs' item. |
| | | * This class is used simply to avoid an inset on the left for the 'All Base |
| | | * DNs' item. Since this item is a CategorizedComboBoxElement of type |
| | | * CategorizedComboBoxElement.Type.REGULAR, it has by default an inset on the |
| | | * left. The class simply handles this particular case to not to have that |
| | | * inset for the 'All Base DNs' item. |
| | | */ |
| | | class CustomComboBoxCellRenderer extends CustomListCellRenderer |
| | | { |
| | | private LocalizableMessage ALL_BASE_DNS_STRING = INFO_CTRL_PANEL_ALL_BASE_DNS.get(); |
| | | |
| | | /** |
| | | * The constructor. |
| | | * @param combo the combo box to be rendered. |
| | | * |
| | | * @param combo |
| | | * the combo box to be rendered. |
| | | */ |
| | | CustomComboBoxCellRenderer(JComboBox combo) |
| | | CustomComboBoxCellRenderer(JComboBox<?> combo) |
| | | { |
| | | super(combo); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Component getListCellRendererComponent(JList list, Object value, |
| | | int index, boolean isSelected, boolean cellHasFocus) |
| | | @SuppressWarnings("rawtypes") |
| | | public Component getListCellRendererComponent( |
| | | JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) |
| | | { |
| | | Component comp = super.getListCellRendererComponent(list, value, index, |
| | | isSelected, cellHasFocus); |
| | | Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
| | | if (value instanceof CategorizedComboBoxElement) |
| | | { |
| | | CategorizedComboBoxElement element = (CategorizedComboBoxElement)value; |
| | | CategorizedComboBoxElement element = (CategorizedComboBoxElement) value; |
| | | String name = getStringValue(element); |
| | | if (ALL_BASE_DNS.equals(name)) |
| | | { |
| | | ((JLabel)comp).setText(ALL_BASE_DNS_STRING.toString()); |
| | | ((JLabel) comp).setText(ALL_BASE_DNS_STRING.toString()); |
| | | } |
| | | } |
| | | comp.setFont(defaultFont); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Checks that the root node has some children. It it has no children the |
| | | * Checks that the root node has some children. It it has no children the |
| | | * message 'No Match Found' is displayed instead of the tree panel. |
| | | * |
| | | */ |
| | | private void checkRootNode() |
| | | { |
| | | DefaultMutableTreeNode root = |
| | | (DefaultMutableTreeNode)controller.getTreeModel().getRoot(); |
| | | DefaultMutableTreeNode root = (DefaultMutableTreeNode) controller.getTreeModel().getRoot(); |
| | | boolean visible = root.getChildCount() > 0; |
| | | if (visible != treePane.isVisible()) |
| | | { |
| | |
| | | /** |
| | | * Updates the NumsubordinateHacker of the browser controller with the |
| | | * provided server descriptor. |
| | | * @param server the server descriptor. |
| | | * |
| | | * @param server |
| | | * the server descriptor. |
| | | */ |
| | | private void updateNumSubordinateHacker(ServerDescriptor server) |
| | | { |
| | | String serverHost = server.getHostname(); |
| | | int serverPort = server.getAdminConnector().getPort(); |
| | | |
| | | ArrayList<DN> allSuffixes = new ArrayList<DN>(); |
| | | List<DN> allSuffixes = new ArrayList<>(); |
| | | for (BackendDescriptor backend : server.getBackends()) |
| | | { |
| | | for (BaseDNDescriptor baseDN : backend.getBaseDns()) |
| | |
| | | allSuffixes.add(baseDN.getDn()); |
| | | } |
| | | } |
| | | ArrayList<DN> rootSuffixes = new ArrayList<DN>(); |
| | | |
| | | List<DN> rootSuffixes = new ArrayList<>(); |
| | | for (DN dn : allSuffixes) |
| | | { |
| | | boolean isRootSuffix = true; |
| | |
| | | rootSuffixes.add(dn); |
| | | } |
| | | } |
| | | controller.getNumSubordinateHacker().update(allSuffixes, rootSuffixes, |
| | | serverHost, serverPort); |
| | | controller.getNumSubordinateHacker().update(allSuffixes, rootSuffixes, serverHost, serverPort); |
| | | } |
| | | |
| | | /** |
| | | * This is a class that simply checks the number of entries that the browser |
| | | * contains and updates a counter with the new number of entries. |
| | | * It is basically a thread that sleeps and checks whether some |
| | | * calculation must be made: when we know that something is updated in the |
| | | * browser the method recalculate() is called. We could use a more |
| | | * sofisticated code (like use a wait() call that would get notified when |
| | | * recalculate() is called) but this is not required and it might have an |
| | | * impact on the reactivity of the UI if recalculate gets called too often. |
| | | * We can afford to wait 400 miliseconds before updating the number of |
| | | * entries and with this approach there is hardly no impact on the reactivity |
| | | * of the UI. |
| | | * |
| | | * contains and updates a counter with the new number of entries. It is |
| | | * basically a thread that sleeps and checks whether some calculation must be |
| | | * made: when we know that something is updated in the browser the method |
| | | * recalculate() is called. We could use a more sofisticated code (like use a |
| | | * wait() call that would get notified when recalculate() is called) but this |
| | | * is not required and it might have an impact on the reactivity of the UI if |
| | | * recalculate gets called too often. We can afford to wait 400 miliseconds |
| | | * before updating the number of entries and with this approach there is |
| | | * hardly no impact on the reactivity of the UI. |
| | | */ |
| | | protected class NumberOfEntriesUpdater extends Thread implements Runnable |
| | | { |
| | | private boolean recalculate; |
| | | |
| | | /** |
| | | * Constructor. |
| | | * |
| | | */ |
| | | public NumberOfEntriesUpdater() |
| | | { |
| | | } |
| | | |
| | | /** |
| | | * Notifies that the number of entries in the browser has changed. |
| | | * |
| | | */ |
| | | /** Notifies that the number of entries in the browser has changed. */ |
| | | public void recalculate() |
| | | { |
| | | recalculate = true; |
| | | } |
| | | |
| | | /** |
| | | * Executes the updater. |
| | | */ |
| | | /** Executes the updater. */ |
| | | @Override |
| | | public void run() |
| | | { |
| | |
| | | // access to the node children |
| | | if (controller.getTree().isRootVisible()) |
| | | { |
| | | nEntries ++; |
| | | nEntries++; |
| | | } |
| | | DefaultMutableTreeNode root = |
| | | (DefaultMutableTreeNode)controller.getTreeModel().getRoot(); |
| | | DefaultMutableTreeNode root = (DefaultMutableTreeNode) controller.getTreeModel().getRoot(); |
| | | |
| | | nEntries += getChildren(root); |
| | | lNumberOfEntries.setText(INFO_CTRL_BROWSER_NUMBER_OF_ENTRIES.get( |
| | | nEntries).toString()); |
| | | lNumberOfEntries.setText(INFO_CTRL_BROWSER_NUMBER_OF_ENTRIES.get(nEntries).toString()); |
| | | } |
| | | }); |
| | | } |
| | |
| | | |
| | | /** |
| | | * Returns the number of children for a given node. |
| | | * @param node the node. |
| | | * |
| | | * @param node |
| | | * the node. |
| | | * @return the number of children for the node. |
| | | */ |
| | | private int getChildren(DefaultMutableTreeNode node) |
| | |
| | | Enumeration<?> en = node.children(); |
| | | while (en.hasMoreElements()) |
| | | { |
| | | nEntries ++; |
| | | nEntries += getChildren((DefaultMutableTreeNode)en.nextElement()); |
| | | nEntries++; |
| | | nEntries += getChildren((DefaultMutableTreeNode) en.nextElement()); |
| | | } |
| | | } |
| | | return nEntries; |