/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.tools.ldapdecoder.protocol; import java.io.PrintStream; import java.util.Date; import com.slamd.asn1.ASN1Boolean; import com.slamd.asn1.ASN1Element; import com.slamd.asn1.ASN1OctetString; import com.slamd.asn1.ASN1Sequence; /** * This class defines an LDAP modify DN request, which is used to alter the DN * of an entry in a directory server. * * * @author Neil A. Wilson */ public class ModifyDNRequest extends ProtocolOp { /** * The ASN.1 type that should be used for the newSuperior portion of the * modify DN request if it is provided. */ public static final byte NEW_SUPERIOR_TYPE = (byte) 0x80; // Indicates whether the old RDN value should be removed from the entry. private boolean deleteOldRDN; // The current DN of the entry to rename. private String dn; // The new RDN to use for the entry. private String newRDN; // The new parent to use for the entry. private String newSuperior; /** * Creates a new modify DN request with the provided information. * * @param dn The current DN for the entry. * @param newRDN The new RDN to use for the entry. * @param deleteOldRDN Indicates whether the old RDN value should be removed * from the entry. */ public ModifyDNRequest(String dn, String newRDN, boolean deleteOldRDN) { this.dn = dn; this.newRDN = newRDN; this.deleteOldRDN = deleteOldRDN; newSuperior = null; } /** * Creates a new modify DN request with the provided information. * * @param dn The current DN for the entry. * @param newRDN The new RDN to use for the entry. * @param deleteOldRDN Indicates whether the old RDN value should be removed * from the entry. * @param newSuperior The new parent to use for the entry. */ public ModifyDNRequest(String dn, String newRDN, boolean deleteOldRDN, String newSuperior) { this.dn = dn; this.newRDN = newRDN; this.deleteOldRDN = deleteOldRDN; this.newSuperior = newSuperior; } /** * Retrieves the current DN of the entry to rename. * * @return The current DN of the entry to rename. */ public String getDN() { return dn; } /** * Retrieves the new RDN to use for the entry. * * @return The new RDN to use for the entry. */ public String getNewRDN() { return newRDN; } /** * Indicates whether the old RDN value should be removed from the entry when * it is renamed. * * @return <CODE>true</CODE> if the old RDN value should be removed from the * entry, or <CODE>false</CODE> if not. */ public boolean deleteOldRDN() { return deleteOldRDN; } /** * Retrieves the new parent to use for the entry. * * @return The new parent to use for the entry. */ public String getNewSuperior() { return newSuperior; } /** * Encodes this protocol op to an ASN.1 element. * * @return The ASN.1 element containing the encoded protocol op. */ public ASN1Element encode() { ASN1Element[] modifyDNElements; if (newSuperior == null) { modifyDNElements = new ASN1Element[] { new ASN1OctetString(dn), new ASN1OctetString(newRDN), new ASN1Boolean(deleteOldRDN) }; } else { modifyDNElements = new ASN1Element[] { new ASN1OctetString(dn), new ASN1OctetString(newRDN), new ASN1Boolean(deleteOldRDN), new ASN1OctetString(NEW_SUPERIOR_TYPE, newSuperior) }; } return new ASN1Sequence(MODIFY_DN_REQUEST_TYPE, modifyDNElements); } /** * Decodes the provided ASN.1 element as a modify DN request protocol op. * * @param element The ASN.1 element to be decoded. * * @return The decoded modify DN request. * * @throws ProtocolException If a problem occurs while decoding the provided * ASN.1 element as a modify DN request. */ public static ModifyDNRequest decodeModifyDNRequest(ASN1Element element) throws ProtocolException { ASN1Element[] modifyDNElements; try { modifyDNElements = element.decodeAsSequence().getElements(); } catch (Exception e) { throw new ProtocolException("Unable to decode modify DN request sequence", e); } if ((modifyDNElements.length < 3) || (modifyDNElements.length > 4)) { throw new ProtocolException("There must be either 3 or 4 elements in a " + "modify DN request sequence"); } String dn; try { dn = modifyDNElements[0].decodeAsOctetString().getStringValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode entry DN for modify DN " + "request", e); } String newRDN; try { newRDN = modifyDNElements[1].decodeAsOctetString().getStringValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode new RDN for modify DN " + "request", e); } boolean deleteOldRDN; try { deleteOldRDN = modifyDNElements[2].decodeAsBoolean().getBooleanValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode deleteOldRDN for modify " + "DN request", e); } String newSuperior = null; if (modifyDNElements.length == 4) { try { newSuperior = modifyDNElements[3].decodeAsOctetString().getStringValue(); } catch (Exception e) { throw new ProtocolException("Unable to decode newSuperior for modify " + "DN request", e); } } return new ModifyDNRequest(dn, newRDN, deleteOldRDN, newSuperior); } /** * Retrieves a user-friendly name for this protocol op. * * @return A user-friendly name for this protocol op. */ public String getProtocolOpType() { return "LDAP Modify DN Request"; } /** * Retrieves a string representation of this protocol op with the specified * indent. * * @param indent The number of spaces to indent the output. * * @return A string representation of this protocol op with the specified * indent. */ public String toString(int indent) { StringBuilder indentBuf = new StringBuilder(indent); for (int i=0; i < indent; i++) { indentBuf.append(' '); } StringBuilder buffer = new StringBuilder(); buffer.append(indentBuf).append("Current Entry DN: ").append(dn). append(LDAPMessage.EOL); buffer.append(indentBuf).append("New RDN: ").append(newRDN). append(LDAPMessage.EOL); buffer.append(indentBuf).append("Delete Old RDN: "). append(deleteOldRDN).append(LDAPMessage.EOL); if (newSuperior != null) { buffer.append(indentBuf).append("New Superior: ").append(newSuperior). append(LDAPMessage.EOL); } return buffer.toString(); } /** * Constructs a string representation of this LDAP message in a form that can * be written to a SLAMD script. It may be empty if this message isn't one * that would be generated as part of a client request. * * @param scriptWriter The print stream to which the script contents should * be written. */ public void toSLAMDScript(PrintStream scriptWriter) { scriptWriter.println("#### Modify DN request captured at " + new Date()); scriptWriter.println("# Entry DN: " + dn); scriptWriter.println("# New RDN: " + newRDN); scriptWriter.println("# Delete Old RDN: " + deleteOldRDN); if ((newSuperior == null) || (newSuperior.length() == 0)) { scriptWriter.println("resultCode = conn.modifyRDN(\"" + dn + "\", \"" + newRDN + "\", " + deleteOldRDN + ");"); } else { scriptWriter.println("# New Superior: " + newSuperior); scriptWriter.println("# NOTE: The SLAMD scripting language does not " + "currently support modify DN with newSuperior."); } scriptWriter.println(); scriptWriter.println(); } }