001/*
002 * Copyright 2007-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2018 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 LDAPResult processChange(final LDAPInterface connection,
155                                  final boolean includeControls)
156         throws LDAPException
157  {
158    return connection.delete(toDeleteRequest(includeControls));
159  }
160
161
162
163  /**
164   * {@inheritDoc}
165   */
166  @Override()
167  public String[] toLDIF(final int wrapColumn)
168  {
169    List<String> ldifLines = new ArrayList<>(5);
170    encodeNameAndValue("dn", new ASN1OctetString(getDN()), ldifLines);
171
172    for (final Control c : getControls())
173    {
174      encodeNameAndValue("control", encodeControlString(c), ldifLines);
175    }
176
177    ldifLines.add("changetype: delete");
178
179    if (wrapColumn > 2)
180    {
181      ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines);
182    }
183
184    final String[] ldifArray = new String[ldifLines.size()];
185    ldifLines.toArray(ldifArray);
186    return ldifArray;
187  }
188
189
190
191  /**
192   * {@inheritDoc}
193   */
194  @Override()
195  public void toLDIF(final ByteStringBuffer buffer, final int wrapColumn)
196  {
197    LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
198         wrapColumn);
199    buffer.append(StaticUtils.EOL_BYTES);
200
201    for (final Control c : getControls())
202    {
203      LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
204           wrapColumn);
205      buffer.append(StaticUtils.EOL_BYTES);
206    }
207
208    LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("delete"),
209                                  buffer, wrapColumn);
210    buffer.append(StaticUtils.EOL_BYTES);
211  }
212
213
214
215  /**
216   * {@inheritDoc}
217   */
218  @Override()
219  public void toLDIFString(final StringBuilder buffer, final int wrapColumn)
220  {
221    LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
222         wrapColumn);
223    buffer.append(StaticUtils.EOL);
224
225    for (final Control c : getControls())
226    {
227      LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
228           wrapColumn);
229      buffer.append(StaticUtils.EOL);
230    }
231
232    LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("delete"),
233                                  buffer, wrapColumn);
234    buffer.append(StaticUtils.EOL);
235  }
236
237
238
239  /**
240   * {@inheritDoc}
241   */
242  @Override()
243  public int hashCode()
244  {
245    try
246    {
247      return getParsedDN().hashCode();
248    }
249    catch (final Exception e)
250    {
251      Debug.debugException(e);
252      return StaticUtils.toLowerCase(getDN()).hashCode();
253    }
254  }
255
256
257
258  /**
259   * {@inheritDoc}
260   */
261  @Override()
262  public boolean equals(final Object o)
263  {
264    if (o == null)
265    {
266      return false;
267    }
268
269    if (o == this)
270    {
271      return true;
272    }
273
274    if (! (o instanceof LDIFDeleteChangeRecord))
275    {
276      return false;
277    }
278
279    final LDIFDeleteChangeRecord r = (LDIFDeleteChangeRecord) o;
280
281    final HashSet<Control> c1 = new HashSet<>(getControls());
282    final HashSet<Control> c2 = new HashSet<>(r.getControls());
283    if (! c1.equals(c2))
284    {
285      return false;
286    }
287
288    try
289    {
290      return getParsedDN().equals(r.getParsedDN());
291    }
292    catch (final Exception e)
293    {
294      Debug.debugException(e);
295      return StaticUtils.toLowerCase(getDN()).equals(
296           StaticUtils.toLowerCase(r.getDN()));
297    }
298  }
299
300
301
302  /**
303   * {@inheritDoc}
304   */
305  @Override()
306  public void toString(final StringBuilder buffer)
307  {
308    buffer.append("LDIFDeleteChangeRecord(dn='");
309    buffer.append(getDN());
310    buffer.append('\'');
311
312    final List<Control> controls = getControls();
313    if (! controls.isEmpty())
314    {
315      buffer.append(", controls={");
316
317      final Iterator<Control> iterator = controls.iterator();
318      while (iterator.hasNext())
319      {
320        iterator.next().toString(buffer);
321        if (iterator.hasNext())
322        {
323          buffer.append(',');
324        }
325      }
326
327      buffer.append('}');
328    }
329
330    buffer.append(')');
331  }
332}