001 /*
002 * Copyright 2007-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2013 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 */
021 package com.unboundid.ldif;
022
023
024
025 import java.util.Arrays;
026 import java.util.List;
027
028 import com.unboundid.asn1.ASN1OctetString;
029 import com.unboundid.ldap.sdk.ChangeType;
030 import com.unboundid.ldap.sdk.DN;
031 import com.unboundid.ldap.sdk.LDAPException;
032 import com.unboundid.ldap.sdk.LDAPInterface;
033 import com.unboundid.ldap.sdk.LDAPResult;
034 import com.unboundid.ldap.sdk.ModifyDNRequest;
035 import com.unboundid.ldap.sdk.RDN;
036 import com.unboundid.util.ByteStringBuffer;
037 import com.unboundid.util.NotMutable;
038 import com.unboundid.util.ThreadSafety;
039 import com.unboundid.util.ThreadSafetyLevel;
040
041 import static com.unboundid.util.Debug.*;
042 import static com.unboundid.util.StaticUtils.*;
043 import static com.unboundid.util.Validator.*;
044
045
046
047 /**
048 * This class defines an LDIF modify DN change record, which can be used to
049 * represent an LDAP modify DN request. See the documentation for the
050 * {@link LDIFChangeRecord} class for an example demonstrating the process for
051 * interacting with LDIF change records.
052 */
053 @NotMutable()
054 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
055 public final class LDIFModifyDNChangeRecord
056 extends LDIFChangeRecord
057 {
058 /**
059 * The serial version UID for this serializable class.
060 */
061 private static final long serialVersionUID = -2356367870035948998L;
062
063
064
065 // Indicates whether to delete the current RDN value.
066 private final boolean deleteOldRDN;
067
068 // The parsed new superior DN for the entry.
069 private volatile DN parsedNewSuperiorDN;
070
071 // The parsed new RDN for the entry.
072 private volatile RDN parsedNewRDN;
073
074 // The new RDN value for the entry.
075 private final String newRDN;
076
077 // The new superior DN for the entry, if available.
078 private final String newSuperiorDN;
079
080
081
082 /**
083 * Creates a new LDIF modify DN change record with the provided information.
084 *
085 * @param dn The current DN for the entry. It must not be
086 * {@code null}.
087 * @param newRDN The new RDN value for the entry. It must not be
088 * {@code null}.
089 * @param deleteOldRDN Indicates whether to delete the currentRDN value
090 * from the entry.
091 * @param newSuperiorDN The new superior DN for this LDIF modify DN change
092 * record. It may be {@code null} if the entry is not
093 * to be moved below a new parent.
094 */
095 public LDIFModifyDNChangeRecord(final String dn, final String newRDN,
096 final boolean deleteOldRDN,
097 final String newSuperiorDN)
098 {
099 super(dn);
100
101 ensureNotNull(newRDN);
102
103 this.newRDN = newRDN;
104 this.deleteOldRDN = deleteOldRDN;
105 this.newSuperiorDN = newSuperiorDN;
106 }
107
108
109
110 /**
111 * Creates a new LDIF modify DN change record from the provided modify DN
112 * request.
113 *
114 * @param modifyDNRequest The modify DN request to use to create this LDIF
115 * modify DN change record. It must not be
116 * {@code null}.
117 */
118 public LDIFModifyDNChangeRecord(final ModifyDNRequest modifyDNRequest)
119 {
120 super(modifyDNRequest.getDN());
121
122 newRDN = modifyDNRequest.getNewRDN();
123 deleteOldRDN = modifyDNRequest.deleteOldRDN();
124 newSuperiorDN = modifyDNRequest.getNewSuperiorDN();
125 }
126
127
128
129 /**
130 * Retrieves the new RDN value for the entry.
131 *
132 * @return The new RDN value for the entry.
133 */
134 public String getNewRDN()
135 {
136 return newRDN;
137 }
138
139
140
141 /**
142 * Retrieves the parsed new RDN value for the entry.
143 *
144 * @return The parsed new RDN value for the entry.
145 *
146 * @throws LDAPException If a problem occurs while trying to parse the new
147 * RDN.
148 */
149 public RDN getParsedNewRDN()
150 throws LDAPException
151 {
152 if (parsedNewRDN == null)
153 {
154 parsedNewRDN = new RDN(newRDN);
155 }
156
157 return parsedNewRDN;
158 }
159
160
161
162 /**
163 * Indicates whether to delete the current RDN value from the entry.
164 *
165 * @return {@code true} if the current RDN value should be removed from the
166 * entry, or {@code false} if not.
167 */
168 public boolean deleteOldRDN()
169 {
170 return deleteOldRDN;
171 }
172
173
174
175 /**
176 * Retrieves the new superior DN for the entry, if applicable.
177 *
178 * @return The new superior DN for the entry, or {@code null} if the entry is
179 * not to be moved below a new parent.
180 */
181 public String getNewSuperiorDN()
182 {
183 return newSuperiorDN;
184 }
185
186
187
188 /**
189 * Retrieves the parsed new superior DN for the entry, if applicable.
190 *
191 * @return The parsed new superior DN for the entry, or {@code null} if the
192 * entry is not to be moved below a new parent.
193 *
194 * @throws LDAPException If a problem occurs while trying to parse the new
195 * superior DN.
196 */
197 public DN getParsedNewSuperiorDN()
198 throws LDAPException
199 {
200 if ((parsedNewSuperiorDN == null) && (newSuperiorDN != null))
201 {
202 parsedNewSuperiorDN = new DN(newSuperiorDN);
203 }
204
205 return parsedNewSuperiorDN;
206 }
207
208
209
210 /**
211 * Retrieves the DN that the entry should have after the successful completion
212 * of the operation.
213 *
214 * @return The DN that the entry should have after the successful completion
215 * of the operation.
216 *
217 * @throws LDAPException If a problem occurs while trying to parse the
218 * target DN, new RDN, or new superior DN.
219 */
220 public DN getNewDN()
221 throws LDAPException
222 {
223 if (newSuperiorDN == null)
224 {
225 final DN parentDN = getParsedDN().getParent();
226 if (parentDN == null)
227 {
228 return new DN(getParsedNewRDN());
229 }
230 else
231 {
232 return new DN(getParsedNewRDN(), parentDN);
233 }
234 }
235 else
236 {
237 return new DN(getParsedNewRDN(), getParsedNewSuperiorDN());
238 }
239 }
240
241
242
243 /**
244 * Creates a modify DN request from this LDIF modify DN change record.
245 *
246 * @return The modify DN request created from this LDIF modify DN change
247 * record.
248 */
249 public ModifyDNRequest toModifyDNRequest()
250 {
251 return new ModifyDNRequest(getDN(), newRDN, deleteOldRDN, newSuperiorDN);
252 }
253
254
255
256 /**
257 * {@inheritDoc}
258 */
259 @Override()
260 public ChangeType getChangeType()
261 {
262 return ChangeType.MODIFY_DN;
263 }
264
265
266
267 /**
268 * {@inheritDoc}
269 */
270 @Override()
271 public LDAPResult processChange(final LDAPInterface connection)
272 throws LDAPException
273 {
274 return connection.modifyDN(toModifyDNRequest());
275 }
276
277
278
279 /**
280 * {@inheritDoc}
281 */
282 @Override()
283 public String[] toLDIF(final int wrapColumn)
284 {
285 List<String> ldifLines;
286
287 if (newSuperiorDN == null)
288 {
289 ldifLines = Arrays.asList(
290 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN())),
291 "changetype: moddn",
292 LDIFWriter.encodeNameAndValue("newrdn", new ASN1OctetString(newRDN)),
293 "deleteoldrdn: " + (deleteOldRDN ? "1" : "0"));
294 }
295 else
296 {
297 ldifLines = Arrays.asList(
298 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN())),
299 "changetype: moddn",
300 LDIFWriter.encodeNameAndValue("newrdn", new ASN1OctetString(newRDN)),
301 "deleteoldrdn: " + (deleteOldRDN ? "1" : "0"),
302 LDIFWriter.encodeNameAndValue("newsuperior",
303 new ASN1OctetString(newSuperiorDN)));
304 }
305
306 if (wrapColumn > 2)
307 {
308 ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines);
309 }
310
311 final String[] lineArray = new String[ldifLines.size()];
312 return ldifLines.toArray(lineArray);
313 }
314
315
316
317 /**
318 * {@inheritDoc}
319 */
320 @Override()
321 public void toLDIF(final ByteStringBuffer buffer, final int wrapColumn)
322 {
323 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
324 wrapColumn);
325 buffer.append(EOL_BYTES);
326
327 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("moddn"),
328 buffer, wrapColumn);
329 buffer.append(EOL_BYTES);
330
331 LDIFWriter.encodeNameAndValue("newrdn", new ASN1OctetString(newRDN), buffer,
332 wrapColumn);
333 buffer.append(EOL_BYTES);
334
335 if (deleteOldRDN)
336 {
337 LDIFWriter.encodeNameAndValue("deleteoldrdn", new ASN1OctetString("1"),
338 buffer, wrapColumn);
339 }
340 else
341 {
342 LDIFWriter.encodeNameAndValue("deleteoldrdn", new ASN1OctetString("0"),
343 buffer, wrapColumn);
344 }
345 buffer.append(EOL_BYTES);
346
347 if (newSuperiorDN != null)
348 {
349 LDIFWriter.encodeNameAndValue("newsuperior",
350 new ASN1OctetString(newSuperiorDN), buffer,
351 wrapColumn);
352 buffer.append(EOL_BYTES);
353 }
354 }
355
356
357
358 /**
359 * {@inheritDoc}
360 */
361 @Override()
362 public void toLDIFString(final StringBuilder buffer, final int wrapColumn)
363 {
364 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
365 wrapColumn);
366 buffer.append(EOL);
367
368 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("moddn"),
369 buffer, wrapColumn);
370 buffer.append(EOL);
371
372 LDIFWriter.encodeNameAndValue("newrdn", new ASN1OctetString(newRDN), buffer,
373 wrapColumn);
374 buffer.append(EOL);
375
376 if (deleteOldRDN)
377 {
378 LDIFWriter.encodeNameAndValue("deleteoldrdn", new ASN1OctetString("1"),
379 buffer, wrapColumn);
380 }
381 else
382 {
383 LDIFWriter.encodeNameAndValue("deleteoldrdn", new ASN1OctetString("0"),
384 buffer, wrapColumn);
385 }
386 buffer.append(EOL);
387
388 if (newSuperiorDN != null)
389 {
390 LDIFWriter.encodeNameAndValue("newsuperior",
391 new ASN1OctetString(newSuperiorDN), buffer,
392 wrapColumn);
393 buffer.append(EOL);
394 }
395 }
396
397
398
399 /**
400 * {@inheritDoc}
401 */
402 @Override()
403 public int hashCode()
404 {
405 int hashCode;
406 try
407 {
408 hashCode = getParsedDN().hashCode() + getParsedNewRDN().hashCode();
409 if (newSuperiorDN != null)
410 {
411 hashCode += getParsedNewSuperiorDN().hashCode();
412 }
413 }
414 catch (Exception e)
415 {
416 debugException(e);
417 hashCode = toLowerCase(getDN()).hashCode() +
418 toLowerCase(newRDN).hashCode();
419 if (newSuperiorDN != null)
420 {
421 hashCode += toLowerCase(newSuperiorDN).hashCode();
422 }
423 }
424
425 if (deleteOldRDN)
426 {
427 hashCode++;
428 }
429
430 return hashCode;
431 }
432
433
434
435 /**
436 * {@inheritDoc}
437 */
438 @Override()
439 public boolean equals(final Object o)
440 {
441 if (o == null)
442 {
443 return false;
444 }
445
446 if (o == this)
447 {
448 return true;
449 }
450
451 if (! (o instanceof LDIFModifyDNChangeRecord))
452 {
453 return false;
454 }
455
456 final LDIFModifyDNChangeRecord r = (LDIFModifyDNChangeRecord) o;
457
458 try
459 {
460 if (! getParsedDN().equals(r.getParsedDN()))
461 {
462 return false;
463 }
464 }
465 catch (Exception e)
466 {
467 debugException(e);
468 if (! toLowerCase(getDN()).equals(toLowerCase(r.getDN())))
469 {
470 return false;
471 }
472 }
473
474 try
475 {
476 if (! getParsedNewRDN().equals(r.getParsedNewRDN()))
477 {
478 return false;
479 }
480 }
481 catch (Exception e)
482 {
483 debugException(e);
484 if (! toLowerCase(newRDN).equals(toLowerCase(r.newRDN)))
485 {
486 return false;
487 }
488 }
489
490 if (newSuperiorDN == null)
491 {
492 if (r.newSuperiorDN != null)
493 {
494 return false;
495 }
496 }
497 else
498 {
499 if (r.newSuperiorDN == null)
500 {
501 return false;
502 }
503
504 try
505 {
506 if (! getParsedNewSuperiorDN().equals(r.getParsedNewSuperiorDN()))
507 {
508 return false;
509 }
510 }
511 catch (Exception e)
512 {
513 debugException(e);
514 if (! toLowerCase(newSuperiorDN).equals(toLowerCase(r.newSuperiorDN)))
515 {
516 return false;
517 }
518 }
519 }
520
521 return (deleteOldRDN == r.deleteOldRDN);
522 }
523
524
525
526 /**
527 * {@inheritDoc}
528 */
529 @Override()
530 public void toString(final StringBuilder buffer)
531 {
532 buffer.append("LDIFModifyDNChangeRecord(dn='");
533 buffer.append(getDN());
534 buffer.append("', newRDN='");
535 buffer.append(newRDN);
536 buffer.append("', deleteOldRDN=");
537 buffer.append(deleteOldRDN);
538
539 if (newSuperiorDN != null)
540 {
541 buffer.append(", newSuperiorDN='");
542 buffer.append(newSuperiorDN);
543 buffer.append('\'');
544 }
545
546 buffer.append(')');
547 }
548 }