001 /*
002 * Copyright 2007-2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2016 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 encodeNameAndValue("dn", new ASN1OctetString(getDN()), ldifLines);
300
301 for (final Control c : getControls())
302 {
303 encodeNameAndValue("control", encodeControlString(c), ldifLines);
304 }
305
306 ldifLines.add("changetype: add");
307
308 for (final Attribute a : attributes)
309 {
310 final String name = a.getName();
311 for (final ASN1OctetString value : a.getRawValues())
312 {
313 encodeNameAndValue(name, value, ldifLines);
314 }
315 }
316
317 if (wrapColumn > 2)
318 {
319 ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines);
320 }
321
322 final String[] ldifArray = new String[ldifLines.size()];
323 ldifLines.toArray(ldifArray);
324 return ldifArray;
325 }
326
327
328
329 /**
330 * {@inheritDoc}
331 */
332 @Override()
333 public void toLDIF(final ByteStringBuffer buffer, final int wrapColumn)
334 {
335 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
336 wrapColumn);
337 buffer.append(EOL_BYTES);
338
339 for (final Control c : getControls())
340 {
341 LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
342 wrapColumn);
343 buffer.append(EOL_BYTES);
344 }
345
346 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"),
347 buffer, wrapColumn);
348 buffer.append(EOL_BYTES);
349
350 for (final Attribute a : attributes)
351 {
352 final String name = a.getName();
353 for (final ASN1OctetString value : a.getRawValues())
354 {
355 LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn);
356 buffer.append(EOL_BYTES);
357 }
358 }
359 }
360
361
362
363 /**
364 * {@inheritDoc}
365 */
366 @Override()
367 public void toLDIFString(final StringBuilder buffer, final int wrapColumn)
368 {
369 LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
370 wrapColumn);
371 buffer.append(EOL);
372
373 for (final Control c : getControls())
374 {
375 LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
376 wrapColumn);
377 buffer.append(EOL);
378 }
379
380 LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"),
381 buffer, wrapColumn);
382 buffer.append(EOL);
383
384 for (final Attribute a : attributes)
385 {
386 final String name = a.getName();
387 for (final ASN1OctetString value : a.getRawValues())
388 {
389 LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn);
390 buffer.append(EOL);
391 }
392 }
393 }
394
395
396
397 /**
398 * {@inheritDoc}
399 */
400 @Override()
401 public int hashCode()
402 {
403 try
404 {
405 int hashCode = getParsedDN().hashCode();
406 for (final Attribute a : attributes)
407 {
408 hashCode += a.hashCode();
409 }
410
411 return hashCode;
412 }
413 catch (final Exception e)
414 {
415 debugException(e);
416 return new Entry(getDN(), attributes).hashCode();
417 }
418 }
419
420
421
422 /**
423 * {@inheritDoc}
424 */
425 @Override()
426 public boolean equals(final Object o)
427 {
428 if (o == null)
429 {
430 return false;
431 }
432
433 if (o == this)
434 {
435 return true;
436 }
437
438 if (! (o instanceof LDIFAddChangeRecord))
439 {
440 return false;
441 }
442
443 final LDIFAddChangeRecord r = (LDIFAddChangeRecord) o;
444
445 final HashSet<Control> c1 = new HashSet<Control>(getControls());
446 final HashSet<Control> c2 = new HashSet<Control>(r.getControls());
447 if (! c1.equals(c2))
448 {
449 return false;
450 }
451
452 final Entry e1 = new Entry(getDN(), attributes);
453 final Entry e2 = new Entry(r.getDN(), r.attributes);
454 return e1.equals(e2);
455 }
456
457
458
459 /**
460 * {@inheritDoc}
461 */
462 @Override()
463 public void toString(final StringBuilder buffer)
464 {
465 buffer.append("LDIFAddChangeRecord(dn='");
466 buffer.append(getDN());
467 buffer.append("', attrs={");
468
469 for (int i=0; i < attributes.length; i++)
470 {
471 if (i > 0)
472 {
473 buffer.append(", ");
474 }
475 attributes[i].toString(buffer);
476 }
477 buffer.append('}');
478
479 final List<Control> controls = getControls();
480 if (! controls.isEmpty())
481 {
482 buffer.append(", controls={");
483
484 final Iterator<Control> iterator = controls.iterator();
485 while (iterator.hasNext())
486 {
487 iterator.next().toString(buffer);
488 if (iterator.hasNext())
489 {
490 buffer.append(',');
491 }
492 }
493
494 buffer.append('}');
495 }
496
497 buffer.append(')');
498 }
499 }