001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.protocols.ldap;
028 import org.opends.messages.Message;
029
030
031
032 import java.util.ArrayList;
033
034 import org.opends.server.protocols.asn1.ASN1Element;
035 import org.opends.server.protocols.asn1.ASN1OctetString;
036 import org.opends.server.protocols.asn1.ASN1Sequence;
037 import org.opends.server.types.DebugLogLevel;
038 import org.opends.server.types.LDAPException;
039
040 import static org.opends.server.loggers.debug.DebugLogger.*;
041 import org.opends.server.loggers.debug.DebugTracer;
042 import static org.opends.messages.ProtocolMessages.*;
043 import static org.opends.server.protocols.ldap.LDAPConstants.*;
044 import static org.opends.server.protocols.ldap.LDAPResultCode.*;
045 import static org.opends.server.util.ServerConstants.*;
046
047
048 /**
049 * This class defines the structures and methods for an LDAP extended request
050 * protocol op, which is used to request some special type of processing defined
051 * in an extension to the LDAP protocol.
052 */
053 public class ExtendedRequestProtocolOp
054 extends ProtocolOp
055 {
056 /**
057 * The tracer object for the debug logger.
058 */
059 private static final DebugTracer TRACER = getTracer();
060
061 // The value for this extended request.
062 private ASN1OctetString value;
063
064 // The OID for this extended request.
065 private String oid;
066
067
068
069 /**
070 * Creates a new extended request protocol op with the specified OID and no
071 * value.
072 *
073 * @param oid The OID for this extended request.
074 */
075 public ExtendedRequestProtocolOp(String oid)
076 {
077 this.oid = oid;
078 this.value = null;
079 }
080
081
082
083 /**
084 * Creates a new extended request protocol op with the specified OID and
085 * value.
086 *
087 * @param oid The OID for this extended request.
088 * @param value The value for this extended request.
089 */
090 public ExtendedRequestProtocolOp(String oid, ASN1OctetString value)
091 {
092 this.oid = oid;
093 this.value = value;
094 }
095
096
097
098 /**
099 * Retrieves the OID for this extended request.
100 *
101 * @return The OID for this extended request.
102 */
103 public String getOID()
104 {
105 return oid;
106 }
107
108
109
110 /**
111 * Specifies the OID for this extended request.
112 *
113 * @param oid The OID for this extended request.
114 */
115 public void setOID(String oid)
116 {
117 this.oid = oid;
118 }
119
120
121
122 /**
123 * Retrieves the value for this extended request.
124 *
125 * @return The value for this extended request, or <CODE>null</CODE> if there
126 * is no value.
127 */
128 public ASN1OctetString getValue()
129 {
130 return value;
131 }
132
133
134
135 /**
136 * Specifies the value for this extended request.
137 *
138 * @param value The value for this extended request.
139 */
140 public void setValue(ASN1OctetString value)
141 {
142 this.value = value;
143 }
144
145
146
147 /**
148 * Retrieves the BER type for this protocol op.
149 *
150 * @return The BER type for this protocol op.
151 */
152 public byte getType()
153 {
154 return OP_TYPE_EXTENDED_REQUEST;
155 }
156
157
158
159 /**
160 * Retrieves the name for this protocol op type.
161 *
162 * @return The name for this protocol op type.
163 */
164 public String getProtocolOpName()
165 {
166 return "Extended Request";
167 }
168
169
170
171 /**
172 * Encodes this protocol op to an ASN.1 element suitable for including in an
173 * LDAP message.
174 *
175 * @return The ASN.1 element containing the encoded protocol op.
176 */
177 public ASN1Element encode()
178 {
179 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
180 elements.add(new ASN1OctetString(TYPE_EXTENDED_REQUEST_OID, oid));
181
182 if (value != null)
183 {
184 value.setType(TYPE_EXTENDED_REQUEST_VALUE);
185 elements.add(value);
186 }
187
188 return new ASN1Sequence(OP_TYPE_EXTENDED_REQUEST, elements);
189 }
190
191
192
193 /**
194 * Decodes the provided ASN.1 element as an LDAP extended request protocol op.
195 *
196 * @param element The ASN.1 element to be decoded.
197 *
198 * @return The decoded extended request protocol op.
199 *
200 * @throws LDAPException If a problem occurs while attempting to decode the
201 * provided ASN.1 element as an LDAP extended request
202 * protocol op.
203 */
204 public static ExtendedRequestProtocolOp decodeExtendedRequest(ASN1Element
205 element)
206 throws LDAPException
207 {
208 ArrayList<ASN1Element> elements;
209 try
210 {
211 elements = element.decodeAsSequence().elements();
212 }
213 catch (Exception e)
214 {
215 if (debugEnabled())
216 {
217 TRACER.debugCaught(DebugLogLevel.ERROR, e);
218 }
219
220 Message message =
221 ERR_LDAP_EXTENDED_REQUEST_DECODE_SEQUENCE.get(String.valueOf(e));
222 throw new LDAPException(PROTOCOL_ERROR, message, e);
223 }
224
225
226 int numElements = elements.size();
227 if ((numElements < 1) || (numElements > 2))
228 {
229 Message message = ERR_LDAP_EXTENDED_REQUEST_DECODE_INVALID_ELEMENT_COUNT.
230 get(numElements);
231 throw new LDAPException(PROTOCOL_ERROR, message);
232 }
233
234
235 String oid;
236 try
237 {
238 oid = elements.get(0).decodeAsOctetString().stringValue();
239 }
240 catch (Exception e)
241 {
242 if (debugEnabled())
243 {
244 TRACER.debugCaught(DebugLogLevel.ERROR, e);
245 }
246
247 Message message =
248 ERR_LDAP_EXTENDED_REQUEST_DECODE_OID.get(String.valueOf(e));
249 throw new LDAPException(PROTOCOL_ERROR, message, e);
250 }
251
252
253 ASN1OctetString value;
254 if (numElements == 2)
255 {
256 try
257 {
258 value = elements.get(1).decodeAsOctetString();
259 }
260 catch (Exception e)
261 {
262 if (debugEnabled())
263 {
264 TRACER.debugCaught(DebugLogLevel.ERROR, e);
265 }
266
267 Message message =
268 ERR_LDAP_EXTENDED_REQUEST_DECODE_VALUE.get(String.valueOf(e));
269 throw new LDAPException(PROTOCOL_ERROR, message, e);
270 }
271 }
272 else
273 {
274 value = null;
275 }
276
277
278 return new ExtendedRequestProtocolOp(oid, value);
279 }
280
281
282
283 /**
284 * Appends a string representation of this LDAP protocol op to the provided
285 * buffer.
286 *
287 * @param buffer The buffer to which the string should be appended.
288 */
289 public void toString(StringBuilder buffer)
290 {
291 buffer.append("ExtendedRequest(oid=");
292 buffer.append(oid);
293
294 if (value != null)
295 {
296 buffer.append(", value=");
297 value.toString(buffer);
298 }
299
300 buffer.append(")");
301 }
302
303
304
305 /**
306 * Appends a multi-line string representation of this LDAP protocol op to the
307 * provided buffer.
308 *
309 * @param buffer The buffer to which the information should be appended.
310 * @param indent The number of spaces from the margin that the lines should
311 * be indented.
312 */
313 public void toString(StringBuilder buffer, int indent)
314 {
315 StringBuilder indentBuf = new StringBuilder(indent);
316 for (int i=0 ; i < indent; i++)
317 {
318 indentBuf.append(' ');
319 }
320
321 buffer.append(indentBuf);
322 buffer.append("Extended Request");
323 buffer.append(EOL);
324
325 buffer.append(indentBuf);
326 buffer.append(" OID: ");
327 buffer.append(oid);
328 buffer.append(EOL);
329
330 if (value != null)
331 {
332 buffer.append(indentBuf);
333 buffer.append(" Value:");
334 buffer.append(EOL);
335 value.toString(buffer, indent+4);
336 }
337 }
338 }
339