001/* 002 * Copyright 2009-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2009-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.protocol; 022 023 024 025import com.unboundid.asn1.ASN1Boolean; 026import com.unboundid.asn1.ASN1Buffer; 027import com.unboundid.asn1.ASN1BufferSequence; 028import com.unboundid.asn1.ASN1Element; 029import com.unboundid.asn1.ASN1OctetString; 030import com.unboundid.asn1.ASN1Sequence; 031import com.unboundid.asn1.ASN1StreamReader; 032import com.unboundid.asn1.ASN1StreamReaderSequence; 033import com.unboundid.ldap.sdk.Control; 034import com.unboundid.ldap.sdk.LDAPException; 035import com.unboundid.ldap.sdk.ModifyDNRequest; 036import com.unboundid.ldap.sdk.ResultCode; 037import com.unboundid.util.NotMutable; 038import com.unboundid.util.InternalUseOnly; 039import com.unboundid.util.ThreadSafety; 040import com.unboundid.util.ThreadSafetyLevel; 041 042import static com.unboundid.ldap.protocol.ProtocolMessages.*; 043import static com.unboundid.util.Debug.*; 044import static com.unboundid.util.StaticUtils.*; 045 046 047 048/** 049 * This class provides an implementation of an LDAP modify DN request protocol 050 * op. 051 */ 052@InternalUseOnly() 053@NotMutable() 054@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 055public final class ModifyDNRequestProtocolOp 056 implements ProtocolOp 057{ 058 /** 059 * The BER type for the newSuperior element. 060 */ 061 public static final byte TYPE_NEW_SUPERIOR = (byte) 0x80; 062 063 064 065 /** 066 * The serial version UID for this serializable class. 067 */ 068 private static final long serialVersionUID = 7514385089303489375L; 069 070 071 072 // The deleteOldRDN flag for this modify DN request. 073 private final boolean deleteOldRDN; 074 075 // The entry DN for this modify DN request. 076 private final String dn; 077 078 // The new RDN for this modify DN request. 079 private final String newRDN; 080 081 // The new superior DN for this modify DN request. 082 private final String newSuperiorDN; 083 084 085 086 /** 087 * Creates a new modify DN request protocol op with the provided information. 088 * 089 * @param dn The entry DN for this modify DN request. 090 * @param newRDN The new RDN for this modify DN request. 091 * @param deleteOldRDN Indicates whether to delete the old RDN values. 092 * @param newSuperiorDN The new superior DN for this modify DN request, or 093 * {@code null} if there is none. 094 */ 095 public ModifyDNRequestProtocolOp(final String dn, final String newRDN, 096 final boolean deleteOldRDN, 097 final String newSuperiorDN) 098 { 099 this.dn = dn; 100 this.newRDN = newRDN; 101 this.deleteOldRDN = deleteOldRDN; 102 this.newSuperiorDN = newSuperiorDN; 103 } 104 105 106 107 /** 108 * Creates a new modify DN request protocol op from the provided modify DN 109 * request object. 110 * 111 * @param request The modify DN request object to use to create this 112 * protocol op. 113 */ 114 public ModifyDNRequestProtocolOp(final ModifyDNRequest request) 115 { 116 dn = request.getDN(); 117 newRDN = request.getNewRDN(); 118 deleteOldRDN = request.deleteOldRDN(); 119 newSuperiorDN = request.getNewSuperiorDN(); 120 } 121 122 123 124 /** 125 * Creates a new modify DN request protocol op read from the provided ASN.1 126 * stream reader. 127 * 128 * @param reader The ASN.1 stream reader from which to read the modify DN 129 * request protocol op. 130 * 131 * @throws LDAPException If a problem occurs while reading or parsing the 132 * modify DN request. 133 */ 134 ModifyDNRequestProtocolOp(final ASN1StreamReader reader) 135 throws LDAPException 136 { 137 try 138 { 139 final ASN1StreamReaderSequence opSequence = reader.beginSequence(); 140 141 dn = reader.readString(); 142 newRDN = reader.readString(); 143 deleteOldRDN = reader.readBoolean(); 144 145 if (opSequence.hasMoreElements()) 146 { 147 newSuperiorDN = reader.readString(); 148 } 149 else 150 { 151 newSuperiorDN = null; 152 } 153 } 154 catch (Exception e) 155 { 156 debugException(e); 157 158 throw new LDAPException(ResultCode.DECODING_ERROR, 159 ERR_MODIFY_DN_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), e); 160 } 161 } 162 163 164 165 /** 166 * Retrieves the target entry DN for this modify DN request. 167 * 168 * @return The target entry DN for this modify DN request. 169 */ 170 public String getDN() 171 { 172 return dn; 173 } 174 175 176 177 /** 178 * Retrieves the new RDN for this modify DN request. 179 * 180 * @return The new RDN for this modify DN request. 181 */ 182 public String getNewRDN() 183 { 184 return newRDN; 185 } 186 187 188 189 /** 190 * Indicates whether to delete the old RDN values from the target entry. 191 * 192 * @return {@code true} if the old RDN values should be removed from the 193 * entry, or {@code false} if not. 194 */ 195 public boolean deleteOldRDN() 196 { 197 return deleteOldRDN; 198 } 199 200 201 202 /** 203 * Retrieves the new superior DN for this modify DN request, if any. 204 * 205 * @return The new superior DN for this modify DN request, or {@code null} if 206 * there is none. 207 */ 208 public String getNewSuperiorDN() 209 { 210 return newSuperiorDN; 211 } 212 213 214 215 /** 216 * {@inheritDoc} 217 */ 218 public byte getProtocolOpType() 219 { 220 return LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST; 221 } 222 223 224 225 /** 226 * {@inheritDoc} 227 */ 228 public ASN1Element encodeProtocolOp() 229 { 230 if (newSuperiorDN == null) 231 { 232 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST, 233 new ASN1OctetString(dn), 234 new ASN1OctetString(newRDN), 235 new ASN1Boolean(deleteOldRDN)); 236 } 237 else 238 { 239 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST, 240 new ASN1OctetString(dn), 241 new ASN1OctetString(newRDN), 242 new ASN1Boolean(deleteOldRDN), 243 new ASN1OctetString(TYPE_NEW_SUPERIOR, newSuperiorDN)); 244 } 245 } 246 247 248 249 /** 250 * Decodes the provided ASN.1 element as a modify DN request protocol op. 251 * 252 * @param element The ASN.1 element to be decoded. 253 * 254 * @return The decoded modify DN request protocol op. 255 * 256 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 257 * a modify DN request protocol op. 258 */ 259 public static ModifyDNRequestProtocolOp decodeProtocolOp( 260 final ASN1Element element) 261 throws LDAPException 262 { 263 try 264 { 265 final ASN1Element[] elements = 266 ASN1Sequence.decodeAsSequence(element).elements(); 267 final String dn = 268 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 269 final String newRDN = 270 ASN1OctetString.decodeAsOctetString(elements[1]).stringValue(); 271 final boolean deleteOldRDN = 272 ASN1Boolean.decodeAsBoolean(elements[2]).booleanValue(); 273 274 final String newSuperiorDN; 275 if (elements.length > 3) 276 { 277 newSuperiorDN = 278 ASN1OctetString.decodeAsOctetString(elements[3]).stringValue(); 279 } 280 else 281 { 282 newSuperiorDN = null; 283 } 284 285 return new ModifyDNRequestProtocolOp(dn, newRDN, deleteOldRDN, 286 newSuperiorDN); 287 } 288 catch (final Exception e) 289 { 290 debugException(e); 291 throw new LDAPException(ResultCode.DECODING_ERROR, 292 ERR_MODIFY_DN_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), 293 e); 294 } 295 } 296 297 298 299 /** 300 * {@inheritDoc} 301 */ 302 public void writeTo(final ASN1Buffer buffer) 303 { 304 final ASN1BufferSequence opSequence = 305 buffer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST); 306 buffer.addOctetString(dn); 307 buffer.addOctetString(newRDN); 308 buffer.addBoolean(deleteOldRDN); 309 310 if (newSuperiorDN != null) 311 { 312 buffer.addOctetString(TYPE_NEW_SUPERIOR, newSuperiorDN); 313 } 314 opSequence.end(); 315 } 316 317 318 319 /** 320 * Creates a modify DN request from this protocol op. 321 * 322 * @param controls The set of controls to include in the modify DN request. 323 * It may be empty or {@code null} if no controls should be 324 * included. 325 * 326 * @return The modify DN request that was created. 327 */ 328 public ModifyDNRequest toModifyDNRequest(final Control... controls) 329 { 330 return new ModifyDNRequest(dn, newRDN, deleteOldRDN, newSuperiorDN, 331 controls); 332 } 333 334 335 336 /** 337 * Retrieves a string representation of this protocol op. 338 * 339 * @return A string representation of this protocol op. 340 */ 341 @Override() 342 public String toString() 343 { 344 final StringBuilder buffer = new StringBuilder(); 345 toString(buffer); 346 return buffer.toString(); 347 } 348 349 350 351 /** 352 * {@inheritDoc} 353 */ 354 public void toString(final StringBuilder buffer) 355 { 356 buffer.append("ModifyDNRequestProtocolOp(dn='"); 357 buffer.append(dn); 358 buffer.append("', newRDN='"); 359 buffer.append(newRDN); 360 buffer.append("', deleteOldRDN="); 361 buffer.append(deleteOldRDN); 362 363 if (newSuperiorDN != null) 364 { 365 buffer.append(", newSuperiorDN='"); 366 buffer.append(newSuperiorDN); 367 buffer.append('\''); 368 } 369 370 buffer.append(')'); 371 } 372}