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