/*
* 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-2010 Sun Microsystems, Inc.
* Portions Copyright 2012 ForgeRock AS
*/
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.List;
import javax.naming.ldap.InitialLdapContext;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
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 JLabel lPassword;
private JPasswordField password = Utilities.createPasswordField(25);
private JLabel lconfirmPassword;
private JPasswordField confirmPassword = Utilities.createPasswordField(25);
private JLabel lPasswordInfo;
private JButton browse;
private JLabel dn;
private GenericDialog browseDlg;
private LDAPEntrySelectionPanel browsePanel;
private CustomSearchResult entryToDuplicate;
private String rdnAttribute;
/**
* 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 aParentDN;
String aRdn;
try
{
DN nodeDN = DN.decode(node.getDN());
if (nodeDN.isNullDN())
{
aParentDN = nodeDN;
aRdn = "(1)";
}
else
{
aParentDN = nodeDN.getParent();
aRdn = nodeDN.getRDN().getAttributeValue(0).toString()+"-1";
}
}
catch (DirectoryException de)
{
throw new IllegalStateException("Unexpected error decoding dn: '"+
node.getDN()+"' error: "+de, de);
}
parentDN.setText(aParentDN.toString());
name.setText(aRdn);
password.setText("");
confirmPassword.setText("");
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.weighty = 0.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.weighty = 0.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.gridwidth = 1;
gbc.weightx = 0.0;
gbc.gridx = 0;
gbc.gridy ++;
gbc.insets.left = 0;
lPassword = Utilities.createPrimaryLabel(
INFO_CTRL_PANEL_DUPLICATE_ENTRY_NEWPASSWORD_LABEL.get());
add(lPassword, gbc);
gbc.weightx = 1.0;
gbc.gridwidth = 2;
gbc.weighty = 0.0;
gbc.insets.left = 10;
gbc.gridx = 1;
add(password, gbc);
gbc.gridwidth = 1;
gbc.weightx = 0.0;
gbc.gridx = 0;
gbc.gridy ++;
gbc.insets.left = 0;
lconfirmPassword = Utilities.createPrimaryLabel(
INFO_CTRL_PANEL_DUPLICATE_ENTRY_CONFIRMNEWPASSWORD_LABEL.get());
add(lconfirmPassword, gbc);
gbc.weightx = 1.0;
gbc.gridwidth = 2;
gbc.weighty = 0.0;
gbc.insets.left = 10;
gbc.gridx = 1;
add(confirmPassword, gbc);
gbc.gridx = 0;
gbc.gridy ++;
gbc.insets.left = 0;
lPasswordInfo = Utilities.createInlineHelpLabel(
INFO_CTRL_PANEL_DUPLICATE_ENTRY_PASSWORD_INFO.get());
gbc.gridwidth = 3;
add(lPasswordInfo, 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);
}
char[] pwd1 = password.getPassword();
char[] pwd2 = confirmPassword.getPassword();
String sPwd1 = new String(pwd1);
String sPwd2 = new String(pwd2);
if (!sPwd1.equals(sPwd2))
{
errors.add(ERR_CTRL_PANEL_PASSWORD_DO_NOT_MATCH.get());
}
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())
{
List<Object> values = entryToDuplicate.getAttributeValues(attrName);
if (attrName.equalsIgnoreCase(ServerConstants.ATTR_USER_PASSWORD))
{
sb.append("\n");
String pwd = new String(password.getPassword());
if (!pwd.isEmpty())
{
sb.append(attrName+": " + pwd);
}
}
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();
Boolean hasPassword = !sr.getAttributeValues(
ServerConstants.ATTR_USER_PASSWORD).isEmpty();
lPassword.setVisible(hasPassword);
password.setVisible(hasPassword);
lconfirmPassword.setVisible(hasPassword);
confirmPassword.setVisible(hasPassword);
lPasswordInfo.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 void sleepIfRequired(long sleepTime, long startTime)
{
long tSleep = sleepTime - (System.currentTimeMillis() - startTime);
if (tSleep > 0)
{
try
{
Thread.sleep(tSleep);
}
catch (Throwable t)
{
}
}
}
}