001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.protocols.ldap; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.ArrayList; 033 034 import org.opends.server.protocols.asn1.ASN1Boolean; 035 import org.opends.server.protocols.asn1.ASN1Element; 036 import org.opends.server.protocols.asn1.ASN1OctetString; 037 import org.opends.server.protocols.asn1.ASN1Sequence; 038 import org.opends.server.types.DebugLogLevel; 039 import org.opends.server.types.LDAPException; 040 041 import static org.opends.server.loggers.debug.DebugLogger.*; 042 import org.opends.server.loggers.debug.DebugTracer; 043 import static org.opends.messages.ProtocolMessages.*; 044 import static org.opends.server.protocols.ldap.LDAPConstants.*; 045 import static org.opends.server.protocols.ldap.LDAPResultCode.*; 046 import static org.opends.server.util.ServerConstants.*; 047 048 049 /** 050 * This class defines the structures and methods for an LDAP modify DN request 051 * protocol op, which is used to move or rename an entry or subtree within the 052 * Directory Server. 053 */ 054 public class ModifyDNRequestProtocolOp 055 extends ProtocolOp 056 { 057 /** 058 * The tracer object for the debug logger. 059 */ 060 private static final DebugTracer TRACER = getTracer(); 061 062 // The current entry DN for this modify DN request. 063 private ASN1OctetString entryDN; 064 065 // The new RDN for this modify DN request. 066 private ASN1OctetString newRDN; 067 068 // The new superior DN for this modify DN request. 069 private ASN1OctetString newSuperior; 070 071 // Indicates whether to delete the current RDN value(s). 072 private boolean deleteOldRDN; 073 074 075 076 /** 077 * Creates a new modify DN request protocol op with the provided information. 078 * 079 * @param entryDN The current entry DN for this modify DN request. 080 * @param newRDN The new RDN for this modify DN request. 081 * @param deleteOldRDN Indicates whether to delete the current RDN value(s). 082 */ 083 public ModifyDNRequestProtocolOp(ASN1OctetString entryDN, 084 ASN1OctetString newRDN, boolean deleteOldRDN) 085 { 086 this.entryDN = entryDN; 087 this.newRDN = newRDN; 088 this.deleteOldRDN = deleteOldRDN; 089 this.newSuperior = null; 090 } 091 092 093 094 /** 095 * Creates a new modify DN request protocol op with the provided information. 096 * 097 * @param entryDN The current entry DN for this modify DN request. 098 * @param newRDN The new RDN for this modify DN request. 099 * @param deleteOldRDN Indicates whether to delete the current RDN value(s). 100 * @param newSuperior The new superior DN for this modify DN request. 101 */ 102 public ModifyDNRequestProtocolOp(ASN1OctetString entryDN, 103 ASN1OctetString newRDN, boolean deleteOldRDN, 104 ASN1OctetString newSuperior) 105 { 106 this.entryDN = entryDN; 107 this.newRDN = newRDN; 108 this.deleteOldRDN = deleteOldRDN; 109 this.newSuperior = newSuperior; 110 } 111 112 113 114 /** 115 * Retrieves the current entry DN for this modify DN request. 116 * 117 * @return The current entry DN for this modify DN request. 118 */ 119 public ASN1OctetString getEntryDN() 120 { 121 return entryDN; 122 } 123 124 125 126 /** 127 * Specifies the current entry DN for this modify DN request. 128 * 129 * @param entryDN The current entry DN for this modify DN request. 130 */ 131 public void setEntryDN(ASN1OctetString entryDN) 132 { 133 this.entryDN = entryDN; 134 } 135 136 137 138 /** 139 * Retrieves the new RDN for this modify DN request. 140 * 141 * @return The new RDN for this modify DN request. 142 */ 143 public ASN1OctetString getNewRDN() 144 { 145 return newRDN; 146 } 147 148 149 150 /** 151 * Specifies the new RDN for this modify DN request. 152 * 153 * @param newRDN The new RDN for this modify DN request. 154 */ 155 public void setNewRDN(ASN1OctetString newRDN) 156 { 157 this.newRDN = newRDN; 158 } 159 160 161 162 /** 163 * Indicates whether the current RDN value(s) should be deleted. 164 * 165 * @return <CODE>true</CODE> if the current RDN value(s) should be deleted, 166 * or <CODE>false</CODE> if not. 167 */ 168 public boolean deleteOldRDN() 169 { 170 return deleteOldRDN; 171 } 172 173 174 175 /** 176 * Specifies whether the current RDN value(s) should be deleted. 177 * 178 * @param deleteOldRDN Specifies whether the current RDN value(s) should be 179 * deleted. 180 */ 181 public void setDeleteOldRDN(boolean deleteOldRDN) 182 { 183 this.deleteOldRDN = deleteOldRDN; 184 } 185 186 187 188 /** 189 * Retrieves the new superior DN for this modify DN request. 190 * 191 * @return The new superior DN for this modify DN request, or 192 * <CODE>null</CODE> if none was provided. 193 */ 194 public ASN1OctetString getNewSuperior() 195 { 196 return newSuperior; 197 } 198 199 200 201 /** 202 * Specifies the new superior DN for this modify DN request. 203 * 204 * @param newSuperior The new superior DN for this modify DN request. 205 */ 206 public void setNewSuperior(ASN1OctetString newSuperior) 207 { 208 this.newSuperior = newSuperior; 209 } 210 211 212 213 /** 214 * Retrieves the BER type for this protocol op. 215 * 216 * @return The BER type for this protocol op. 217 */ 218 public byte getType() 219 { 220 return OP_TYPE_MODIFY_DN_REQUEST; 221 } 222 223 224 225 /** 226 * Retrieves the name for this protocol op type. 227 * 228 * @return The name for this protocol op type. 229 */ 230 public String getProtocolOpName() 231 { 232 return "Modify DN Request"; 233 } 234 235 236 237 /** 238 * Encodes this protocol op to an ASN.1 element suitable for including in an 239 * LDAP message. 240 * 241 * @return The ASN.1 element containing the encoded protocol op. 242 */ 243 public ASN1Element encode() 244 { 245 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(4); 246 elements.add(entryDN); 247 elements.add(newRDN); 248 elements.add(new ASN1Boolean(deleteOldRDN)); 249 250 if (newSuperior != null) 251 { 252 newSuperior.setType(TYPE_MODIFY_DN_NEW_SUPERIOR); 253 elements.add(newSuperior); 254 } 255 256 return new ASN1Sequence(OP_TYPE_MODIFY_DN_REQUEST, elements); 257 } 258 259 260 261 /** 262 * Decodes the provided ASN.1 element as a modify DN request protocol op. 263 * 264 * @param element The ASN.1 element to decode. 265 * 266 * @return The decoded modify DN request protocol op. 267 * 268 * @throws LDAPException If a problem occurs while trying to decode the 269 * provided ASN.1 element as an LDAP modify DN request 270 * protocol op. 271 */ 272 public static ModifyDNRequestProtocolOp decodeModifyDNRequest(ASN1Element 273 element) 274 throws LDAPException 275 { 276 ArrayList<ASN1Element> elements; 277 try 278 { 279 elements = element.decodeAsSequence().elements(); 280 } 281 catch (Exception e) 282 { 283 if (debugEnabled()) 284 { 285 TRACER.debugCaught(DebugLogLevel.ERROR, e); 286 } 287 288 Message message = 289 ERR_LDAP_MODIFY_DN_REQUEST_DECODE_SEQUENCE.get(String.valueOf(e)); 290 throw new LDAPException(PROTOCOL_ERROR, message, e); 291 } 292 293 294 int numElements = elements.size(); 295 if ((numElements < 3) || (numElements > 4)) 296 { 297 Message message = ERR_LDAP_MODIFY_DN_REQUEST_DECODE_INVALID_ELEMENT_COUNT. 298 get(numElements); 299 throw new LDAPException(PROTOCOL_ERROR, message); 300 } 301 302 303 ASN1OctetString entryDN; 304 try 305 { 306 entryDN = elements.get(0).decodeAsOctetString(); 307 } 308 catch (Exception e) 309 { 310 if (debugEnabled()) 311 { 312 TRACER.debugCaught(DebugLogLevel.ERROR, e); 313 } 314 315 Message message = 316 ERR_LDAP_MODIFY_DN_REQUEST_DECODE_DN.get(String.valueOf(e)); 317 throw new LDAPException(PROTOCOL_ERROR, message, e); 318 } 319 320 321 ASN1OctetString newRDN; 322 try 323 { 324 newRDN = elements.get(1).decodeAsOctetString(); 325 } 326 catch (Exception e) 327 { 328 if (debugEnabled()) 329 { 330 TRACER.debugCaught(DebugLogLevel.ERROR, e); 331 } 332 333 Message message = 334 ERR_LDAP_MODIFY_DN_REQUEST_DECODE_NEW_RDN.get(String.valueOf(e)); 335 throw new LDAPException(PROTOCOL_ERROR, message, e); 336 } 337 338 339 boolean deleteOldRDN; 340 try 341 { 342 deleteOldRDN = elements.get(2).decodeAsBoolean().booleanValue(); 343 } 344 catch (Exception e) 345 { 346 if (debugEnabled()) 347 { 348 TRACER.debugCaught(DebugLogLevel.ERROR, e); 349 } 350 351 Message message = ERR_LDAP_MODIFY_DN_REQUEST_DECODE_DELETE_OLD_RDN.get( 352 String.valueOf(e)); 353 throw new LDAPException(PROTOCOL_ERROR, message, e); 354 } 355 356 357 ASN1OctetString newSuperior; 358 if (numElements == 4) 359 { 360 try 361 { 362 newSuperior = elements.get(3).decodeAsOctetString(); 363 } 364 catch (Exception e) 365 { 366 if (debugEnabled()) 367 { 368 TRACER.debugCaught(DebugLogLevel.ERROR, e); 369 } 370 371 Message message = ERR_LDAP_MODIFY_DN_REQUEST_DECODE_NEW_SUPERIOR.get( 372 String.valueOf(e)); 373 throw new LDAPException(PROTOCOL_ERROR, message, e); 374 } 375 } 376 else 377 { 378 newSuperior = null; 379 } 380 381 382 return new ModifyDNRequestProtocolOp(entryDN, newRDN, deleteOldRDN, 383 newSuperior); 384 } 385 386 387 388 /** 389 * Appends a string representation of this LDAP protocol op to the provided 390 * buffer. 391 * 392 * @param buffer The buffer to which the string should be appended. 393 */ 394 public void toString(StringBuilder buffer) 395 { 396 buffer.append("ModifyDNRequest(dn="); 397 entryDN.toString(buffer); 398 buffer.append(", newRDN="); 399 newRDN.toString(buffer); 400 buffer.append(", deleteOldRDN="); 401 buffer.append(deleteOldRDN); 402 403 if (newSuperior != null) 404 { 405 buffer.append(", newSuperior="); 406 newSuperior.toString(buffer); 407 } 408 409 buffer.append(")"); 410 } 411 412 413 414 /** 415 * Appends a multi-line string representation of this LDAP protocol op to the 416 * provided buffer. 417 * 418 * @param buffer The buffer to which the information should be appended. 419 * @param indent The number of spaces from the margin that the lines should 420 * be indented. 421 */ 422 public void toString(StringBuilder buffer, int indent) 423 { 424 StringBuilder indentBuf = new StringBuilder(indent); 425 for (int i=0 ; i < indent; i++) 426 { 427 indentBuf.append(' '); 428 } 429 430 buffer.append(indentBuf); 431 buffer.append("Modify DN Request"); 432 buffer.append(EOL); 433 434 buffer.append(indentBuf); 435 buffer.append(" Entry DN: "); 436 entryDN.toString(buffer); 437 buffer.append(EOL); 438 439 buffer.append(indentBuf); 440 buffer.append(" New RDN: "); 441 newRDN.toString(buffer); 442 buffer.append(EOL); 443 444 buffer.append(indentBuf); 445 buffer.append(" Delete Old RDN: "); 446 buffer.append(deleteOldRDN); 447 buffer.append(EOL); 448 449 if (newSuperior != null) 450 { 451 buffer.append(indentBuf); 452 buffer.append(" New Superior: "); 453 newSuperior.toString(buffer); 454 buffer.append(EOL); 455 } 456 } 457 } 458