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