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