001 /* 002 * Copyright 2009-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2009-2014 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 com.unboundid.asn1.ASN1Buffer; 026 import com.unboundid.asn1.ASN1BufferSequence; 027 import com.unboundid.asn1.ASN1Element; 028 import com.unboundid.asn1.ASN1OctetString; 029 import com.unboundid.asn1.ASN1Sequence; 030 import com.unboundid.asn1.ASN1StreamReader; 031 import com.unboundid.asn1.ASN1StreamReaderSequence; 032 import com.unboundid.ldap.sdk.Control; 033 import com.unboundid.ldap.sdk.ExtendedRequest; 034 import com.unboundid.ldap.sdk.LDAPException; 035 import com.unboundid.ldap.sdk.ResultCode; 036 import com.unboundid.util.InternalUseOnly; 037 038 import static com.unboundid.ldap.protocol.ProtocolMessages.*; 039 import static com.unboundid.util.Debug.*; 040 import static com.unboundid.util.StaticUtils.*; 041 import static com.unboundid.util.Validator.*; 042 043 044 045 /** 046 * This class provides an implementation of an LDAP extended request protocol 047 * op. 048 */ 049 @InternalUseOnly() 050 public final class ExtendedRequestProtocolOp 051 implements ProtocolOp 052 { 053 /** 054 * The BER type for the OID element. 055 */ 056 public static final byte TYPE_OID = (byte) 0x80; 057 058 059 060 /** 061 * The BER type for the value element. 062 */ 063 public static final byte TYPE_VALUE = (byte) 0x81; 064 065 066 067 /** 068 * The serial version UID for this serializable class. 069 */ 070 private static final long serialVersionUID = -5343424210200494377L; 071 072 073 074 // The value for this extended request. 075 private final ASN1OctetString value; 076 077 // The OID for this extended request. 078 private final String oid; 079 080 081 082 /** 083 * Creates a new extended request protocol op with the provided information. 084 * 085 * @param oid The OID for this extended request. 086 * @param value The value for this extended request, or {@code null} if 087 * there should not be a value. 088 */ 089 public ExtendedRequestProtocolOp(final String oid, 090 final ASN1OctetString value) 091 { 092 this.oid = oid; 093 094 if (value == null) 095 { 096 this.value = null; 097 } 098 else 099 { 100 this.value = new ASN1OctetString(TYPE_VALUE, value.getValue()); 101 } 102 } 103 104 105 106 /** 107 * Creates a new extended request protocol op from the provided extended 108 * request object. 109 * 110 * @param request The extended request object to use to create this protocol 111 * op. 112 */ 113 public ExtendedRequestProtocolOp(final ExtendedRequest request) 114 { 115 oid = request.getOID(); 116 value = request.getValue(); 117 } 118 119 120 121 /** 122 * Creates a new extended request protocol op read from the provided ASN.1 123 * stream reader. 124 * 125 * @param reader The ASN.1 stream reader from which to read the extended 126 * request protocol op. 127 * 128 * @throws LDAPException If a problem occurs while reading or parsing the 129 * extended request. 130 */ 131 ExtendedRequestProtocolOp(final ASN1StreamReader reader) 132 throws LDAPException 133 { 134 try 135 { 136 final ASN1StreamReaderSequence opSequence = reader.beginSequence(); 137 oid = reader.readString(); 138 ensureNotNull(oid); 139 140 if (opSequence.hasMoreElements()) 141 { 142 value = new ASN1OctetString(TYPE_VALUE, reader.readBytes()); 143 } 144 else 145 { 146 value = null; 147 } 148 } 149 catch (Exception e) 150 { 151 debugException(e); 152 153 throw new LDAPException(ResultCode.DECODING_ERROR, 154 ERR_EXTENDED_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), e); 155 } 156 } 157 158 159 160 /** 161 * Retrieves the OID for this extended request. 162 * 163 * @return The OID for this extended request. 164 */ 165 public String getOID() 166 { 167 return oid; 168 } 169 170 171 172 /** 173 * Retrieves the value for this extended request, if any. 174 * 175 * @return The value for this extended request, or {@code null} if there is 176 * no value. 177 */ 178 public ASN1OctetString getValue() 179 { 180 return value; 181 } 182 183 184 185 /** 186 * {@inheritDoc} 187 */ 188 public byte getProtocolOpType() 189 { 190 return LDAPMessage.PROTOCOL_OP_TYPE_EXTENDED_REQUEST; 191 } 192 193 194 195 /** 196 * {@inheritDoc} 197 */ 198 public ASN1Element encodeProtocolOp() 199 { 200 if (value == null) 201 { 202 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_EXTENDED_REQUEST, 203 new ASN1OctetString(TYPE_OID, oid)); 204 } 205 else 206 { 207 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_EXTENDED_REQUEST, 208 new ASN1OctetString(TYPE_OID, oid), 209 value); 210 } 211 } 212 213 214 215 /** 216 * Decodes the provided ASN.1 element as an extended request protocol op. 217 * 218 * @param element The ASN.1 element to be decoded. 219 * 220 * @return The decoded extended request protocol op. 221 * 222 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 223 * an extended request protocol op. 224 */ 225 public static ExtendedRequestProtocolOp decodeProtocolOp( 226 final ASN1Element element) 227 throws LDAPException 228 { 229 try 230 { 231 final ASN1Element[] elements = 232 ASN1Sequence.decodeAsSequence(element).elements(); 233 final String oid = 234 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 235 236 final ASN1OctetString value; 237 if (elements.length == 1) 238 { 239 value = null; 240 } 241 else 242 { 243 value = ASN1OctetString.decodeAsOctetString(elements[1]); 244 } 245 246 return new ExtendedRequestProtocolOp(oid, value); 247 } 248 catch (final Exception e) 249 { 250 debugException(e); 251 throw new LDAPException(ResultCode.DECODING_ERROR, 252 ERR_EXTENDED_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), 253 e); 254 } 255 } 256 257 258 259 /** 260 * {@inheritDoc} 261 */ 262 public void writeTo(final ASN1Buffer buffer) 263 { 264 final ASN1BufferSequence opSequence = 265 buffer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_EXTENDED_REQUEST); 266 buffer.addOctetString(TYPE_OID, oid); 267 268 if (value != null) 269 { 270 buffer.addOctetString(TYPE_VALUE, value.getValue()); 271 } 272 opSequence.end(); 273 } 274 275 276 277 /** 278 * Creates an extended request from this protocol op. 279 * 280 * @param controls The set of controls to include in the extended request. 281 * It may be empty or {@code null} if no controls should be 282 * included. 283 * 284 * @return The extended request that was created. 285 */ 286 public ExtendedRequest toExtendedRequest(final Control... controls) 287 { 288 return new ExtendedRequest(oid, value, controls); 289 } 290 291 292 293 /** 294 * Retrieves a string representation of this protocol op. 295 * 296 * @return A string representation of this protocol op. 297 */ 298 @Override() 299 public String toString() 300 { 301 final StringBuilder buffer = new StringBuilder(); 302 toString(buffer); 303 return buffer.toString(); 304 } 305 306 307 308 /** 309 * {@inheritDoc} 310 */ 311 public void toString(final StringBuilder buffer) 312 { 313 buffer.append("ExtendedRequestProtocolOp(oid='"); 314 buffer.append(oid); 315 buffer.append("')"); 316 } 317 }