001    /*
002     * Copyright 2007-2013 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2013 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.Collection;
027    import java.util.Iterator;
028    import java.util.List;
029    
030    import com.unboundid.asn1.ASN1OctetString;
031    import com.unboundid.ldap.sdk.AddRequest;
032    import com.unboundid.ldap.sdk.Attribute;
033    import com.unboundid.ldap.sdk.ChangeType;
034    import com.unboundid.ldap.sdk.Entry;
035    import com.unboundid.ldap.sdk.LDAPException;
036    import com.unboundid.ldap.sdk.LDAPInterface;
037    import com.unboundid.ldap.sdk.LDAPResult;
038    import com.unboundid.util.ByteStringBuffer;
039    import com.unboundid.util.NotMutable;
040    import com.unboundid.util.ThreadSafety;
041    import com.unboundid.util.ThreadSafetyLevel;
042    
043    import static com.unboundid.util.Debug.*;
044    import static com.unboundid.util.StaticUtils.*;
045    import static com.unboundid.util.Validator.*;
046    
047    
048    
049    /**
050     * This class defines an LDIF add change record, which can be used to represent
051     * an LDAP add request.  See the documentation for the {@link LDIFChangeRecord}
052     * class for an example demonstrating the process for interacting with LDIF
053     * change records.
054     */
055    @NotMutable()
056    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
057    public final class LDIFAddChangeRecord
058           extends LDIFChangeRecord
059    {
060      /**
061       * The serial version UID for this serializable class.
062       */
063      private static final long serialVersionUID = 5717427836786488295L;
064    
065    
066    
067      // The set of attributes for this add change record.
068      private final Attribute[] attributes;
069    
070    
071    
072      /**
073       * Creates a new LDIF add change record with the provided DN and attributes.
074       *
075       * @param  dn          The DN for this LDIF add change record.  It must not be
076       *                     {@code null}.
077       * @param  attributes  The set of attributes for this LDIF add change record.
078       *                     It must not be {@code null} or empty.
079       */
080      public LDIFAddChangeRecord(final String dn, final Attribute... attributes)
081      {
082        super(dn);
083    
084        ensureNotNull(attributes);
085        ensureTrue(attributes.length > 0,
086                   "LDIFAddChangeRecord.attributes must not be empty.");
087    
088        this.attributes = attributes;
089      }
090    
091    
092    
093      /**
094       * Creates a new LDIF add change record with the provided DN and attributes.
095       *
096       * @param  dn          The DN for this LDIF add change record.  It must not be
097       *                     {@code null}.
098       * @param  attributes  The set of attributes for this LDIF add change record.
099       *                     It must not be {@code null} or empty.
100       */
101      public LDIFAddChangeRecord(final String dn, final List<Attribute> attributes)
102      {
103        super(dn);
104    
105        ensureNotNull(attributes);
106        ensureFalse(attributes.isEmpty(),
107                    "LDIFAddChangeRecord.attributes must not be empty.");
108    
109        this.attributes = new Attribute[attributes.size()];
110        attributes.toArray(this.attributes);
111      }
112    
113    
114    
115      /**
116       * Creates a new LDIF add change record from the provided entry.
117       *
118       * @param  entry  The entry to use to create this LDIF add change record.  It
119       *                must not be {@code null}.
120       */
121      public LDIFAddChangeRecord(final Entry entry)
122      {
123        super(entry.getDN());
124    
125        final Collection<Attribute> attrs = entry.getAttributes();
126        attributes = new Attribute[attrs.size()];
127    
128        final Iterator<Attribute> iterator = attrs.iterator();
129        for (int i=0; i < attributes.length; i++)
130        {
131          attributes[i] = iterator.next();
132        }
133      }
134    
135    
136    
137      /**
138       * Creates a new LDIF add change record from the provided add request.
139       *
140       * @param  addRequest  The add request to use to create this LDIF add change
141       *                     record.  It must not be {@code null}.
142       */
143      public LDIFAddChangeRecord(final AddRequest addRequest)
144      {
145        super(addRequest.getDN());
146    
147        final List<Attribute> attrs = addRequest.getAttributes();
148        attributes = new Attribute[attrs.size()];
149    
150        final Iterator<Attribute> iterator = attrs.iterator();
151        for (int i=0; i < attributes.length; i++)
152        {
153          attributes[i] = iterator.next();
154        }
155      }
156    
157    
158    
159      /**
160       * Retrieves the set of attributes for this add change record.
161       *
162       * @return  The set of attributes for this add change record.
163       */
164      public Attribute[] getAttributes()
165      {
166        return attributes;
167      }
168    
169    
170    
171      /**
172       * Retrieves the entry that would be created by this add change record.
173       *
174       * @return  The entry that would be created by this add change record.
175       */
176      public Entry getEntryToAdd()
177      {
178        return new Entry(getDN(), attributes);
179      }
180    
181    
182    
183      /**
184       * Creates an add request from this LDIF add change record.
185       *
186       * @return  The add request created from this LDIF add change record.
187       */
188      public AddRequest toAddRequest()
189      {
190        return new AddRequest(getDN(), attributes);
191      }
192    
193    
194    
195      /**
196       * {@inheritDoc}
197       */
198      @Override()
199      public ChangeType getChangeType()
200      {
201        return ChangeType.ADD;
202      }
203    
204    
205    
206      /**
207       * {@inheritDoc}
208       */
209      @Override()
210      public LDAPResult processChange(final LDAPInterface connection)
211             throws LDAPException
212      {
213        return connection.add(toAddRequest());
214      }
215    
216    
217    
218      /**
219       * {@inheritDoc}
220       */
221      @Override()
222      public String[] toLDIF(final int wrapColumn)
223      {
224        List<String> ldifLines = new ArrayList<String>(2*attributes.length);
225        ldifLines.add(LDIFWriter.encodeNameAndValue("dn",
226                                                    new ASN1OctetString(getDN())));
227        ldifLines.add("changetype: add");
228    
229        for (final Attribute a : attributes)
230        {
231          final String name = a.getName();
232          for (final ASN1OctetString value : a.getRawValues())
233          {
234            ldifLines.add(LDIFWriter.encodeNameAndValue(name, value));
235          }
236        }
237    
238        if (wrapColumn > 2)
239        {
240          ldifLines = LDIFWriter.wrapLines(wrapColumn, ldifLines);
241        }
242    
243        final String[] ldifArray = new String[ldifLines.size()];
244        ldifLines.toArray(ldifArray);
245        return ldifArray;
246      }
247    
248    
249    
250      /**
251       * {@inheritDoc}
252       */
253      @Override()
254      public void toLDIF(final ByteStringBuffer buffer, final int wrapColumn)
255      {
256        LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
257                                      wrapColumn);
258        buffer.append(EOL_BYTES);
259        LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"),
260                                      buffer, wrapColumn);
261        buffer.append(EOL_BYTES);
262    
263        for (final Attribute a : attributes)
264        {
265          final String name = a.getName();
266          for (final ASN1OctetString value : a.getRawValues())
267          {
268            LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn);
269            buffer.append(EOL_BYTES);
270          }
271        }
272      }
273    
274    
275    
276      /**
277       * {@inheritDoc}
278       */
279      @Override()
280      public void toLDIFString(final StringBuilder buffer, final int wrapColumn)
281      {
282        LDIFWriter.encodeNameAndValue("dn", new ASN1OctetString(getDN()), buffer,
283                                      wrapColumn);
284        buffer.append(EOL);
285    
286        LDIFWriter.encodeNameAndValue("changetype", new ASN1OctetString("add"),
287                                      buffer, wrapColumn);
288        buffer.append(EOL);
289    
290        for (final Attribute a : attributes)
291        {
292          final String name = a.getName();
293          for (final ASN1OctetString value : a.getRawValues())
294          {
295            LDIFWriter.encodeNameAndValue(name, value, buffer, wrapColumn);
296            buffer.append(EOL);
297          }
298        }
299      }
300    
301    
302    
303      /**
304       * {@inheritDoc}
305       */
306      @Override()
307      public int hashCode()
308      {
309        try
310        {
311          int hashCode = getParsedDN().hashCode();
312          for (final Attribute a : attributes)
313          {
314            hashCode += a.hashCode();
315          }
316    
317          return hashCode;
318        }
319        catch (Exception e)
320        {
321          debugException(e);
322          return new Entry(getDN(), attributes).hashCode();
323        }
324      }
325    
326    
327    
328      /**
329       * {@inheritDoc}
330       */
331      @Override()
332      public boolean equals(final Object o)
333      {
334        if (o == null)
335        {
336          return false;
337        }
338    
339        if (o == this)
340        {
341          return true;
342        }
343    
344        if (! (o instanceof LDIFAddChangeRecord))
345        {
346          return false;
347        }
348    
349        final LDIFAddChangeRecord r = (LDIFAddChangeRecord) o;
350    
351        final Entry e1 = new Entry(getDN(), attributes);
352        final Entry e2 = new Entry(r.getDN(), r.attributes);
353        return e1.equals(e2);
354      }
355    
356    
357    
358      /**
359       * {@inheritDoc}
360       */
361      @Override()
362      public void toString(final StringBuilder buffer)
363      {
364        buffer.append("LDIFAddChangeRecord(dn='");
365        buffer.append(getDN());
366        buffer.append("', attrs={");
367    
368        for (int i=0; i < attributes.length; i++)
369        {
370          if (i > 0)
371          {
372            buffer.append(", ");
373          }
374          attributes[i].toString(buffer);
375        }
376    
377        buffer.append("})");
378      }
379    }