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