001/* 002 * Copyright 2009-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2009-2024 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2009-2024 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.migrate.jndi; 037 038 039 040import javax.naming.NamingException; 041import javax.naming.ldap.ExtendedResponse; 042 043import com.unboundid.asn1.ASN1Exception; 044import com.unboundid.asn1.ASN1OctetString; 045import com.unboundid.ldap.sdk.ExtendedResult; 046import com.unboundid.ldap.sdk.ResultCode; 047import com.unboundid.util.NotMutable; 048import com.unboundid.util.NotNull; 049import com.unboundid.util.Nullable; 050import com.unboundid.util.StaticUtils; 051import com.unboundid.util.ThreadSafety; 052import com.unboundid.util.ThreadSafetyLevel; 053 054 055 056/** 057 * This class provides a mechanism for converting between an LDAP extended 058 * response as used in JNDI and one used in the UnboundID LDAP SDK for Java. 059 * 060 * @see ExtendedResult 061 */ 062@NotMutable() 063@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 064public final class JNDIExtendedResponse 065 implements ExtendedResponse 066{ 067 /** 068 * The serial version UID for this serializable class. 069 */ 070 private static final long serialVersionUID = -9210853181740736844L; 071 072 073 074 // The SDK extended result that backs this JNDI extended response. 075 @NotNull private final ExtendedResult r; 076 077 078 079 /** 080 * Creates a new JNDI extended response from the provided SDK extended result. 081 * 082 * @param r The SDK extended result to use to create this JNDI extended 083 * response. 084 */ 085 public JNDIExtendedResponse(@NotNull final ExtendedResult r) 086 { 087 this.r = r; 088 } 089 090 091 092 /** 093 * Creates a new JNDI extended response from the provided JNDI extended 094 * response. 095 * 096 * @param r The JNDI extended response to use to create this JNDI extended 097 * response. 098 * 099 * @throws NamingException If a problem occurs while trying to create this 100 * JNDI extended response. 101 */ 102 public JNDIExtendedResponse(@NotNull final ExtendedResponse r) 103 throws NamingException 104 { 105 this(toSDKExtendedResult(r)); 106 } 107 108 109 110 /** 111 * Creates a new JNDI extended response with the provided information. 112 * 113 * @param id The object identifier for the response, or {@code null} 114 * if there should not be a value. 115 * @param berValue A byte array containing the encoded value (including BER 116 * type and length), or {@code null} if the response should 117 * not have a value. 118 * @param offset The offset within the provided array at which the value 119 * should begin. 120 * @param length The number of bytes contained in the value. 121 * 122 * @throws NamingException If a problem occurs while creating the response. 123 */ 124 JNDIExtendedResponse(@Nullable final String id, 125 @Nullable final byte[] berValue, final int offset, 126 final int length) 127 throws NamingException 128 { 129 final ASN1OctetString value; 130 if (berValue == null) 131 { 132 value = null; 133 } 134 else 135 { 136 final byte[] trimmedBytes; 137 if ((offset == 0) && (length == berValue.length)) 138 { 139 trimmedBytes = berValue; 140 } 141 else 142 { 143 trimmedBytes = new byte[length]; 144 System.arraycopy(berValue, offset, trimmedBytes, 0, length); 145 } 146 147 if (JNDIConverter.includeTypeAndLengthInExtendedOpValues()) 148 { 149 try 150 { 151 value = ASN1OctetString.decodeAsOctetString(trimmedBytes); 152 } 153 catch (final ASN1Exception ae) 154 { 155 throw new NamingException(StaticUtils.getExceptionMessage(ae)); 156 } 157 } 158 else 159 { 160 value = new ASN1OctetString(trimmedBytes); 161 } 162 } 163 164 r = new ExtendedResult(-1, ResultCode.SUCCESS, null, null, null, id, value, 165 null); 166 } 167 168 169 170 /** 171 * Retrieves the object identifier for this extended response, if available. 172 * 173 * @return The object identifier for this extended response, or {@code null} 174 * if there is no OID. 175 */ 176 @Override() 177 @Nullable() 178 public String getID() 179 { 180 return r.getOID(); 181 } 182 183 184 185 /** 186 * Retrieves the encoded value for this extended response (including the BER 187 * type and length), if available. 188 * 189 * @return The encoded value for this extended response, or {@code null} if 190 * there is no value. 191 */ 192 @Override() 193 @Nullable() 194 public byte[] getEncodedValue() 195 { 196 final ASN1OctetString value = r.getValue(); 197 if (value == null) 198 { 199 return null; 200 } 201 else 202 { 203 if (JNDIConverter.includeTypeAndLengthInExtendedOpValues()) 204 { 205 return value.encode(); 206 } 207 else 208 { 209 return value.getValue(); 210 } 211 } 212 } 213 214 215 216 /** 217 * Retrieves an LDAP SDK extended result that is the equivalent of this JNDI 218 * extended response. 219 * 220 * @return An LDAP SDK extended result that is the equivalent of this JNDI 221 * extended response. 222 */ 223 @NotNull() 224 public ExtendedResult toSDKExtendedResult() 225 { 226 return r; 227 } 228 229 230 231 /** 232 * Retrieves an LDAP SDK extended result that is the equivalent of the 233 * provided JNDI extended response. 234 * 235 * @param r The JNDI extended response to convert to an LDAP SDK extended 236 * result. 237 * 238 * @return The LDAP SDK extended result converted from the provided JNDI 239 * extended response. 240 * 241 * @throws NamingException If a problem occurs while decoding the provided 242 * JNDI extended response as an SDK extended result. 243 */ 244 @Nullable() 245 public static ExtendedResult toSDKExtendedResult( 246 @Nullable final ExtendedResponse r) 247 throws NamingException 248 { 249 if (r == null) 250 { 251 return null; 252 } 253 254 final JNDIExtendedResponse response; 255 final byte[] encodedValue = r.getEncodedValue(); 256 if (encodedValue == null) 257 { 258 response = new JNDIExtendedResponse(r.getID(), null, 0, 0); 259 } 260 else 261 { 262 response = new JNDIExtendedResponse(r.getID(), encodedValue, 0, 263 encodedValue.length); 264 } 265 266 return response.toSDKExtendedResult(); 267 } 268 269 270 271 /** 272 * Retrieves a string representation of this JNDI extended response. 273 * 274 * @return A string representation of this JNDI response. 275 */ 276 @Override() 277 @NotNull() 278 public String toString() 279 { 280 return r.toString(); 281 } 282}