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