001/*
002 * Copyright 2007-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2019 Ping Identity Corporation
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 */
021package com.unboundid.ldif;
022
023
024
025import java.util.ArrayList;
026import java.util.HashSet;
027import java.util.Iterator;
028import java.util.List;
029
030import com.unboundid.asn1.ASN1OctetString;
031import com.unboundid.ldap.sdk.ChangeType;
032import com.unboundid.ldap.sdk.Control;
033import com.unboundid.ldap.sdk.DeleteRequest;
034import com.unboundid.ldap.sdk.LDAPException;
035import com.unboundid.ldap.sdk.LDAPInterface;
036import com.unboundid.ldap.sdk.LDAPResult;
037import com.unboundid.util.ByteStringBuffer;
038import com.unboundid.util.Debug;
039import com.unboundid.util.NotMutable;
040import com.unboundid.util.StaticUtils;
041import com.unboundid.util.ThreadSafety;
042import com.unboundid.util.ThreadSafetyLevel;
043
044
045
046/**
047 * This class defines an LDIF delete change record, which can be used to
048 * represent an LDAP delete request.  See the documentation for the
049 * {@link LDIFChangeRecord} class for an example demonstrating the process for
050 * interacting with LDIF change records.
051 */
052@NotMutable()
053@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
054public final class LDIFDeleteChangeRecord
055       extends LDIFChangeRecord
056{
057  /**
058   * The serial version UID for this serializable class.
059   */
060  private static final long serialVersionUID = 9173178539060889790L;
061
062
063
064  /**
065   * Creates a new LDIF delete change record with the provided DN.
066   *
067   * @param  dn  The DN of the entry to delete.  It must not be {@code null}.
068   */
069  public LDIFDeleteChangeRecord(final String dn)
070  {
071    this(dn, null);
072  }
073
074
075
076  /**
077   * Creates a new LDIF delete change record with the provided DN.
078   *
079   * @param  dn        The DN of the entry to delete.  It must not be
080   *                   {@code null}.
081   * @param  controls  The set of controls for this LDIF delete change record.
082   *                   It may be {@code null} or empty if there are no controls.
083   */
084  public LDIFDeleteChangeRecord(final String dn, final List<Control> controls)
085  {
086    super(dn, controls);
087  }
088
089
090
091  /**
092   * Creates a new LDIF delete change record from the provided delete request.
093   *
094   * @param  deleteRequest  The delete request to use to create this LDIF delete
095   *                        change record.  It must not be {@code null}.
096   */
097  public LDIFDeleteChangeRecord(final DeleteRequest deleteRequest)
098  {
099    super(deleteRequest.getDN(), deleteRequest.getControlList());
100  }
101
102
103
104  /**
105   * Creates a delete request from this LDIF delete change record. Any change
106   * record controls will be included in the request
107   *
108   * @return The delete request created from this LDIF delete change record.
109   */
110  public DeleteRequest toDeleteRequest()
111  {
112    return toDeleteRequest(true);
113  }
114
115
116
117  /**
118   * Creates a delete request from this LDIF delete change record, optionally
119   * including any change record controls in the request.
120   *
121   * @param  includeControls  Indicates whether to include any controls in the
122   *                          request.
123   *
124   * @return The delete request created from this LDIF delete change record.
125   */
126  public DeleteRequest toDeleteRequest(final boolean includeControls)
127  {
128    final DeleteRequest deleteRequest = new DeleteRequest(getDN());
129    if (includeControls)
130    {
131      deleteRequest.setControls(getControls());
132    }
133
134    return deleteRequest;
135  }
136
137
138
139  /**
140   * {@inheritDoc}
141   */
142  @Override()
143  public ChangeType getChangeType()
144  {
145    return ChangeType.DELETE;
146  }
147
148
149
150  /**
151   * {@inheritDoc}
152   */
153  @Override()
154  public LDIFDeleteChangeRecord duplicate(final Control... controls)
155  {
156    return new LDIFDeleteChangeRecord(getDN(), StaticUtils.toList(controls));
157  }
158
159
160
161  /**
162   * {@inheritDoc}
163   */
164  @Override()
165  public LDAPResult processChange(final LDAPInterface connection,
166                                  final boolean includeControls)
167         throws LDAPException
168  {
169    return connection.delete(toDeleteRequest(includeControls));
170  }
171
172
173
174  /**
175   * {@inheritDoc}
176   */
177  @Override()
178  public String[] toLDIF(final int wrapColumn)
179  {
180    List<String> ldifLines = new ArrayList<>(5);
181    encodeNameAndValue("dn", new ASN1OctetString(getDN()), ldifLines);
182
183    for (final Control c : getControls())
184    {
185      encodeNameAndValue("control", encodeControlString(c), ldifLines);
186    }
187
188    ldifLines.add("changetype: delete");
189
190    if (wrapColumn > 2)
191    {
192      ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines);
193    }
194
195    final String[] ldifArray = new String[ldifLines.size()];
196    ldifLines.toArray(ldifArray);
197    return ldifArray;
198  }
199
200
201
202  /**
203   * {@inheritDoc}
204   */
205  @Override()
206  public void toLDIF(final ByteStringBuffer buffer, final int wrapColumn)
207  {
208    LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
209         wrapColumn);
210    buffer.append(StaticUtils.EOL_BYTES);
211
212    for (final Control c : getControls())
213    {
214      LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
215           wrapColumn);
216      buffer.append(StaticUtils.EOL_BYTES);
217    }
218
219    LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("delete"),
220                                  buffer, wrapColumn);
221    buffer.append(StaticUtils.EOL_BYTES);
222  }
223
224
225
226  /**
227   * {@inheritDoc}
228   */
229  @Override()
230  public void toLDIFString(final StringBuilder buffer, final int wrapColumn)
231  {
232    LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
233         wrapColumn);
234    buffer.append(StaticUtils.EOL);
235
236    for (final Control c : getControls())
237    {
238      LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
239           wrapColumn);
240      buffer.append(StaticUtils.EOL);
241    }
242
243    LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("delete"),
244                                  buffer, wrapColumn);
245    buffer.append(StaticUtils.EOL);
246  }
247
248
249
250  /**
251   * {@inheritDoc}
252   */
253  @Override()
254  public int hashCode()
255  {
256    try
257    {
258      return getParsedDN().hashCode();
259    }
260    catch (final Exception e)
261    {
262      Debug.debugException(e);
263      return StaticUtils.toLowerCase(getDN()).hashCode();
264    }
265  }
266
267
268
269  /**
270   * {@inheritDoc}
271   */
272  @Override()
273  public boolean equals(final Object o)
274  {
275    if (o == null)
276    {
277      return false;
278    }
279
280    if (o == this)
281    {
282      return true;
283    }
284
285    if (! (o instanceof LDIFDeleteChangeRecord))
286    {
287      return false;
288    }
289
290    final LDIFDeleteChangeRecord r = (LDIFDeleteChangeRecord) o;
291
292    final HashSet<Control> c1 = new HashSet<>(getControls());
293    final HashSet<Control> c2 = new HashSet<>(r.getControls());
294    if (! c1.equals(c2))
295    {
296      return false;
297    }
298
299    try
300    {
301      return getParsedDN().equals(r.getParsedDN());
302    }
303    catch (final Exception e)
304    {
305      Debug.debugException(e);
306      return StaticUtils.toLowerCase(getDN()).equals(
307           StaticUtils.toLowerCase(r.getDN()));
308    }
309  }
310
311
312
313  /**
314   * {@inheritDoc}
315   */
316  @Override()
317  public void toString(final StringBuilder buffer)
318  {
319    buffer.append("LDIFDeleteChangeRecord(dn='");
320    buffer.append(getDN());
321    buffer.append('\'');
322
323    final List<Control> controls = getControls();
324    if (! controls.isEmpty())
325    {
326      buffer.append(", controls={");
327
328      final Iterator<Control> iterator = controls.iterator();
329      while (iterator.hasNext())
330      {
331        iterator.next().toString(buffer);
332        if (iterator.hasNext())
333        {
334          buffer.append(',');
335        }
336      }
337
338      buffer.append('}');
339    }
340
341    buffer.append(')');
342  }
343}