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