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