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 }