001/* 002 * Copyright 2009-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2009-2019 Ping Identity Corporation 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.Debug; 038import com.unboundid.util.InternalUseOnly; 039import com.unboundid.util.NotMutable; 040import com.unboundid.util.StaticUtils; 041import com.unboundid.util.ThreadSafety; 042import com.unboundid.util.ThreadSafetyLevel; 043 044import static com.unboundid.ldap.protocol.ProtocolMessages.*; 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 (final Exception e) 155 { 156 Debug.debugException(e); 157 158 throw new LDAPException(ResultCode.DECODING_ERROR, 159 ERR_MODIFY_DN_REQUEST_CANNOT_DECODE.get( 160 StaticUtils.getExceptionMessage(e)), 161 e); 162 } 163 } 164 165 166 167 /** 168 * Retrieves the target entry DN for this modify DN request. 169 * 170 * @return The target entry DN for this modify DN request. 171 */ 172 public String getDN() 173 { 174 return dn; 175 } 176 177 178 179 /** 180 * Retrieves the new RDN for this modify DN request. 181 * 182 * @return The new RDN for this modify DN request. 183 */ 184 public String getNewRDN() 185 { 186 return newRDN; 187 } 188 189 190 191 /** 192 * Indicates whether to delete the old RDN values from the target entry. 193 * 194 * @return {@code true} if the old RDN values should be removed from the 195 * entry, or {@code false} if not. 196 */ 197 public boolean deleteOldRDN() 198 { 199 return deleteOldRDN; 200 } 201 202 203 204 /** 205 * Retrieves the new superior DN for this modify DN request, if any. 206 * 207 * @return The new superior DN for this modify DN request, or {@code null} if 208 * there is none. 209 */ 210 public String getNewSuperiorDN() 211 { 212 return newSuperiorDN; 213 } 214 215 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override() 221 public byte getProtocolOpType() 222 { 223 return LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST; 224 } 225 226 227 228 /** 229 * {@inheritDoc} 230 */ 231 @Override() 232 public ASN1Element encodeProtocolOp() 233 { 234 if (newSuperiorDN == null) 235 { 236 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST, 237 new ASN1OctetString(dn), 238 new ASN1OctetString(newRDN), 239 new ASN1Boolean(deleteOldRDN)); 240 } 241 else 242 { 243 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST, 244 new ASN1OctetString(dn), 245 new ASN1OctetString(newRDN), 246 new ASN1Boolean(deleteOldRDN), 247 new ASN1OctetString(TYPE_NEW_SUPERIOR, newSuperiorDN)); 248 } 249 } 250 251 252 253 /** 254 * Decodes the provided ASN.1 element as a modify DN request protocol op. 255 * 256 * @param element The ASN.1 element to be decoded. 257 * 258 * @return The decoded modify DN request protocol op. 259 * 260 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 261 * a modify DN request protocol op. 262 */ 263 public static ModifyDNRequestProtocolOp decodeProtocolOp( 264 final ASN1Element element) 265 throws LDAPException 266 { 267 try 268 { 269 final ASN1Element[] elements = 270 ASN1Sequence.decodeAsSequence(element).elements(); 271 final String dn = 272 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 273 final String newRDN = 274 ASN1OctetString.decodeAsOctetString(elements[1]).stringValue(); 275 final boolean deleteOldRDN = 276 ASN1Boolean.decodeAsBoolean(elements[2]).booleanValue(); 277 278 final String newSuperiorDN; 279 if (elements.length > 3) 280 { 281 newSuperiorDN = 282 ASN1OctetString.decodeAsOctetString(elements[3]).stringValue(); 283 } 284 else 285 { 286 newSuperiorDN = null; 287 } 288 289 return new ModifyDNRequestProtocolOp(dn, newRDN, deleteOldRDN, 290 newSuperiorDN); 291 } 292 catch (final Exception e) 293 { 294 Debug.debugException(e); 295 throw new LDAPException(ResultCode.DECODING_ERROR, 296 ERR_MODIFY_DN_REQUEST_CANNOT_DECODE.get( 297 StaticUtils.getExceptionMessage(e)), 298 e); 299 } 300 } 301 302 303 304 /** 305 * {@inheritDoc} 306 */ 307 @Override() 308 public void writeTo(final ASN1Buffer buffer) 309 { 310 final ASN1BufferSequence opSequence = 311 buffer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_MODIFY_DN_REQUEST); 312 buffer.addOctetString(dn); 313 buffer.addOctetString(newRDN); 314 buffer.addBoolean(deleteOldRDN); 315 316 if (newSuperiorDN != null) 317 { 318 buffer.addOctetString(TYPE_NEW_SUPERIOR, newSuperiorDN); 319 } 320 opSequence.end(); 321 } 322 323 324 325 /** 326 * Creates a modify DN request from this protocol op. 327 * 328 * @param controls The set of controls to include in the modify DN request. 329 * It may be empty or {@code null} if no controls should be 330 * included. 331 * 332 * @return The modify DN request that was created. 333 */ 334 public ModifyDNRequest toModifyDNRequest(final Control... controls) 335 { 336 return new ModifyDNRequest(dn, newRDN, deleteOldRDN, newSuperiorDN, 337 controls); 338 } 339 340 341 342 /** 343 * Retrieves a string representation of this protocol op. 344 * 345 * @return A string representation of this protocol op. 346 */ 347 @Override() 348 public String toString() 349 { 350 final StringBuilder buffer = new StringBuilder(); 351 toString(buffer); 352 return buffer.toString(); 353 } 354 355 356 357 /** 358 * {@inheritDoc} 359 */ 360 @Override() 361 public void toString(final StringBuilder buffer) 362 { 363 buffer.append("ModifyDNRequestProtocolOp(dn='"); 364 buffer.append(dn); 365 buffer.append("', newRDN='"); 366 buffer.append(newRDN); 367 buffer.append("', deleteOldRDN="); 368 buffer.append(deleteOldRDN); 369 370 if (newSuperiorDN != null) 371 { 372 buffer.append(", newSuperiorDN='"); 373 buffer.append(newSuperiorDN); 374 buffer.append('\''); 375 } 376 377 buffer.append(')'); 378 } 379}