001 /*
002 * Copyright 2007-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-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 */
021 package com.unboundid.ldif;
022
023
024
025 import java.util.ArrayList;
026 import java.util.Collection;
027 import java.util.HashSet;
028 import java.util.Iterator;
029 import java.util.List;
030
031 import com.unboundid.asn1.ASN1OctetString;
032 import com.unboundid.ldap.sdk.AddRequest;
033 import com.unboundid.ldap.sdk.Attribute;
034 import com.unboundid.ldap.sdk.ChangeType;
035 import com.unboundid.ldap.sdk.Control;
036 import com.unboundid.ldap.sdk.Entry;
037 import com.unboundid.ldap.sdk.LDAPException;
038 import com.unboundid.ldap.sdk.LDAPInterface;
039 import com.unboundid.ldap.sdk.LDAPResult;
040 import com.unboundid.util.ByteStringBuffer;
041
042 import static com.unboundid.util.Debug.*;
043 import static com.unboundid.util.StaticUtils.*;
044 import static com.unboundid.util.Validator.*;
045
046
047
048 /**
049 * This class defines an LDIF add change record, which can be used to represent
050 * an LDAP add request. See the documentation for the {@code LDIFChangeRecord}
051 * class for an example demonstrating the process for interacting with LDIF
052 * change records.
053 */
054 public final class LDIFAddChangeRecord
055 extends LDIFChangeRecord
056 {
057 /**
058 * The serial version UID for this serializable class.
059 */
060 private static final long serialVersionUID = 4722916031463878423L;
061
062
063
064 // The set of attributes for this add change record.
065 private final Attribute[] attributes;
066
067
068
069 /**
070 * Creates a new LDIF add change record with the provided DN and attributes.
071 *
072 * @param dn The DN for this LDIF add change record. It must not be
073 * {@code null}.
074 * @param attributes The set of attributes for this LDIF add change record.
075 * It must not be {@code null} or empty.
076 */
077 public LDIFAddChangeRecord(final String dn, final Attribute... attributes)
078 {
079 this(dn, attributes, null);
080 }
081
082
083
084 /**
085 * Creates a new LDIF add change record with the provided DN and attributes.
086 *
087 * @param dn The DN for this LDIF add change record. It must not be
088 * {@code null}.
089 * @param attributes The set of attributes for this LDIF add change record.
090 * It must not be {@code null} or empty.
091 * @param controls The set of controls for this LDIF add change record.
092 * It may be {@code null} or empty if there are no
093 * controls.
094 */
095 public LDIFAddChangeRecord(final String dn, final Attribute[] attributes,
096 final List<Control> controls)
097 {
098 super(dn, controls);
099
100 ensureNotNull(attributes);
101 ensureTrue(attributes.length > 0,
102 "LDIFAddChangeRecord.attributes must not be empty.");
103
104 this.attributes = attributes;
105 }
106
107
108
109 /**
110 * Creates a new LDIF add change record with the provided DN and attributes.
111 *
112 * @param dn The DN for this LDIF add change record. It must not be
113 * {@code null}.
114 * @param attributes The set of attributes for this LDIF add change record.
115 * It must not be {@code null} or empty.
116 */
117 public LDIFAddChangeRecord(final String dn, final List<Attribute> attributes)
118 {
119 this(dn, attributes, null);
120 }
121
122
123
124 /**
125 * Creates a new LDIF add change record with the provided DN and attributes.
126 *
127 * @param dn The DN for this LDIF add change record. It must not be
128 * {@code null}.
129 * @param attributes The set of attributes for this LDIF add change record.
130 * It must not be {@code null} or empty.
131 * @param controls The set of controls for this LDIF add change record.
132 * It may be {@code null} or empty if there are no
133 * controls.
134 */
135 public LDIFAddChangeRecord(final String dn, final List<Attribute> attributes,
136 final List<Control> controls)
137 {
138 super(dn, controls);
139
140 ensureNotNull(attributes);
141 ensureFalse(attributes.isEmpty(),
142 "LDIFAddChangeRecord.attributes must not be empty.");
143
144 this.attributes = new Attribute[attributes.size()];
145 attributes.toArray(this.attributes);
146 }
147
148
149
150 /**
151 * Creates a new LDIF add change record from the provided entry.
152 *
153 * @param entry The entry to use to create this LDIF add change record. It
154 * must not be {@code null}.
155 */
156 public LDIFAddChangeRecord(final Entry entry)
157 {
158 this(entry, null);
159 }
160
161
162
163 /**
164 * Creates a new LDIF add change record from the provided entry.
165 *
166 * @param entry The entry to use to create this LDIF add change record.
167 * It must not be {@code null}.
168 * @param controls The set of controls for this LDIF add change record. It
169 * may be {@code null} or empty if there are no controls.
170 */
171 public LDIFAddChangeRecord(final Entry entry, final List<Control> controls)
172 {
173 super(entry.getDN(), controls);
174
175 final Collection<Attribute> attrs = entry.getAttributes();
176 attributes = new Attribute[attrs.size()];
177
178 final Iterator<Attribute> iterator = attrs.iterator();
179 for (int i=0; i < attributes.length; i++)
180 {
181 attributes[i] = iterator.next();
182 }
183 }
184
185
186
187 /**
188 * Creates a new LDIF add change record from the provided add request.
189 *
190 * @param addRequest The add request to use to create this LDIF add change
191 * record. It must not be {@code null}.
192 */
193 public LDIFAddChangeRecord(final AddRequest addRequest)
194 {
195 super(addRequest.getDN(), addRequest.getControlList());
196
197 final List<Attribute> attrs = addRequest.getAttributes();
198 attributes = new Attribute[attrs.size()];
199
200 final Iterator<Attribute> iterator = attrs.iterator();
201 for (int i=0; i < attributes.length; i++)
202 {
203 attributes[i] = iterator.next();
204 }
205 }
206
207
208
209 /**
210 * Retrieves the set of attributes for this add change record.
211 *
212 * @return The set of attributes for this add change record.
213 */
214 public Attribute[] getAttributes()
215 {
216 return attributes;
217 }
218
219
220
221 /**
222 * Retrieves the entry that would be created by this add change record.
223 *
224 * @return The entry that would be created by this add change record.
225 */
226 public Entry getEntryToAdd()
227 {
228 return new Entry(getDN(), attributes);
229 }
230
231
232
233 /**
234 * Creates an add request from this LDIF add change record. Any controls
235 * included in this change record will be included in the request.
236 *
237 * @return The add request created from this LDIF add change record.
238 */
239 public AddRequest toAddRequest()
240 {
241 return toAddRequest(true);
242 }
243
244
245
246 /**
247 * Creates an add request from this LDIF add change record, optionally
248 * including any change record controls in the request.
249 *
250 * @param includeControls Indicates whether to include any controls in the
251 * request.
252 *
253 * @return The add request created from this LDIF add change record.
254 */
255 public AddRequest toAddRequest(final boolean includeControls)
256 {
257 final AddRequest addRequest = new AddRequest(getDN(), attributes);
258 if (includeControls)
259 {
260 addRequest.setControls(getControls());
261 }
262
263 return addRequest;
264 }
265
266
267
268 /**
269 * {@inheritDoc}
270 */
271 @Override()
272 public ChangeType getChangeType()
273 {
274 return ChangeType.ADD;
275 }
276
277
278
279 /**
280 * {@inheritDoc}
281 */
282 @Override()
283 public LDAPResult processChange(final LDAPInterface connection,
284 final boolean includeControls)
285 throws LDAPException
286 {
287 return connection.add(toAddRequest(includeControls));
288 }
289
290
291
292 /**
293 * {@inheritDoc}
294 */
295 @Override()
296 public String[] toLDIF(final int wrapColumn)
297 {
298 List<String> ldifLines = new ArrayList<String>(2*attributes.length);
299 ldifLines.add(LDIFWriter.encodeNameAndValue("dn",
300 new ASN1OctetString(getDN())));
301
302 for (final Control c : getControls())
303 {
304 ldifLines.add(LDIFWriter.encodeNameAndValue("control",
305 encodeControlString(c)));
306 }
307
308 ldifLines.add("changetype: add");
309
310 for (final Attribute a : attributes)
311 {
312 final String name = a.getName();
313 for (final ASN1OctetString value : a.getRawValues())
314 {
315 ldifLines.add(LDIFWriter.encodeNameAndValue(name, value));
316 }
317 }
318
319 if (wrapColumn > 2)
320 {
321 ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines);
322 }
323
324 final String[] ldifArray = new String[ldifLines.size()];
325 ldifLines.toArray(ldifArray);
326 return ldifArray;
327 }
328
329
330
331 /**
332 * {@inheritDoc}
333 */
334 @Override()
335 public void toLDIF(final ByteStringBuffer buffer, final int wrapColumn)
336 {
337 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
338 wrapColumn);
339 buffer.append(EOL_BYTES);
340
341 for (final Control c : getControls())
342 {
343 LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
344 wrapColumn);
345 buffer.append(EOL_BYTES);
346 }
347
348 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"),
349 buffer, wrapColumn);
350 buffer.append(EOL_BYTES);
351
352 for (final Attribute a : attributes)
353 {
354 final String name = a.getName();
355 for (final ASN1OctetString value : a.getRawValues())
356 {
357 LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn);
358 buffer.append(EOL_BYTES);
359 }
360 }
361 }
362
363
364
365 /**
366 * {@inheritDoc}
367 */
368 @Override()
369 public void toLDIFString(final StringBuilder buffer, final int wrapColumn)
370 {
371 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
372 wrapColumn);
373 buffer.append(EOL);
374
375 for (final Control c : getControls())
376 {
377 LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
378 wrapColumn);
379 buffer.append(EOL);
380 }
381
382 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"),
383 buffer, wrapColumn);
384 buffer.append(EOL);
385
386 for (final Attribute a : attributes)
387 {
388 final String name = a.getName();
389 for (final ASN1OctetString value : a.getRawValues())
390 {
391 LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn);
392 buffer.append(EOL);
393 }
394 }
395 }
396
397
398
399 /**
400 * {@inheritDoc}
401 */
402 @Override()
403 public int hashCode()
404 {
405 try
406 {
407 int hashCode = getParsedDN().hashCode();
408 for (final Attribute a : attributes)
409 {
410 hashCode += a.hashCode();
411 }
412
413 return hashCode;
414 }
415 catch (final Exception e)
416 {
417 debugException(e);
418 return new Entry(getDN(), attributes).hashCode();
419 }
420 }
421
422
423
424 /**
425 * {@inheritDoc}
426 */
427 @Override()
428 public boolean equals(final Object o)
429 {
430 if (o == null)
431 {
432 return false;
433 }
434
435 if (o == this)
436 {
437 return true;
438 }
439
440 if (! (o instanceof LDIFAddChangeRecord))
441 {
442 return false;
443 }
444
445 final LDIFAddChangeRecord r = (LDIFAddChangeRecord) o;
446
447 final HashSet<Control> c1 = new HashSet<Control>(getControls());
448 final HashSet<Control> c2 = new HashSet<Control>(r.getControls());
449 if (! c1.equals(c2))
450 {
451 return false;
452 }
453
454 final Entry e1 = new Entry(getDN(), attributes);
455 final Entry e2 = new Entry(r.getDN(), r.attributes);
456 return e1.equals(e2);
457 }
458
459
460
461 /**
462 * {@inheritDoc}
463 */
464 @Override()
465 public void toString(final StringBuilder buffer)
466 {
467 buffer.append("LDIFAddChangeRecord(dn='");
468 buffer.append(getDN());
469 buffer.append("', attrs={");
470
471 for (int i=0; i < attributes.length; i++)
472 {
473 if (i > 0)
474 {
475 buffer.append(", ");
476 }
477 attributes[i].toString(buffer);
478 }
479 buffer.append('}');
480
481 final List<Control> controls = getControls();
482 if (! controls.isEmpty())
483 {
484 buffer.append(", controls={");
485
486 final Iterator<Control> iterator = controls.iterator();
487 while (iterator.hasNext())
488 {
489 iterator.next().toString(buffer);
490 if (iterator.hasNext())
491 {
492 buffer.append(',');
493 }
494 }
495
496 buffer.append('}');
497 }
498
499 buffer.append(')');
500 }
501 }