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 */
021package com.unboundid.ldap.sdk.migrate.jndi;
022
023
024
025import javax.naming.NamingException;
026import javax.naming.ldap.ExtendedResponse;
027
028import com.unboundid.asn1.ASN1Exception;
029import com.unboundid.asn1.ASN1OctetString;
030import com.unboundid.ldap.sdk.ExtendedResult;
031import com.unboundid.ldap.sdk.ResultCode;
032import com.unboundid.util.NotMutable;
033import com.unboundid.util.StaticUtils;
034import com.unboundid.util.ThreadSafety;
035import com.unboundid.util.ThreadSafetyLevel;
036
037
038
039/**
040 * This class provides a mechanism for converting between an LDAP extended
041 * response as used in JNDI and one used in the UnboundID LDAP SDK for Java.
042 *
043 * @see  ExtendedResult
044 */
045@NotMutable()
046@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
047public final class JNDIExtendedResponse
048       implements ExtendedResponse
049{
050  /**
051   * The serial version UID for this serializable class.
052   */
053  private static final long serialVersionUID = -9210853181740736844L;
054
055
056
057  // The SDK extended result that backs this JNDI extended response.
058  private final ExtendedResult r;
059
060
061
062  /**
063   * Creates a new JNDI extended response from the provided SDK extended result.
064   *
065   * @param  r  The SDK extended result to use to create this JNDI extended
066   *            response.
067   */
068  public JNDIExtendedResponse(final ExtendedResult r)
069  {
070    this.r = r;
071  }
072
073
074
075  /**
076   * Creates a new JNDI extended response from the provided JNDI extended
077   * response.
078   *
079   * @param  r  The JNDI extended response to use to create this JNDI extended
080   *            response.
081   *
082   * @throws  NamingException  If a problem occurs while trying to create this
083   *                           JNDI extended response.
084   */
085  public JNDIExtendedResponse(final ExtendedResponse r)
086         throws NamingException
087  {
088    this(toSDKExtendedResult(r));
089  }
090
091
092
093  /**
094   * Creates a new JNDI extended response with the provided information.
095   *
096   * @param  id        The object identifier for the response, or {@code null}
097   *                   if there should not be a value.
098   * @param  berValue  A byte array containing the encoded value (including BER
099   *                   type and length), or {@code null} if the response should
100   *                   not have a value.
101   * @param  offset    The offset within the provided array at which the value
102   *                   should begin.
103   * @param  length    The number of bytes contained in the value.
104   *
105   * @throws  NamingException  If a problem occurs while creating the response.
106   */
107  JNDIExtendedResponse(final String id, final byte[] berValue, final int offset,
108                       final int length)
109       throws NamingException
110  {
111    final ASN1OctetString value;
112    if (berValue == null)
113    {
114      value = null;
115    }
116    else
117    {
118      try
119      {
120        if ((offset == 0) && (length == berValue.length))
121        {
122          value = ASN1OctetString.decodeAsOctetString(berValue);
123        }
124        else
125        {
126          final byte[] valueBytes = new byte[length];
127          System.arraycopy(berValue, offset, valueBytes, 0, length);
128          value = ASN1OctetString.decodeAsOctetString(valueBytes);
129        }
130      }
131      catch (ASN1Exception ae)
132      {
133        throw new NamingException(StaticUtils.getExceptionMessage(ae));
134      }
135    }
136
137    r = new ExtendedResult(-1, ResultCode.SUCCESS, null, null, null, id, value,
138                           null);
139  }
140
141
142
143  /**
144   * Retrieves the object identifier for this extended response, if available.
145   *
146   * @return  The object identifier for this extended response, or {@code null}
147   *          if there is no OID.
148   */
149  public String getID()
150  {
151    return r.getOID();
152  }
153
154
155
156  /**
157   * Retrieves the encoded value for this extended response (including the BER
158   * type and length), if available.
159   *
160   * @return  The encoded value for this extended response, or {@code null} if
161   *          there is no value.
162   */
163  public byte[] getEncodedValue()
164  {
165    final ASN1OctetString value = r.getValue();
166    if (value == null)
167    {
168      return null;
169    }
170    else
171    {
172      return value.encode();
173    }
174  }
175
176
177
178  /**
179   * Retrieves an LDAP SDK extended result that is the equivalent of this JNDI
180   * extended response.
181   *
182   * @return  An LDAP SDK extended result that is the equivalent of this JNDI
183   *          extended response.
184   */
185  public ExtendedResult toSDKExtendedResult()
186  {
187    return r;
188  }
189
190
191
192  /**
193   * Retrieves an LDAP SDK extended result that is the equivalent of the
194   * provided JNDI extended response.
195   *
196   * @param  r  The JNDI extended response to convert to an LDAP SDK extended
197   *            result.
198   *
199   * @return  The LDAP SDK extended result converted from the provided JNDI
200   *          extended response.
201   *
202   * @throws  NamingException  If a problem occurs while decoding the provided
203   *                           JNDI extended response as an SDK extended result.
204   */
205  public static ExtendedResult toSDKExtendedResult(final ExtendedResponse r)
206         throws NamingException
207  {
208    if (r == null)
209    {
210      return null;
211    }
212
213    final JNDIExtendedResponse response;
214    final byte[] encodedValue = r.getEncodedValue();
215    if (encodedValue == null)
216    {
217      response = new JNDIExtendedResponse(r.getID(), null, 0, 0);
218    }
219    else
220    {
221      response = new JNDIExtendedResponse(r.getID(), encodedValue, 0,
222           encodedValue.length);
223    }
224
225    return response.toSDKExtendedResult();
226  }
227
228
229
230  /**
231   * Retrieves a string representation of this JNDI extended response.
232   *
233   * @return  A string representation of this JNDI response.
234   */
235  @Override()
236  public String toString()
237  {
238    return r.toString();
239  }
240}