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