001/*
002 * Copyright 2007-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2007-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2007-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldif;
037
038
039
040import java.util.ArrayList;
041import java.util.HashSet;
042import java.util.Iterator;
043import java.util.List;
044
045import com.unboundid.asn1.ASN1OctetString;
046import com.unboundid.ldap.sdk.ChangeType;
047import com.unboundid.ldap.sdk.Control;
048import com.unboundid.ldap.sdk.DeleteRequest;
049import com.unboundid.ldap.sdk.LDAPException;
050import com.unboundid.ldap.sdk.LDAPInterface;
051import com.unboundid.ldap.sdk.LDAPResult;
052import com.unboundid.util.ByteStringBuffer;
053import com.unboundid.util.Debug;
054import com.unboundid.util.NotMutable;
055import com.unboundid.util.NotNull;
056import com.unboundid.util.Nullable;
057import com.unboundid.util.StaticUtils;
058import com.unboundid.util.ThreadSafety;
059import com.unboundid.util.ThreadSafetyLevel;
060
061
062
063/**
064 * This class defines an LDIF delete change record, which can be used to
065 * represent an LDAP delete request.  See the documentation for the
066 * {@link LDIFChangeRecord} class for an example demonstrating the process for
067 * interacting with LDIF change records.
068 */
069@NotMutable()
070@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
071public final class LDIFDeleteChangeRecord
072       extends LDIFChangeRecord
073{
074  /**
075   * The serial version UID for this serializable class.
076   */
077  private static final long serialVersionUID = 9173178539060889790L;
078
079
080
081  /**
082   * Creates a new LDIF delete change record with the provided DN.
083   *
084   * @param  dn  The DN of the entry to delete.  It must not be {@code null}.
085   */
086  public LDIFDeleteChangeRecord(@NotNull final String dn)
087  {
088    this(dn, null);
089  }
090
091
092
093  /**
094   * Creates a new LDIF delete change record with the provided DN.
095   *
096   * @param  dn        The DN of the entry to delete.  It must not be
097   *                   {@code null}.
098   * @param  controls  The set of controls for this LDIF delete change record.
099   *                   It may be {@code null} or empty if there are no controls.
100   */
101  public LDIFDeleteChangeRecord(@NotNull final String dn,
102                                @Nullable final List<Control> controls)
103  {
104    super(dn, controls);
105  }
106
107
108
109  /**
110   * Creates a new LDIF delete change record from the provided delete request.
111   *
112   * @param  deleteRequest  The delete request to use to create this LDIF delete
113   *                        change record.  It must not be {@code null}.
114   */
115  public LDIFDeleteChangeRecord(@NotNull final DeleteRequest deleteRequest)
116  {
117    super(deleteRequest.getDN(), deleteRequest.getControlList());
118  }
119
120
121
122  /**
123   * Creates a delete request from this LDIF delete change record. Any change
124   * record controls will be included in the request
125   *
126   * @return The delete request created from this LDIF delete change record.
127   */
128  @NotNull()
129  public DeleteRequest toDeleteRequest()
130  {
131    return toDeleteRequest(true);
132  }
133
134
135
136  /**
137   * Creates a delete request from this LDIF delete change record, optionally
138   * including any change record controls in the request.
139   *
140   * @param  includeControls  Indicates whether to include any controls in the
141   *                          request.
142   *
143   * @return The delete request created from this LDIF delete change record.
144   */
145  @NotNull()
146  public DeleteRequest toDeleteRequest(final boolean includeControls)
147  {
148    final DeleteRequest deleteRequest = new DeleteRequest(getDN());
149    if (includeControls)
150    {
151      deleteRequest.setControls(getControls());
152    }
153
154    return deleteRequest;
155  }
156
157
158
159  /**
160   * {@inheritDoc}
161   */
162  @Override()
163  @NotNull()
164  public ChangeType getChangeType()
165  {
166    return ChangeType.DELETE;
167  }
168
169
170
171  /**
172   * {@inheritDoc}
173   */
174  @Override()
175  @NotNull()
176  public LDIFDeleteChangeRecord duplicate(@Nullable final Control... controls)
177  {
178    return new LDIFDeleteChangeRecord(getDN(), StaticUtils.toList(controls));
179  }
180
181
182
183  /**
184   * {@inheritDoc}
185   */
186  @Override()
187  @NotNull()
188  public LDAPResult processChange(@NotNull final LDAPInterface connection,
189                                  final boolean includeControls)
190         throws LDAPException
191  {
192    return connection.delete(toDeleteRequest(includeControls));
193  }
194
195
196
197  /**
198   * {@inheritDoc}
199   */
200  @Override()
201  @NotNull()
202  public String[] toLDIF(final int wrapColumn)
203  {
204    List<String> ldifLines = new ArrayList<>(5);
205    encodeNameAndValue("dn", new ASN1OctetString(getDN()), ldifLines);
206
207    for (final Control c : getControls())
208    {
209      encodeNameAndValue("control", encodeControlString(c), ldifLines);
210    }
211
212    ldifLines.add("changetype: delete");
213
214    if (wrapColumn > 2)
215    {
216      ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines);
217    }
218
219    final String[] ldifArray = new String[ldifLines.size()];
220    ldifLines.toArray(ldifArray);
221    return ldifArray;
222  }
223
224
225
226  /**
227   * {@inheritDoc}
228   */
229  @Override()
230  public void toLDIF(@NotNull final ByteStringBuffer buffer,
231                     final int wrapColumn)
232  {
233    LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
234         wrapColumn);
235    buffer.append(StaticUtils.EOL_BYTES);
236
237    for (final Control c : getControls())
238    {
239      LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
240           wrapColumn);
241      buffer.append(StaticUtils.EOL_BYTES);
242    }
243
244    LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("delete"),
245                                  buffer, wrapColumn);
246    buffer.append(StaticUtils.EOL_BYTES);
247  }
248
249
250
251  /**
252   * {@inheritDoc}
253   */
254  @Override()
255  public void toLDIFString(@NotNull final StringBuilder buffer,
256                           final int wrapColumn)
257  {
258    LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
259         wrapColumn);
260    buffer.append(StaticUtils.EOL);
261
262    for (final Control c : getControls())
263    {
264      LDIFWriter.encodeNameAndValue("control", encodeControlString(c), buffer,
265           wrapColumn);
266      buffer.append(StaticUtils.EOL);
267    }
268
269    LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("delete"),
270                                  buffer, wrapColumn);
271    buffer.append(StaticUtils.EOL);
272  }
273
274
275
276  /**
277   * {@inheritDoc}
278   */
279  @Override()
280  public int hashCode()
281  {
282    try
283    {
284      return getParsedDN().hashCode();
285    }
286    catch (final Exception e)
287    {
288      Debug.debugException(e);
289      return StaticUtils.toLowerCase(getDN()).hashCode();
290    }
291  }
292
293
294
295  /**
296   * {@inheritDoc}
297   */
298  @Override()
299  public boolean equals(@Nullable final Object o)
300  {
301    if (o == null)
302    {
303      return false;
304    }
305
306    if (o == this)
307    {
308      return true;
309    }
310
311    if (! (o instanceof LDIFDeleteChangeRecord))
312    {
313      return false;
314    }
315
316    final LDIFDeleteChangeRecord r = (LDIFDeleteChangeRecord) o;
317
318    final HashSet<Control> c1 = new HashSet<>(getControls());
319    final HashSet<Control> c2 = new HashSet<>(r.getControls());
320    if (! c1.equals(c2))
321    {
322      return false;
323    }
324
325    try
326    {
327      return getParsedDN().equals(r.getParsedDN());
328    }
329    catch (final Exception e)
330    {
331      Debug.debugException(e);
332      return StaticUtils.toLowerCase(getDN()).equals(
333           StaticUtils.toLowerCase(r.getDN()));
334    }
335  }
336
337
338
339  /**
340   * {@inheritDoc}
341   */
342  @Override()
343  public void toString(@NotNull final StringBuilder buffer)
344  {
345    buffer.append("LDIFDeleteChangeRecord(dn='");
346    buffer.append(getDN());
347    buffer.append('\'');
348
349    final List<Control> controls = getControls();
350    if (! controls.isEmpty())
351    {
352      buffer.append(", controls={");
353
354      final Iterator<Control> iterator = controls.iterator();
355      while (iterator.hasNext())
356      {
357        iterator.next().toString(buffer);
358        if (iterator.hasNext())
359        {
360          buffer.append(',');
361        }
362      }
363
364      buffer.append('}');
365    }
366
367    buffer.append(')');
368  }
369}