| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.guitools.controlpanel.ui; |
| | | |
| | | import static org.opends.messages.AdminToolMessages.*; |
| | | |
| | | import java.awt.Component; |
| | | import java.awt.GridBagConstraints; |
| | | import java.awt.event.ActionEvent; |
| | | import java.awt.event.ActionListener; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Set; |
| | | |
| | | import javax.naming.ldap.InitialLdapContext; |
| | | import javax.swing.JButton; |
| | | import javax.swing.JLabel; |
| | | import javax.swing.JTextField; |
| | | import javax.swing.event.DocumentEvent; |
| | | import javax.swing.event.DocumentListener; |
| | | |
| | | import org.opends.guitools.controlpanel.browser.BrowserController; |
| | | import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; |
| | | import org.opends.guitools.controlpanel.ui.nodes.BasicNode; |
| | | import org.opends.guitools.controlpanel.util.BackgroundTask; |
| | | import org.opends.guitools.controlpanel.util.LDAPEntryReader; |
| | | import org.opends.guitools.controlpanel.util.Utilities; |
| | | import org.opends.messages.Message; |
| | | import org.opends.quicksetup.util.Utils; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.util.Base64; |
| | | import org.opends.server.util.LDIFException; |
| | | import org.opends.server.util.ServerConstants; |
| | | |
| | | /** |
| | | * The panel used to duplicate an entry. |
| | | * |
| | | */ |
| | | public class DuplicateEntryPanel extends AbstractNewEntryPanel |
| | | { |
| | | private static final long serialVersionUID = -9879879123123123L; |
| | | private JLabel lName; |
| | | private JTextField name; |
| | | private JLabel lParentDN; |
| | | private JTextField parentDN; |
| | | private JButton browse; |
| | | private JLabel dn; |
| | | |
| | | private GenericDialog browseDlg; |
| | | private LDAPEntrySelectionPanel browsePanel; |
| | | |
| | | private CustomSearchResult entryToDuplicate; |
| | | private String rdnAttribute; |
| | | |
| | | private JLabel entryHasPasswordWarning; |
| | | |
| | | private final static String DEFAULT_PASSWORD_VALUE = "password"; |
| | | |
| | | /** |
| | | * Default constructor. |
| | | * |
| | | */ |
| | | public DuplicateEntryPanel() |
| | | { |
| | | super(); |
| | | createLayout(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Component getPreferredFocusComponent() |
| | | { |
| | | return name; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean requiresScroll() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void setParent(BasicNode parentNode, BrowserController controller) |
| | | { |
| | | throw new IllegalArgumentException("this method must not be called"); |
| | | } |
| | | |
| | | /** |
| | | * Sets the entry to be duplicated. |
| | | * @param node the node to be duplicated. |
| | | * @param controller the browser controller. |
| | | */ |
| | | public void setEntryToDuplicate(BasicNode node, |
| | | BrowserController controller) |
| | | { |
| | | if (node == null) |
| | | { |
| | | throw new IllegalArgumentException("node is null."); |
| | | } |
| | | |
| | | displayMessage(INFO_CTRL_PANEL_READING_SUMMARY.get()); |
| | | setEnabledOK(false); |
| | | |
| | | entryToDuplicate = null; |
| | | super.controller = controller; |
| | | |
| | | DN parentDN; |
| | | String rdn; |
| | | try |
| | | { |
| | | DN nodeDN = DN.decode(node.getDN()); |
| | | if (nodeDN.isNullDN()) |
| | | { |
| | | parentDN = nodeDN; |
| | | rdn = "(1)"; |
| | | } |
| | | else |
| | | { |
| | | parentDN = nodeDN.getParent(); |
| | | rdn = nodeDN.getRDN().getAttributeValue(0).toString()+"-1"; |
| | | } |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | throw new IllegalStateException("Unexpected error decoding dn: '"+ |
| | | node.getDN()+"' error: "+de, de); |
| | | } |
| | | this.parentDN.setText(parentDN.toString()); |
| | | this.name.setText(rdn); |
| | | |
| | | readEntry(node); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected Message getProgressDialogTitle() |
| | | { |
| | | return INFO_CTRL_PANEL_DUPLICATE_ENTRY_TITLE.get(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Message getTitle() |
| | | { |
| | | return INFO_CTRL_PANEL_DUPLICATE_ENTRY_TITLE.get(); |
| | | } |
| | | |
| | | /** |
| | | * Creates the layout of the panel (but the contents are not populated here). |
| | | */ |
| | | private void createLayout() |
| | | { |
| | | GridBagConstraints gbc = new GridBagConstraints(); |
| | | gbc.gridx = 0; |
| | | gbc.gridy = 0; |
| | | |
| | | addErrorPane(gbc); |
| | | |
| | | gbc.gridy ++; |
| | | gbc.gridwidth = 1; |
| | | gbc.weightx = 0.0; |
| | | gbc.weighty = 0.0; |
| | | gbc.fill = GridBagConstraints.HORIZONTAL; |
| | | |
| | | gbc.gridx = 0; |
| | | gbc.insets.left = 0; |
| | | lName = Utilities.createPrimaryLabel( |
| | | INFO_CTRL_PANEL_DUPLICATE_ENTRY_NAME_LABEL.get()); |
| | | add(lName, gbc); |
| | | name = Utilities.createTextField("", 30); |
| | | gbc.weightx = 1.0; |
| | | gbc.gridwidth = 2; |
| | | gbc.weightx = 1.0; |
| | | gbc.insets.left = 10; |
| | | gbc.gridx = 1; |
| | | add(name, gbc); |
| | | |
| | | gbc.gridy ++; |
| | | gbc.gridx = 0; |
| | | gbc.insets.top = 10; |
| | | gbc.insets.left = 0; |
| | | gbc.gridwidth = 1; |
| | | gbc.weightx = 0.0; |
| | | |
| | | gbc.fill = GridBagConstraints.BOTH; |
| | | lParentDN = Utilities.createPrimaryLabel( |
| | | INFO_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DN_LABEL.get()); |
| | | add(lParentDN, gbc); |
| | | |
| | | parentDN = Utilities.createTextField("", 30); |
| | | gbc.weightx = 1.0; |
| | | gbc.weightx = 1.0; |
| | | gbc.insets.left = 10; |
| | | gbc.gridx = 1; |
| | | add(parentDN, gbc); |
| | | |
| | | browse = Utilities.createButton( |
| | | INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get()); |
| | | gbc.weightx = 0.0; |
| | | gbc.gridx = 2; |
| | | add(browse, gbc); |
| | | browse.addActionListener(new ActionListener() |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void actionPerformed(ActionEvent ev) |
| | | { |
| | | browseClicked(); |
| | | } |
| | | }); |
| | | |
| | | gbc.gridx = 0; |
| | | gbc.gridy ++; |
| | | gbc.insets.left = 0; |
| | | Message msg = INFO_CTRL_PANEL_ENTRY_TO_DUPLICATE_HAS_PASSWORD_WARNING.get( |
| | | DEFAULT_PASSWORD_VALUE); |
| | | entryHasPasswordWarning = Utilities.createDefaultLabel(); |
| | | Utilities.setWarningLabel(entryHasPasswordWarning, msg); |
| | | gbc.gridwidth = 3; |
| | | add(entryHasPasswordWarning, gbc); |
| | | |
| | | gbc.gridwidth = 1; |
| | | gbc.gridx = 0; |
| | | gbc.gridy ++; |
| | | gbc.insets.left = 0; |
| | | add(Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DUPLICATE_ENTRY_DN.get()), |
| | | gbc); |
| | | dn = Utilities.createDefaultLabel(); |
| | | |
| | | gbc.gridx = 1; |
| | | gbc.gridwidth = 2; |
| | | gbc.insets.left = 10; |
| | | add(dn, gbc); |
| | | |
| | | DocumentListener listener = new DocumentListener() |
| | | { |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void insertUpdate(DocumentEvent ev) |
| | | { |
| | | updateDNValue(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void changedUpdate(DocumentEvent ev) |
| | | { |
| | | insertUpdate(ev); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void removeUpdate(DocumentEvent ev) |
| | | { |
| | | insertUpdate(ev); |
| | | } |
| | | }; |
| | | name.getDocument().addDocumentListener(listener); |
| | | parentDN.getDocument().addDocumentListener(listener); |
| | | |
| | | addBottomGlue(gbc); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected void checkSyntax(ArrayList<Message> errors) |
| | | { |
| | | int origSize = errors.size(); |
| | | String name = this.name.getText().trim(); |
| | | setPrimaryValid(lName); |
| | | setPrimaryValid(lParentDN); |
| | | if (name.length() == 0) |
| | | { |
| | | errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_NAME_EMPTY.get()); |
| | | setPrimaryInvalid(lName); |
| | | } |
| | | String parentDN = this.parentDN.getText().trim(); |
| | | if (!Utils.isDn(parentDN)) |
| | | { |
| | | errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DN_NOT_VALID.get()); |
| | | setPrimaryInvalid(lParentDN); |
| | | } |
| | | else if (!entryExists(parentDN)) |
| | | { |
| | | errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DOES_NOT_EXIST.get()); |
| | | setPrimaryInvalid(lParentDN); |
| | | } |
| | | |
| | | if (errors.size() == origSize) |
| | | { |
| | | try |
| | | { |
| | | getEntry(); |
| | | } |
| | | catch (IOException ioe) |
| | | { |
| | | errors.add(ERR_CTRL_PANEL_ERROR_CHECKING_ENTRY.get(ioe.toString())); |
| | | } |
| | | catch (LDIFException le) |
| | | { |
| | | errors.add(le.getMessageObject()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | protected String getLDIF() |
| | | { |
| | | String dn = this.dn.getText(); |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("dn: "+dn); |
| | | for (String attrName : entryToDuplicate.getAttributeNames()) |
| | | { |
| | | Set<Object> values = entryToDuplicate.getAttributeValues(attrName); |
| | | if (attrName.equalsIgnoreCase(ServerConstants.ATTR_USER_PASSWORD)) |
| | | { |
| | | sb.append("\n"); |
| | | sb.append(attrName+": "+DEFAULT_PASSWORD_VALUE); |
| | | } |
| | | else if (!attrName.equalsIgnoreCase(rdnAttribute)) |
| | | { |
| | | if (!ViewEntryPanel.isEditable(attrName, |
| | | getInfo().getServerDescriptor().getSchema())) |
| | | { |
| | | continue; |
| | | } |
| | | for (Object value : values) |
| | | { |
| | | sb.append("\n"); |
| | | if (value instanceof String) |
| | | { |
| | | sb.append(attrName+": "+value); |
| | | } |
| | | else if (value instanceof byte[]) |
| | | { |
| | | sb.append(attrName+":: "+Base64.encode((byte[])value)); |
| | | } |
| | | else |
| | | { |
| | | sb.append(attrName+": "+value); |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | String newValue = null; |
| | | try |
| | | { |
| | | DN theDN = DN.decode(dn); |
| | | newValue = theDN.getRDN().getAttributeValue(0).toString(); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | throw new IllegalStateException("Unexpected error with dn: '"+dn+ |
| | | "' "+de, de); |
| | | } |
| | | if (values.size() == 1) |
| | | { |
| | | sb.append("\n"); |
| | | sb.append(attrName+": "+newValue); |
| | | } |
| | | else |
| | | { |
| | | String oldValue = null; |
| | | try |
| | | { |
| | | DN oldDN = DN.decode(entryToDuplicate.getDN()); |
| | | oldValue = oldDN.getRDN().getAttributeValue(0).toString(); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | throw new IllegalStateException("Unexpected error with dn: '"+ |
| | | entryToDuplicate.getDN()+"' "+de, de); |
| | | } |
| | | for (Object value : values) |
| | | { |
| | | sb.append("\n"); |
| | | if (oldValue.equals(value)) |
| | | { |
| | | sb.append(attrName+": "+newValue); |
| | | } |
| | | else |
| | | { |
| | | sb.append(attrName+": "+value); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | private void browseClicked() |
| | | { |
| | | if (browseDlg == null) |
| | | { |
| | | browsePanel = new LDAPEntrySelectionPanel(); |
| | | browsePanel.setTitle(INFO_CTRL_PANEL_CHOOSE_PARENT_ENTRY_DN.get()); |
| | | browsePanel.setFilter( |
| | | LDAPEntrySelectionPanel.Filter.DEFAULT); |
| | | browsePanel.setMultipleSelection(false); |
| | | browsePanel.setInfo(getInfo()); |
| | | browseDlg = new GenericDialog(Utilities.getFrame(this), |
| | | browsePanel); |
| | | Utilities.centerGoldenMean(browseDlg, |
| | | Utilities.getParentDialog(this)); |
| | | browseDlg.setModal(true); |
| | | } |
| | | browseDlg.setVisible(true); |
| | | String[] dns = browsePanel.getDNs(); |
| | | if (dns.length > 0) |
| | | { |
| | | for (String dn : dns) |
| | | { |
| | | parentDN.setText(dn); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void readEntry(final BasicNode node) |
| | | { |
| | | final long t1 = System.currentTimeMillis(); |
| | | BackgroundTask<CustomSearchResult> task = |
| | | new BackgroundTask<CustomSearchResult>() |
| | | { |
| | | public CustomSearchResult processBackgroundTask() throws Throwable |
| | | { |
| | | InitialLdapContext ctx = |
| | | controller.findConnectionForDisplayedEntry(node); |
| | | LDAPEntryReader reader = new LDAPEntryReader(node.getDN(), ctx); |
| | | sleepIfRequired(700, t1); |
| | | return reader.processBackgroundTask(); |
| | | } |
| | | |
| | | public void backgroundTaskCompleted(CustomSearchResult sr, |
| | | Throwable throwable) |
| | | { |
| | | if (throwable != null) |
| | | { |
| | | Message title = INFO_CTRL_PANEL_ERROR_SEARCHING_ENTRY_TITLE.get(); |
| | | Message details = |
| | | ERR_CTRL_PANEL_ERROR_SEARCHING_ENTRY.get(node.getDN(), |
| | | throwable.toString()); |
| | | displayErrorMessage(title, details); |
| | | } |
| | | else |
| | | { |
| | | entryToDuplicate = sr; |
| | | try |
| | | { |
| | | DN dn = DN.decode(sr.getDN()); |
| | | rdnAttribute = dn.getRDN().getAttributeType(0).getNameOrOID(); |
| | | |
| | | updateDNValue(); |
| | | entryHasPasswordWarning.setVisible(hasPassword()); |
| | | displayMainPanel(); |
| | | setEnabledOK(true); |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | displayErrorMessage(INFO_CTRL_PANEL_ERROR_DIALOG_TITLE.get(), |
| | | de.getMessageObject()); |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | task.startBackgroundTask(); |
| | | } |
| | | |
| | | private void updateDNValue() |
| | | { |
| | | String value = name.getText().trim(); |
| | | if (value.length() > 0) |
| | | { |
| | | String rdn = Utilities.getRDNString(rdnAttribute, value); |
| | | dn.setText(rdn+","+parentDN.getText().trim()); |
| | | } |
| | | else |
| | | { |
| | | dn.setText(","+parentDN.getText().trim()); |
| | | } |
| | | } |
| | | |
| | | private boolean hasPassword() |
| | | { |
| | | return !entryToDuplicate.getAttributeValues( |
| | | ServerConstants.ATTR_USER_PASSWORD).isEmpty(); |
| | | } |
| | | |
| | | private void sleepIfRequired(long sleepTime, long startTime) |
| | | { |
| | | long tSleep = sleepTime - (System.currentTimeMillis() - startTime); |
| | | if (tSleep > 0) |
| | | { |
| | | try |
| | | { |
| | | Thread.sleep(tSleep); |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | } |
| | | } |
| | | } |
| | | } |