001 /* 002 * Copyright 2014-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.util.ArrayList; 026 import java.util.Collection; 027 import java.util.Collections; 028 import java.util.List; 029 030 import com.unboundid.asn1.ASN1Element; 031 import com.unboundid.asn1.ASN1Enumerated; 032 import com.unboundid.asn1.ASN1OctetString; 033 import com.unboundid.asn1.ASN1Sequence; 034 import com.unboundid.ldap.sdk.Control; 035 import com.unboundid.ldap.sdk.ExtendedRequest; 036 import com.unboundid.ldap.sdk.LDAPException; 037 import com.unboundid.ldap.sdk.ResultCode; 038 import com.unboundid.util.Debug; 039 import com.unboundid.util.NotMutable; 040 import com.unboundid.util.StaticUtils; 041 import com.unboundid.util.ThreadSafety; 042 import com.unboundid.util.ThreadSafetyLevel; 043 import com.unboundid.util.Validator; 044 045 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 046 047 048 049 /** 050 * <BLOCKQUOTE> 051 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID 052 * LDAP SDK for Java. It is not available for use in applications that 053 * include only the Standard Edition of the LDAP SDK, and is not supported for 054 * use in conjunction with non-UnboundID products. 055 * </BLOCKQUOTE> 056 * This class provides an extended request that may be used to create or update 057 * a notification destination. The request has an OID of 058 * 1.3.6.1.4.1.30221.2.6.36 and a value with the following encoding: 059 * <BR><BR> 060 * <PRE> 061 * SetNotificationDestinationRequest ::= SEQUENCE { 062 * notificationManagerID OCTET STRING, 063 * notificationDestinationID OCTET STRING, 064 * destinationDetails SEQUENCE OF OCTET STRING, 065 * changeType [0] ENUMERATED { 066 * replace (0), 067 * add (1), 068 * delete (2) } DEFAULT replace } 069 * </PRE> 070 */ 071 @NotMutable() 072 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 073 public final class SetNotificationDestinationExtendedRequest 074 extends ExtendedRequest 075 { 076 /** 077 * The OID (1.3.6.1.4.1.30221.2.6.36) for the set notification destination 078 * extended request. 079 */ 080 public static final String SET_NOTIFICATION_DESTINATION_REQUEST_OID = 081 "1.3.6.1.4.1.30221.2.6.36"; 082 083 084 085 /** 086 * The BER type for the value sequence element that specifies the destination 087 * details change type. 088 */ 089 private static final byte BER_TYPE_CHANGE_TYPE = (byte) 0x80; 090 091 092 093 /** 094 * The serial version UID for this serializable class. 095 */ 096 private static final long serialVersionUID = 8651862605802389433L; 097 098 099 100 // The implementation-specific details for the notification destination. 101 private final List<ASN1OctetString> destinationDetails; 102 103 // The change type for the destination details. 104 private final SetNotificationDestinationChangeType changeType; 105 106 // The notification destination ID. 107 private final String destinationID; 108 109 // The notification manager ID. 110 private final String managerID; 111 112 113 114 /** 115 * Creates a new set notification destination extended request with the 116 * provided information. 117 * 118 * @param managerID The notification manager ID. It must not be 119 * {@code null}. 120 * @param destinationID The notification destination ID. It must not 121 * be {@code null}. 122 * @param destinationDetails The implementation-specific details for the 123 * notification destination. At least one detail 124 * value must be provided. 125 */ 126 public SetNotificationDestinationExtendedRequest(final String managerID, 127 final String destinationID, 128 final ASN1OctetString... destinationDetails) 129 { 130 this(managerID, destinationID, StaticUtils.toList(destinationDetails), 131 SetNotificationDestinationChangeType.REPLACE); 132 } 133 134 135 136 /** 137 * Creates a new set notification destination extended request with the 138 * provided information. 139 * 140 * @param managerID The notification manager ID. It must not be 141 * {@code null}. 142 * @param destinationID The notification destination ID. It must not 143 * be {@code null}. 144 * @param destinationDetails The implementation-specific details for the 145 * notification destination. At least one detail 146 * value must be provided. 147 * @param controls The set of controls to include in the request. 148 * It may be {@code null} or empty if no controls 149 * are needed. 150 */ 151 public SetNotificationDestinationExtendedRequest(final String managerID, 152 final String destinationID, 153 final Collection<ASN1OctetString> destinationDetails, 154 final Control... controls) 155 { 156 this(managerID, destinationID, destinationDetails, 157 SetNotificationDestinationChangeType.REPLACE, controls); 158 } 159 160 161 162 /** 163 * Creates a new set notification destination extended request with the 164 * provided information. 165 * 166 * @param managerID The notification manager ID. It must not be 167 * {@code null}. 168 * @param destinationID The notification destination ID. It must not 169 * be {@code null}. 170 * @param destinationDetails The implementation-specific details for the 171 * notification destination. At least one detail 172 * value must be provided. 173 * @param changeType The change type for the destination details. 174 * @param controls The set of controls to include in the request. 175 * It may be {@code null} or empty if no controls 176 * are needed. 177 */ 178 public SetNotificationDestinationExtendedRequest(final String managerID, 179 final String destinationID, 180 final Collection<ASN1OctetString> destinationDetails, 181 final SetNotificationDestinationChangeType changeType, 182 final Control... controls) 183 { 184 super(SET_NOTIFICATION_DESTINATION_REQUEST_OID, 185 encodeValue(managerID, destinationID, destinationDetails, changeType), 186 controls); 187 188 this.managerID = managerID; 189 this.destinationID = destinationID; 190 this.destinationDetails = Collections.unmodifiableList( 191 new ArrayList<ASN1OctetString>(destinationDetails)); 192 193 if (changeType == null) 194 { 195 this.changeType = SetNotificationDestinationChangeType.REPLACE; 196 } 197 else 198 { 199 this.changeType = changeType; 200 } 201 } 202 203 204 205 /** 206 * Creates a new set notification destination extended request from the 207 * provided generic extended request. 208 * 209 * @param extendedRequest The generic extended request to use to create this 210 * set notification destination extended request. 211 * 212 * @throws LDAPException If a problem occurs while decoding the request. 213 */ 214 public SetNotificationDestinationExtendedRequest( 215 final ExtendedRequest extendedRequest) 216 throws LDAPException 217 { 218 super(extendedRequest); 219 220 final ASN1OctetString value = extendedRequest.getValue(); 221 if (value == null) 222 { 223 throw new LDAPException(ResultCode.DECODING_ERROR, 224 ERR_SET_NOTIFICATION_DEST_REQ_DECODE_NO_VALUE.get()); 225 } 226 227 try 228 { 229 final ASN1Element[] elements = 230 ASN1Sequence.decodeAsSequence(value.getValue()).elements(); 231 managerID = 232 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 233 destinationID = 234 ASN1OctetString.decodeAsOctetString(elements[1]).stringValue(); 235 236 final ASN1Element[] detailElements = 237 ASN1Sequence.decodeAsSequence(elements[2]).elements(); 238 final ArrayList<ASN1OctetString> detailList = 239 new ArrayList<ASN1OctetString>(detailElements.length); 240 for (final ASN1Element e : detailElements) 241 { 242 detailList.add(ASN1OctetString.decodeAsOctetString(e)); 243 } 244 destinationDetails = Collections.unmodifiableList(detailList); 245 246 SetNotificationDestinationChangeType ct = 247 SetNotificationDestinationChangeType.REPLACE; 248 for (int i=3; i < elements.length; i++) 249 { 250 final ASN1Element e = elements[i]; 251 switch (e.getType()) 252 { 253 case BER_TYPE_CHANGE_TYPE: 254 final int ctIntValue = 255 ASN1Enumerated.decodeAsEnumerated(e).intValue(); 256 ct = SetNotificationDestinationChangeType.valueOf(ctIntValue); 257 if (ct == null) 258 { 259 throw new LDAPException(ResultCode.DECODING_ERROR, 260 ERR_SET_NOTIFICATION_DEST_REQ_INVALID_CT.get(ctIntValue)); 261 } 262 break; 263 264 default: 265 throw new LDAPException(ResultCode.DECODING_ERROR, 266 ERR_SET_NOTIFICATION_DEST_REQ_INVALID_ELEMENT_TYPE.get( 267 StaticUtils.toHex(e.getType()))); 268 } 269 } 270 271 changeType = ct; 272 } 273 catch (final LDAPException le) 274 { 275 Debug.debugException(le); 276 throw le; 277 } 278 catch (final Exception e) 279 { 280 Debug.debugException(e); 281 throw new LDAPException(ResultCode.DECODING_ERROR, 282 ERR_SET_NOTIFICATION_DEST_REQ_ERROR_DECODING_VALUE.get( 283 StaticUtils.getExceptionMessage(e)), 284 e); 285 } 286 } 287 288 289 290 /** 291 * Encodes the provided information into an ASN.1 octet string suitable for 292 * use as the value of this extended request. 293 * 294 * @param managerID The notification manager ID. It must not be 295 * {@code null}. 296 * @param destinationID The notification destination ID. It must not 297 * be {@code null}. 298 * @param destinationDetails The implementation-specific details for the 299 * notification destination. At least one detail 300 * value must be provided. 301 * @param changeType The change type for the destination details. 302 * 303 * @return The ASN.1 octet string containing the encoded value. 304 */ 305 private static ASN1OctetString encodeValue(final String managerID, 306 final String destinationID, 307 final Collection<ASN1OctetString> destinationDetails, 308 final SetNotificationDestinationChangeType changeType) 309 { 310 Validator.ensureNotNull(managerID); 311 Validator.ensureNotNull(destinationID); 312 Validator.ensureNotNull(destinationDetails); 313 Validator.ensureFalse(destinationDetails.isEmpty()); 314 315 final ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(4); 316 elements.add(new ASN1OctetString(managerID)); 317 elements.add(new ASN1OctetString(destinationID)); 318 elements.add(new ASN1Sequence( 319 new ArrayList<ASN1Element>(destinationDetails))); 320 321 if ((changeType != null) && 322 (changeType != SetNotificationDestinationChangeType.REPLACE)) 323 { 324 elements.add(new ASN1Enumerated(BER_TYPE_CHANGE_TYPE, 325 changeType.intValue())); 326 } 327 328 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 329 } 330 331 332 333 /** 334 * Retrieves the notification manager ID. 335 * 336 * @return The notification manager ID. 337 */ 338 public String getManagerID() 339 { 340 return managerID; 341 } 342 343 344 345 /** 346 * Retrieves the notification destination ID. 347 * 348 * @return The notification destination ID. 349 */ 350 public String getDestinationID() 351 { 352 return destinationID; 353 } 354 355 356 357 /** 358 * Retrieves the implementation-specific details for the notification 359 * destination. 360 * 361 * @return The implementation-specific details for the notification 362 * destination. 363 */ 364 public List<ASN1OctetString> getDestinationDetails() 365 { 366 return destinationDetails; 367 } 368 369 370 371 /** 372 * Retrieves the change type for the destination details. 373 * 374 * @return The change type for the destination details. 375 */ 376 public SetNotificationDestinationChangeType getChangeType() 377 { 378 return changeType; 379 } 380 381 382 383 /** 384 * {@inheritDoc} 385 */ 386 @Override() 387 public SetNotificationDestinationExtendedRequest duplicate() 388 { 389 return duplicate(getControls()); 390 } 391 392 393 394 /** 395 * {@inheritDoc} 396 */ 397 @Override() 398 public SetNotificationDestinationExtendedRequest 399 duplicate(final Control[] controls) 400 { 401 final SetNotificationDestinationExtendedRequest r = 402 new SetNotificationDestinationExtendedRequest(managerID, 403 destinationID, destinationDetails, changeType, controls); 404 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 405 return r; 406 } 407 408 409 410 /** 411 * {@inheritDoc} 412 */ 413 @Override() 414 public String getExtendedRequestName() 415 { 416 return INFO_EXTENDED_REQUEST_NAME_SET_NOTIFICATION_DEST.get(); 417 } 418 419 420 421 /** 422 * {@inheritDoc} 423 */ 424 @Override() 425 public void toString(final StringBuilder buffer) 426 { 427 buffer.append("SetNotificationDestinationExtendedRequest(managerID='"); 428 buffer.append(managerID); 429 buffer.append("', destinationID='"); 430 buffer.append(destinationID); 431 buffer.append("', destinationDetails=ASN1OctetString["); 432 buffer.append(destinationDetails.size()); 433 buffer.append("], changeType="); 434 buffer.append(changeType.name()); 435 436 final Control[] controls = getControls(); 437 if (controls.length > 0) 438 { 439 buffer.append(", controls={"); 440 for (int i=0; i < controls.length; i++) 441 { 442 if (i > 0) 443 { 444 buffer.append(", "); 445 } 446 447 buffer.append(controls[i]); 448 } 449 buffer.append('}'); 450 } 451 452 buffer.append(')'); 453 } 454 }