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.unboundidds.controls; 037 038 039 040import java.io.Serializable; 041 042import com.unboundid.asn1.ASN1Element; 043import com.unboundid.asn1.ASN1Null; 044import com.unboundid.asn1.ASN1OctetString; 045import com.unboundid.ldap.sdk.LDAPException; 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; 053import com.unboundid.util.Validator; 054 055import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 056 057 058 059/** 060 * This class provides a data structure which may be used to indicate the base 061 * DN to use for a join request. See the class-level documentation for the 062 * {@link JoinRequestControl} class for additional information and an example 063 * demonstrating its use. 064 * <BR> 065 * <BLOCKQUOTE> 066 * <B>NOTE:</B> This class, and other classes within the 067 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 068 * supported for use against Ping Identity, UnboundID, and 069 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 070 * for proprietary functionality or for external specifications that are not 071 * considered stable or mature enough to be guaranteed to work in an 072 * interoperable way with other types of LDAP servers. 073 * </BLOCKQUOTE> 074 */ 075@NotMutable() 076@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 077public final class JoinBaseDN 078 implements Serializable 079{ 080 /** 081 * The base type which indicates that the base DN for join processing should 082 * be the same as the base DN from the search request. 083 */ 084 public static final byte BASE_TYPE_SEARCH_BASE = (byte) 0x80; 085 086 087 088 /** 089 * The base type which indicates that the base DN for join processing should 090 * be the DN of the source entry. 091 */ 092 public static final byte BASE_TYPE_SOURCE_ENTRY_DN = (byte) 0x81; 093 094 095 096 /** 097 * The base type which indicates that the base DN for join processing should 098 * be a custom base DN. 099 */ 100 public static final byte BASE_TYPE_CUSTOM = (byte) 0x82; 101 102 103 104 /** 105 * The singleton instance that will be used for the "useSearchBaseDN" type. 106 */ 107 @NotNull private static final JoinBaseDN USE_SEARCH_BASE_DN = new JoinBaseDN( 108 BASE_TYPE_SEARCH_BASE, null); 109 110 111 112 /** 113 * The singleton instance that will be used for the "useSourceEntryDN" type. 114 */ 115 @NotNull private static final JoinBaseDN USE_SOURCE_ENTRY_DN = new JoinBaseDN( 116 BASE_TYPE_SOURCE_ENTRY_DN, null); 117 118 119 120 /** 121 * The serial version UID for this serializable class. 122 */ 123 private static final long serialVersionUID = -330303461586380445L; 124 125 126 127 // The base type value for this join base DN. 128 private final byte type; 129 130 // The base DN value to use if the custom type is used. 131 @Nullable private final String customBaseDN; 132 133 134 135 /** 136 * Creates a new join base DN with the provided information. 137 * 138 * @param type The base type value for this join base DN. 139 * @param customBaseDN The custom base DN to use, if appropriate. 140 */ 141 private JoinBaseDN(final byte type, @Nullable final String customBaseDN) 142 { 143 this.type = type; 144 this.customBaseDN = customBaseDN; 145 } 146 147 148 149 /** 150 * Creates a join base DN object which indicates that join processing should 151 * use the base DN from the search request. 152 * 153 * @return A join base DN object which indicates that join processing should 154 * use the base DN from the search request. 155 */ 156 @NotNull() 157 public static JoinBaseDN createUseSearchBaseDN() 158 { 159 return USE_SEARCH_BASE_DN; 160 } 161 162 163 164 /** 165 * Creates a join base DN object which indicates that join processing should 166 * use the DN of the source entry. 167 * 168 * @return A join base DN object which indicates that join processing should 169 * use the DN of the source entry. 170 */ 171 @NotNull() 172 public static JoinBaseDN createUseSourceEntryDN() 173 { 174 return USE_SOURCE_ENTRY_DN; 175 } 176 177 178 179 /** 180 * Creates a join base DN object which indicates that join processing should 181 * use the provided base DN. 182 * 183 * @param baseDN The custom base DN to use. It must not be {@code null}. 184 * 185 * @return A join base DN object which indicates that join processing should 186 * use the provided base DN. 187 */ 188 @NotNull() 189 public static JoinBaseDN createUseCustomBaseDN(@NotNull final String baseDN) 190 { 191 Validator.ensureNotNull(baseDN); 192 return new JoinBaseDN(BASE_TYPE_CUSTOM, baseDN); 193 } 194 195 196 197 /** 198 * Retrieves the base type for this join base DN. 199 * 200 * @return The base type for this join base DN. 201 */ 202 public byte getType() 203 { 204 return type; 205 } 206 207 208 209 /** 210 * Retrieves the base DN value to use for the custom base DN type. 211 * 212 * @return The base DN value to use for the custom base DN type, or 213 * {@code null} if the base DN should be the search base DN or the 214 * source entry DN. 215 */ 216 @Nullable() 217 public String getCustomBaseDN() 218 { 219 return customBaseDN; 220 } 221 222 223 224 /** 225 * Encodes this join base DN as appropriate for inclusion in an LDAP join 226 * request control. 227 * 228 * @return The encoded representation of this join base DN. 229 */ 230 @NotNull() 231 ASN1Element encode() 232 { 233 switch (type) 234 { 235 case BASE_TYPE_SEARCH_BASE: 236 case BASE_TYPE_SOURCE_ENTRY_DN: 237 return new ASN1Null(type); 238 239 case BASE_TYPE_CUSTOM: 240 return new ASN1OctetString(type, customBaseDN); 241 242 default: 243 // This should never happen. 244 return null; 245 } 246 } 247 248 249 250 /** 251 * Decodes the provided ASN.1 element as a join rule. 252 * 253 * @param element The element to be decoded. 254 * 255 * @return The decoded join rule. 256 * 257 * @throws LDAPException If a problem occurs while attempting to decode the 258 * provided element as a join rule. 259 */ 260 @NotNull() 261 static JoinBaseDN decode(@NotNull final ASN1Element element) 262 throws LDAPException 263 { 264 switch (element.getType()) 265 { 266 case BASE_TYPE_SEARCH_BASE: 267 return USE_SEARCH_BASE_DN; 268 269 case BASE_TYPE_SOURCE_ENTRY_DN: 270 return USE_SOURCE_ENTRY_DN; 271 272 case BASE_TYPE_CUSTOM: 273 return new JoinBaseDN(element.getType(), 274 element.decodeAsOctetString().stringValue()); 275 276 default: 277 throw new LDAPException(ResultCode.DECODING_ERROR, 278 ERR_JOIN_BASE_DECODE_INVALID_TYPE.get( 279 StaticUtils.toHex(element.getType()))); 280 } 281 } 282 283 284 285 /** 286 * Retrieves a string representation of this join base DN. 287 * 288 * @return A string representation of this join base DN. 289 */ 290 @Override() 291 @NotNull() 292 public String toString() 293 { 294 final StringBuilder buffer = new StringBuilder(); 295 toString(buffer); 296 return buffer.toString(); 297 } 298 299 300 301 /** 302 * Appends a string representation of this join base DN to the provided 303 * buffer. 304 * 305 * @param buffer The buffer to which the information should be appended. 306 */ 307 public void toString(@NotNull final StringBuilder buffer) 308 { 309 switch (type) 310 { 311 case BASE_TYPE_SEARCH_BASE: 312 buffer.append("useSearchBaseDN"); 313 break; 314 315 case BASE_TYPE_SOURCE_ENTRY_DN: 316 buffer.append("useSourceEntryDN"); 317 break; 318 319 case BASE_TYPE_CUSTOM: 320 buffer.append("useCustomBaseDN(baseDN='"); 321 buffer.append(customBaseDN); 322 buffer.append("')"); 323 break; 324 } 325 } 326}