001 /*
002 * Copyright 2009-2012 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2009-2012 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.ASN1OctetString;
033 import com.unboundid.asn1.ASN1StreamReader;
034 import com.unboundid.asn1.ASN1StreamReaderSequence;
035 import com.unboundid.ldap.sdk.LDAPException;
036 import com.unboundid.ldap.sdk.ResultCode;
037 import com.unboundid.util.NotMutable;
038 import com.unboundid.util.InternalUseOnly;
039 import com.unboundid.util.ThreadSafety;
040 import com.unboundid.util.ThreadSafetyLevel;
041
042 import static com.unboundid.ldap.protocol.ProtocolMessages.*;
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 provides an implementation of a extended response protocol op.
051 */
052 @InternalUseOnly()
053 @NotMutable()
054 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
055 public final class ExtendedResponseProtocolOp
056 implements ProtocolOp
057 {
058 /**
059 * The BER type for the response OID element.
060 */
061 public static final byte TYPE_RESPONSE_OID = (byte) 0x8A;
062
063
064
065 /**
066 * The BER type for the response value element.
067 */
068 public static final byte TYPE_RESPONSE_VALUE = (byte) 0x8B;
069
070
071
072 /**
073 * The serial version UID for this serializable class.
074 */
075 private static final long serialVersionUID = -7757619031268544913L;
076
077
078
079 // The value for this extended response.
080 private final ASN1OctetString responseValue;
081
082 // The result code for this extended response.
083 private final int resultCode;
084
085 // The referral URLs for this extended response.
086 private final List<String> referralURLs;
087
088 // The diagnostic message for this extended response.
089 private final String diagnosticMessage;
090
091 // The matched DN for this extended response.
092 private final String matchedDN;
093
094 // The OID for this extended response.
095 private final String responseOID;
096
097
098
099 /**
100 * Creates a new instance of this extended response protocol op with the
101 * provided information.
102 *
103 * @param resultCode The result code for this response.
104 * @param matchedDN The matched DN for this response, if available.
105 * @param diagnosticMessage The diagnostic message for this response, if
106 * any.
107 * @param referralURLs The list of referral URLs for this response, if
108 * any.
109 * @param responseOID The response OID for this response, if any.
110 * @param responseValue The value for this response, if any.
111 */
112 public ExtendedResponseProtocolOp(final int resultCode,
113 final String matchedDN,
114 final String diagnosticMessage,
115 final List<String> referralURLs,
116 final String responseOID,
117 final ASN1OctetString responseValue)
118 {
119 this.resultCode = resultCode;
120 this.matchedDN = matchedDN;
121 this.diagnosticMessage = diagnosticMessage;
122 this.responseOID = responseOID;
123
124 if (referralURLs == null)
125 {
126 this.referralURLs = Collections.emptyList();
127 }
128 else
129 {
130 this.referralURLs = Collections.unmodifiableList(referralURLs);
131 }
132
133 if (responseValue == null)
134 {
135 this.responseValue = null;
136 }
137 else
138 {
139 this.responseValue =
140 new ASN1OctetString(TYPE_RESPONSE_VALUE, responseValue.getValue());
141 }
142 }
143
144
145
146 /**
147 * Creates a new extended response protocol op read from the provided ASN.1
148 * stream reader.
149 *
150 * @param reader The ASN.1 stream reader from which to read the extended
151 * response.
152 *
153 * @throws LDAPException If a problem occurs while reading or parsing the
154 * extended response.
155 */
156 ExtendedResponseProtocolOp(final ASN1StreamReader reader)
157 throws LDAPException
158 {
159 try
160 {
161 final ASN1StreamReaderSequence opSequence = reader.beginSequence();
162 resultCode = reader.readEnumerated();
163
164 String s = reader.readString();
165 ensureNotNull(s);
166 if (s.length() == 0)
167 {
168 matchedDN = null;
169 }
170 else
171 {
172 matchedDN = s;
173 }
174
175 s = reader.readString();
176 ensureNotNull(s);
177 if (s.length() == 0)
178 {
179 diagnosticMessage = null;
180 }
181 else
182 {
183 diagnosticMessage = s;
184 }
185
186 ASN1OctetString value = null;
187 String oid = null;
188 final ArrayList<String> refs = new ArrayList<String>(1);
189 while (opSequence.hasMoreElements())
190 {
191 final byte type = (byte) reader.peek();
192 if (type == GenericResponseProtocolOp.TYPE_REFERRALS)
193 {
194 final ASN1StreamReaderSequence refSequence = reader.beginSequence();
195 while (refSequence.hasMoreElements())
196 {
197 refs.add(reader.readString());
198 }
199 }
200 else if (type == TYPE_RESPONSE_OID)
201 {
202 oid = reader.readString();
203 }
204 else if (type == TYPE_RESPONSE_VALUE)
205 {
206 value = new ASN1OctetString(type, reader.readBytes());
207 }
208 else
209 {
210 throw new LDAPException(ResultCode.DECODING_ERROR,
211 ERR_EXTENDED_RESPONSE_INVALID_ELEMENT.get(toHex(type)));
212 }
213 }
214
215 referralURLs = Collections.unmodifiableList(refs);
216 responseOID = oid;
217 responseValue = value;
218 }
219 catch (LDAPException le)
220 {
221 debugException(le);
222 throw le;
223 }
224 catch (Exception e)
225 {
226 debugException(e);
227 throw new LDAPException(ResultCode.DECODING_ERROR,
228 ERR_EXTENDED_RESPONSE_CANNOT_DECODE.get(getExceptionMessage(e)), e);
229 }
230 }
231
232
233
234 /**
235 * Retrieves the result code for this extended response.
236 *
237 * @return The result code for this extended response.
238 */
239 public int getResultCode()
240 {
241 return resultCode;
242 }
243
244
245
246 /**
247 * Retrieves the matched DN for this extended response, if any.
248 *
249 * @return The matched DN for this extended response, or {@code null} if
250 * there is no matched DN.
251 */
252 public String getMatchedDN()
253 {
254 return matchedDN;
255 }
256
257
258
259 /**
260 * Retrieves the diagnostic message for this extended response, if any.
261 *
262 * @return The diagnostic message for this extended response, or {@code null}
263 * if there is no diagnostic message.
264 */
265 public String getDiagnosticMessage()
266 {
267 return diagnosticMessage;
268 }
269
270
271
272 /**
273 * Retrieves the list of referral URLs for this extended response.
274 *
275 * @return The list of referral URLs for this extended response, or an empty
276 * list if there are no referral URLs.
277 */
278 public List<String> getReferralURLs()
279 {
280 return referralURLs;
281 }
282
283
284
285 /**
286 * Retrieves the OID for this extended response, if any.
287 *
288 * @return The OID for this extended response, or {@code null} if there is no
289 * response OID.
290 */
291 public String getResponseOID()
292 {
293 return responseOID;
294 }
295
296
297
298 /**
299 * Retrieves the value for this extended response, if any.
300 *
301 * @return The value for this extended response, or {@code null} if there is
302 * no response value.
303 */
304 public ASN1OctetString getResponseValue()
305 {
306 return responseValue;
307 }
308
309
310
311 /**
312 * {@inheritDoc}
313 */
314 public byte getProtocolOpType()
315 {
316 return LDAPMessage.PROTOCOL_OP_TYPE_EXTENDED_RESPONSE;
317 }
318
319
320
321 /**
322 * {@inheritDoc}
323 */
324 public void writeTo(final ASN1Buffer buffer)
325 {
326 final ASN1BufferSequence opSequence =
327 buffer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_EXTENDED_RESPONSE);
328 buffer.addEnumerated(resultCode);
329 buffer.addOctetString(matchedDN);
330 buffer.addOctetString(diagnosticMessage);
331
332 if (! referralURLs.isEmpty())
333 {
334 final ASN1BufferSequence refSequence =
335 buffer.beginSequence(GenericResponseProtocolOp.TYPE_REFERRALS);
336 for (final String s : referralURLs)
337 {
338 buffer.addOctetString(s);
339 }
340 refSequence.end();
341 }
342
343 if (responseOID != null)
344 {
345 buffer.addOctetString(TYPE_RESPONSE_OID, responseOID);
346 }
347
348 if (responseValue != null)
349 {
350 buffer.addOctetString(TYPE_RESPONSE_VALUE, responseValue.getValue());
351 }
352
353 opSequence.end();
354 }
355
356
357
358 /**
359 * Retrieves a string representation of this protocol op.
360 *
361 * @return A string representation of this protocol op.
362 */
363 @Override()
364 public String toString()
365 {
366 final StringBuilder buffer = new StringBuilder();
367 toString(buffer);
368 return buffer.toString();
369 }
370
371
372
373 /**
374 * {@inheritDoc}
375 */
376 public void toString(final StringBuilder buffer)
377 {
378 buffer.append("ExtendedResponseProtocolOp(resultCode=");
379 buffer.append(resultCode);
380
381 if (matchedDN != null)
382 {
383 buffer.append(", matchedDN='");
384 buffer.append(matchedDN);
385 buffer.append('\'');
386 }
387
388 if (diagnosticMessage != null)
389 {
390 buffer.append(", diagnosticMessage='");
391 buffer.append(diagnosticMessage);
392 buffer.append('\'');
393 }
394
395 if (! referralURLs.isEmpty())
396 {
397 buffer.append(", referralURLs={");
398
399 final Iterator<String> iterator = referralURLs.iterator();
400 while (iterator.hasNext())
401 {
402 buffer.append('\'');
403 buffer.append(iterator.next());
404 buffer.append('\'');
405 if (iterator.hasNext())
406 {
407 buffer.append(',');
408 }
409 }
410
411 buffer.append('}');
412 }
413
414 if (responseOID != null)
415 {
416 buffer.append(", responseOID='");
417 buffer.append(responseOID);
418 buffer.append('\'');
419 }
420
421 buffer.append(')');
422 }
423 }