001/*
002 * Copyright 2009-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2009-2019 Ping Identity Corporation
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 (final 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  @Override()
150  public String getID()
151  {
152    return r.getOID();
153  }
154
155
156
157  /**
158   * Retrieves the encoded value for this extended response (including the BER
159   * type and length), if available.
160   *
161   * @return  The encoded value for this extended response, or {@code null} if
162   *          there is no value.
163   */
164  @Override()
165  public byte[] getEncodedValue()
166  {
167    final ASN1OctetString value = r.getValue();
168    if (value == null)
169    {
170      return null;
171    }
172    else
173    {
174      return value.encode();
175    }
176  }
177
178
179
180  /**
181   * Retrieves an LDAP SDK extended result that is the equivalent of this JNDI
182   * extended response.
183   *
184   * @return  An LDAP SDK extended result that is the equivalent of this JNDI
185   *          extended response.
186   */
187  public ExtendedResult toSDKExtendedResult()
188  {
189    return r;
190  }
191
192
193
194  /**
195   * Retrieves an LDAP SDK extended result that is the equivalent of the
196   * provided JNDI extended response.
197   *
198   * @param  r  The JNDI extended response to convert to an LDAP SDK extended
199   *            result.
200   *
201   * @return  The LDAP SDK extended result converted from the provided JNDI
202   *          extended response.
203   *
204   * @throws  NamingException  If a problem occurs while decoding the provided
205   *                           JNDI extended response as an SDK extended result.
206   */
207  public static ExtendedResult toSDKExtendedResult(final ExtendedResponse r)
208         throws NamingException
209  {
210    if (r == null)
211    {
212      return null;
213    }
214
215    final JNDIExtendedResponse response;
216    final byte[] encodedValue = r.getEncodedValue();
217    if (encodedValue == null)
218    {
219      response = new JNDIExtendedResponse(r.getID(), null, 0, 0);
220    }
221    else
222    {
223      response = new JNDIExtendedResponse(r.getID(), encodedValue, 0,
224           encodedValue.length);
225    }
226
227    return response.toSDKExtendedResult();
228  }
229
230
231
232  /**
233   * Retrieves a string representation of this JNDI extended response.
234   *
235   * @return  A string representation of this JNDI response.
236   */
237  @Override()
238  public String toString()
239  {
240    return r.toString();
241  }
242}