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 }