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