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 }