001    /*
002     * Copyright 2009-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-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.ldap.protocol;
022    
023    
024    
025    import java.util.ArrayList;
026    import java.util.Collections;
027    import java.util.Iterator;
028    import java.util.List;
029    
030    import com.unboundid.asn1.ASN1Buffer;
031    import com.unboundid.asn1.ASN1BufferSequence;
032    import com.unboundid.asn1.ASN1Element;
033    import com.unboundid.asn1.ASN1OctetString;
034    import com.unboundid.asn1.ASN1Sequence;
035    import com.unboundid.asn1.ASN1StreamReader;
036    import com.unboundid.asn1.ASN1StreamReaderSequence;
037    import com.unboundid.ldap.sdk.AddRequest;
038    import com.unboundid.ldap.sdk.Attribute;
039    import com.unboundid.ldap.sdk.Control;
040    import com.unboundid.ldap.sdk.LDAPException;
041    import com.unboundid.ldap.sdk.ResultCode;
042    import com.unboundid.util.InternalUseOnly;
043    
044    import static com.unboundid.ldap.protocol.ProtocolMessages.*;
045    import static com.unboundid.util.Debug.*;
046    import static com.unboundid.util.StaticUtils.*;
047    import static com.unboundid.util.Validator.*;
048    
049    
050    
051    /**
052     * This class provides an implementation of an LDAP add request protocol op.
053     */
054    @InternalUseOnly()
055    public final class AddRequestProtocolOp
056           implements ProtocolOp
057    {
058      /**
059       * The serial version UID for this serializable class.
060       */
061      private static final long serialVersionUID = -1195296296055518601L;
062    
063    
064    
065      // The list of attributes for this add request.
066      private final List<Attribute> attributes;
067    
068      // The entry DN for this add request.
069      private final String dn;
070    
071    
072    
073      /**
074       * Creates a new add request protocol op with the provided information.
075       *
076       * @param  dn          The entry DN for this add request.
077       * @param  attributes  The list of attributes to include in this add request.
078       */
079      public AddRequestProtocolOp(final String dn, final List<Attribute> attributes)
080      {
081        this.dn         = dn;
082        this.attributes = Collections.unmodifiableList(attributes);
083      }
084    
085    
086    
087      /**
088       * Creates a new add request protocol op from the provided add request object.
089       *
090       * @param  request  The add request object to use to create this protocol op.
091       */
092      public AddRequestProtocolOp(final AddRequest request)
093      {
094        dn          = request.getDN();
095        attributes = request.getAttributes();
096      }
097    
098    
099    
100      /**
101       * Creates a new add request protocol op read from the provided ASN.1 stream
102       * reader.
103       *
104       * @param  reader  The ASN.1 stream reader from which to read the add request
105       *                 protocol op.
106       *
107       * @throws  LDAPException  If a problem occurs while reading or parsing the
108       *                         add request.
109       */
110      AddRequestProtocolOp(final ASN1StreamReader reader)
111           throws LDAPException
112      {
113        try
114        {
115          reader.beginSequence();
116          dn = reader.readString();
117          ensureNotNull(dn);
118    
119          final ArrayList<Attribute> attrs = new ArrayList<Attribute>(10);
120          final ASN1StreamReaderSequence attrSequence = reader.beginSequence();
121          while (attrSequence.hasMoreElements())
122          {
123            attrs.add(Attribute.readFrom(reader));
124          }
125    
126          attributes = Collections.unmodifiableList(attrs);
127        }
128        catch (LDAPException le)
129        {
130          debugException(le);
131          throw le;
132        }
133        catch (Exception e)
134        {
135          debugException(e);
136    
137          throw new LDAPException(ResultCode.DECODING_ERROR,
138               ERR_ADD_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), e);
139        }
140      }
141    
142    
143    
144      /**
145       * Retrieves the target entry DN for this add request.
146       *
147       * @return  The target entry DN for this add request.
148       */
149      public String getDN()
150      {
151        return dn;
152      }
153    
154    
155    
156      /**
157       * Retrieves the list of attributes for this add request.
158       *
159       * @return  The list of attributes for this add request.
160       */
161      public List<Attribute> getAttributes()
162      {
163        return attributes;
164      }
165    
166    
167    
168      /**
169       * {@inheritDoc}
170       */
171      public byte getProtocolOpType()
172      {
173        return LDAPMessage.PROTOCOL_OP_TYPE_ADD_REQUEST;
174      }
175    
176    
177    
178      /**
179       * {@inheritDoc}
180       */
181      public ASN1Element encodeProtocolOp()
182      {
183        final ArrayList<ASN1Element> attrElements =
184             new ArrayList<ASN1Element>(attributes.size());
185        for (final Attribute a : attributes)
186        {
187          attrElements.add(a.encode());
188        }
189    
190        return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_ADD_REQUEST,
191             new ASN1OctetString(dn),
192             new ASN1Sequence(attrElements));
193      }
194    
195    
196    
197      /**
198       * Decodes the provided ASN.1 element as an add request protocol op.
199       *
200       * @param  element  The ASN.1 element to be decoded.
201       *
202       * @return  The decoded add request protocol op.
203       *
204       * @throws  LDAPException  If the provided ASN.1 element cannot be decoded as
205       *                         an add request protocol op.
206       */
207      public static AddRequestProtocolOp decodeProtocolOp(final ASN1Element element)
208             throws LDAPException
209      {
210        try
211        {
212          final ASN1Element[] elements =
213               ASN1Sequence.decodeAsSequence(element).elements();
214          final String dn =
215               ASN1OctetString.decodeAsOctetString(elements[0]).stringValue();
216    
217          final ASN1Element[] attrElements =
218               ASN1Sequence.decodeAsSequence(elements[1]).elements();
219          final ArrayList<Attribute> attributes =
220               new ArrayList<Attribute>(attrElements.length);
221          for (final ASN1Element ae : attrElements)
222          {
223            attributes.add(Attribute.decode(ASN1Sequence.decodeAsSequence(ae)));
224          }
225    
226          return new AddRequestProtocolOp(dn, attributes);
227        }
228        catch (final Exception e)
229        {
230          debugException(e);
231          throw new LDAPException(ResultCode.DECODING_ERROR,
232               ERR_ADD_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)),
233               e);
234        }
235      }
236    
237    
238    
239      /**
240       * {@inheritDoc}
241       */
242      public void writeTo(final ASN1Buffer buffer)
243      {
244        final ASN1BufferSequence opSequence =
245             buffer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_ADD_REQUEST);
246        buffer.addOctetString(dn);
247    
248        final ASN1BufferSequence attrSequence = buffer.beginSequence();
249        for (final Attribute a : attributes)
250        {
251          a.writeTo(buffer);
252        }
253        attrSequence.end();
254        opSequence.end();
255      }
256    
257    
258    
259      /**
260       * Creates an add request from this protocol op.
261       *
262       * @param  controls  The set of controls to include in the add request.  It
263       *                   may be empty or {@code null} if no controls should be
264       *                   included.
265       *
266       * @return  The add request that was created.
267       */
268      public AddRequest toAddRequest(final Control... controls)
269      {
270        return new AddRequest(dn, attributes, controls);
271      }
272    
273    
274    
275      /**
276       * Retrieves a string representation of this protocol op.
277       *
278       * @return  A string representation of this protocol op.
279       */
280      @Override()
281      public String toString()
282      {
283        final StringBuilder buffer = new StringBuilder();
284        toString(buffer);
285        return buffer.toString();
286      }
287    
288    
289    
290      /**
291       * {@inheritDoc}
292       */
293      public void toString(final StringBuilder buffer)
294      {
295        buffer.append("AddRequestProtocolOp(dn='");
296        buffer.append(dn);
297        buffer.append("', attrs={");
298    
299        final Iterator<Attribute> iterator = attributes.iterator();
300        while (iterator.hasNext())
301        {
302          iterator.next().toString(buffer);
303          if (iterator.hasNext())
304          {
305            buffer.append(',');
306          }
307        }
308    
309        buffer.append("})");
310      }
311    }