001 /*
002 * Copyright 2013-2015 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 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.sdk.unboundidds.extensions;
022
023
024
025 import java.io.ByteArrayInputStream;
026 import java.io.InputStream;
027
028 import com.unboundid.asn1.ASN1Element;
029 import com.unboundid.asn1.ASN1Enumerated;
030 import com.unboundid.asn1.ASN1OctetString;
031 import com.unboundid.asn1.ASN1Sequence;
032 import com.unboundid.ldap.sdk.Control;
033 import com.unboundid.ldap.sdk.ExtendedResult;
034 import com.unboundid.ldap.sdk.LDAPException;
035 import com.unboundid.ldap.sdk.ResultCode;
036 import com.unboundid.util.Debug;
037 import com.unboundid.util.StaticUtils;
038 import com.unboundid.util.ThreadSafety;
039 import com.unboundid.util.ThreadSafetyLevel;
040 import com.unboundid.util.Validator;
041
042 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
043
044
045
046 /**
047 * <BLOCKQUOTE>
048 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
049 * LDAP SDK for Java. It is not available for use in applications that
050 * include only the Standard Edition of the LDAP SDK, and is not supported for
051 * use in conjunction with non-UnboundID products.
052 * </BLOCKQUOTE>
053 * This class provides an implementation of an extended result that can be used
054 * to retrieve a version of the server configuration.
055 * <BR><BR>
056 * The OID for this extended result is 1.3.6.1.4.1.30221.2.6.29. If the request
057 * was processed successfully, then the response will have a value with the
058 * following encoding:
059 * <PRE>
060 * GetConfigurationResult ::= SEQUENCE {
061 * configurationType [0] ENUMERATED {
062 * active (0),
063 * baseline (1),
064 * archived (2),
065 * ... },
066 * fileName [1] OCTET STRING,
067 * configurationFileData [2] OCTET STRING,
068 * ... }
069 * </PRE>
070 *
071 * @see GetConfigurationExtendedRequest
072 * @see ListConfigurationsExtendedRequest
073 */
074 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
075 public final class GetConfigurationExtendedResult
076 extends ExtendedResult
077 {
078 /**
079 * The OID (1.3.6.1.4.1.30221.2.6.29) for the get configuration extended
080 * result.
081 */
082 public static final String GET_CONFIG_RESULT_OID = "1.3.6.1.4.1.30221.2.6.29";
083
084
085
086 /**
087 * The BER type for the element holding the type of configuration that has
088 * been returned.
089 */
090 private static final byte TYPE_CONFIG_TYPE = (byte) 0x80;
091
092
093
094 /**
095 * The BER type for the element holding the name of the configuration file
096 * that has been returned.
097 */
098 private static final byte TYPE_FILE_NAME = (byte) 0x81;
099
100
101
102 /**
103 * The BER type for the element holding the raw LDIF data that comprises the
104 * configuration file that has been returned.
105 */
106 private static final byte TYPE_FILE_DATA = (byte) 0x82;
107
108
109
110 /**
111 * The serial version UID for this serializable class.
112 */
113 private static final long serialVersionUID = 6042324433827773678L;
114
115
116
117 // The raw data for the configuration file that has been returned.
118 private final byte[] fileData;
119
120 // The type of configuration that has been returned.
121 private final GetConfigurationType configurationType;
122
123 // The name of the configuration file that has been returned.
124 private final String fileName;
125
126
127
128 /**
129 * Creates a new get configuration extended result from the provided generic
130 * extended result.
131 *
132 * @param result The generic extended result to be decoded as a get
133 * configuration extended result.
134 *
135 * @throws LDAPException If the provided extended result cannot be parsed as
136 * a valid get configuration extended result.
137 */
138 public GetConfigurationExtendedResult(final ExtendedResult result)
139 throws LDAPException
140 {
141 super(result);
142
143 final ASN1OctetString value = result.getValue();
144 if (value == null)
145 {
146 configurationType = null;
147 fileName = null;
148 fileData = null;
149 return;
150 }
151
152 try
153 {
154 final ASN1Element[] elements =
155 ASN1Sequence.decodeAsSequence(value.getValue()).elements();
156
157 final int configType =
158 ASN1Enumerated.decodeAsEnumerated(elements[0]).intValue();
159 configurationType = GetConfigurationType.forIntValue(configType);
160 if (configurationType == null)
161 {
162 throw new LDAPException(ResultCode.DECODING_ERROR,
163 ERR_GET_CONFIG_RESULT_INVALID_CONFIG_TYPE.get(configType));
164 }
165
166 fileName = ASN1OctetString.decodeAsOctetString(elements[1]).stringValue();
167 fileData = ASN1OctetString.decodeAsOctetString(elements[2]).getValue();
168 }
169 catch (final LDAPException le)
170 {
171 Debug.debugException(le);
172 throw le;
173 }
174 catch (final Exception e)
175 {
176 Debug.debugException(e);
177 throw new LDAPException(ResultCode.DECODING_ERROR,
178 ERR_GET_CONFIG_RESULT_ERROR_PARSING_VALUE.get(
179 StaticUtils.getExceptionMessage(e)),
180 e);
181 }
182 }
183
184
185
186 /**
187 * Creates a new get configuration extended result with the provided
188 * information.
189 *
190 * @param messageID The message ID for the LDAP message that is
191 * associated with this LDAP result.
192 * @param resultCode The result code from the response.
193 * @param diagnosticMessage The diagnostic message from the response, if
194 * available.
195 * @param matchedDN The matched DN from the response, if available.
196 * @param referralURLs The set of referral URLs from the response, if
197 * available.
198 * @param configurationType The type of configuration that has been
199 * returned.
200 * @param fileName The name of the configuration file that has been
201 * returned.
202 * @param fileData The raw data for the configuration file that has
203 * been returned.
204 * @param responseControls The set of controls from the response, if
205 * available.
206 */
207 public GetConfigurationExtendedResult(final int messageID,
208 final ResultCode resultCode, final String diagnosticMessage,
209 final String matchedDN, final String[] referralURLs,
210 final GetConfigurationType configurationType,
211 final String fileName, final byte[] fileData,
212 final Control... responseControls)
213 {
214 super(messageID, resultCode, diagnosticMessage, matchedDN, referralURLs,
215 ((configurationType == null) ? null : GET_CONFIG_RESULT_OID),
216 encodeValue(configurationType, fileName, fileData), responseControls);
217
218 this.configurationType = configurationType;
219 this.fileName = fileName;
220 this.fileData = fileData;
221 }
222
223
224
225 /**
226 * Creates an ASN.1 octet string containing an encoded representation of the
227 * value for a get configuration extended result with the provided
228 * information.
229 *
230 * @param configurationType The type of configuration that has been
231 * returned.
232 * @param fileName The name of the configuration file that has been
233 * returned.
234 * @param fileData The raw data for the configuration file that has
235 * been returned.
236 *
237 * @return An ASN.1 octet string containing an encoded representation of the
238 * value for a get configuration extended result, or {@code null} if
239 * a result with the provided information should not have a value.
240 */
241 public static ASN1OctetString encodeValue(
242 final GetConfigurationType configurationType,
243 final String fileName, final byte[] fileData)
244 {
245 if (configurationType == null)
246 {
247 Validator.ensureTrue((fileName == null),
248 "The configuration file name must be null if the configuration " +
249 "type is null.");
250 Validator.ensureTrue((fileData == null),
251 "The configuration file data must be null if the configuration " +
252 "type is null.");
253 return null;
254 }
255
256 Validator.ensureTrue((fileName != null),
257 "The configuration file name must not be null if the configuration " +
258 "type is not null.");
259 Validator.ensureTrue((fileData != null),
260 "The configuration file data must not be null if the configuration " +
261 "type is not null.");
262
263 final ASN1Sequence valueSequence = new ASN1Sequence(
264 new ASN1Enumerated(TYPE_CONFIG_TYPE, configurationType.getIntValue()),
265 new ASN1OctetString(TYPE_FILE_NAME, fileName),
266 new ASN1OctetString(TYPE_FILE_DATA, fileData));
267 return new ASN1OctetString(valueSequence.encode());
268 }
269
270
271
272 /**
273 * Retrieves the type of configuration that has been returned, if available.
274 *
275 * @return The type of configuration that has been returned, or {@code null}
276 * if this is not available.
277 */
278 public GetConfigurationType getConfigurationType()
279 {
280 return configurationType;
281 }
282
283
284
285 /**
286 * Retrieves the name of the configuration file that has been returned, if
287 * available.
288 *
289 * @return The name of the configuration file that has been returned, or
290 * {@code null} if this is not available.
291 */
292 public String getFileName()
293 {
294 return fileName;
295 }
296
297
298
299 /**
300 * Retrieves the raw data for the configuration file that has been returned,
301 * if available.
302 *
303 * @return The raw data for the configuration file that has been returned,
304 * or {@code null} if this is not available.
305 */
306 public byte[] getFileData()
307 {
308 return fileData;
309 }
310
311
312
313 /**
314 * Retrieves an input stream that may be used to read the file data that has
315 * been returned, if available.
316 *
317 * @return An input stream that may be used to read the file data that has
318 * been returned, or {@code null} if this is not available.
319 */
320 public InputStream getFileDataInputStream()
321 {
322 if (fileData == null)
323 {
324 return null;
325 }
326 else
327 {
328 return new ByteArrayInputStream(fileData);
329 }
330 }
331
332
333
334 /**
335 * {@inheritDoc}
336 */
337 @Override()
338 public String getExtendedResultName()
339 {
340 return INFO_EXTENDED_RESULT_NAME_GET_CONFIG.get();
341 }
342
343
344
345 /**
346 * {@inheritDoc}
347 */
348 @Override()
349 public void toString(final StringBuilder buffer)
350 {
351 buffer.append("GetConfigurationExtendedResult(resultCode=");
352 buffer.append(getResultCode());
353
354 final int messageID = getMessageID();
355 if (messageID >= 0)
356 {
357 buffer.append(", messageID=");
358 buffer.append(messageID);
359 }
360
361 if (configurationType != null)
362 {
363 buffer.append(", configType=");
364 buffer.append(configurationType.name());
365 }
366
367 if (fileName != null)
368 {
369 buffer.append(", fileName='");
370 buffer.append(fileName);
371 buffer.append('\'');
372 }
373
374 if (fileData != null)
375 {
376 buffer.append(", fileLength=");
377 buffer.append(fileData.length);
378 }
379
380 final String diagnosticMessage = getDiagnosticMessage();
381 if (diagnosticMessage != null)
382 {
383 buffer.append(", diagnosticMessage='");
384 buffer.append(diagnosticMessage);
385 buffer.append('\'');
386 }
387
388 final String matchedDN = getMatchedDN();
389 if (matchedDN != null)
390 {
391 buffer.append(", matchedDN='");
392 buffer.append(matchedDN);
393 buffer.append('\'');
394 }
395
396 final String[] referralURLs = getReferralURLs();
397 if (referralURLs.length > 0)
398 {
399 buffer.append(", referralURLs={");
400 for (int i=0; i < referralURLs.length; i++)
401 {
402 if (i > 0)
403 {
404 buffer.append(", ");
405 }
406
407 buffer.append('\'');
408 buffer.append(referralURLs[i]);
409 buffer.append('\'');
410 }
411 buffer.append('}');
412 }
413
414 final Control[] responseControls = getResponseControls();
415 if (responseControls.length > 0)
416 {
417 buffer.append(", responseControls={");
418 for (int i=0; i < responseControls.length; i++)
419 {
420 if (i > 0)
421 {
422 buffer.append(", ");
423 }
424
425 buffer.append(responseControls[i]);
426 }
427 buffer.append('}');
428 }
429
430 buffer.append(')');
431 }
432 }