001/*
002 * Copyright 2007-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2007-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) 2007-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;
037
038
039
040import java.io.Serializable;
041import java.util.HashMap;
042
043import com.unboundid.util.NotMutable;
044import com.unboundid.util.NotNull;
045import com.unboundid.util.Nullable;
046import com.unboundid.util.StaticUtils;
047import com.unboundid.util.ThreadSafety;
048import com.unboundid.util.ThreadSafetyLevel;
049
050
051
052/**
053 * This class defines a data type for search scope values.  Clients should
054 * generally use one of the {@code BASE}, {@code ONE}, {@code SUB}, or
055 * {@code SUBORDINATE_SUBTREE} values, although it is possible to create a new
056 * scope with a specified integer value if necessary using the
057 * {@link #valueOf(int)} method.  The following search scope values are defined:
058 * <UL>
059 *   <LI>{@code BASE} -- Indicates that only the entry specified by the base DN
060 *       should be considered.</LI>
061 *   <LI>{@code ONE} -- Indicates that only entries that are immediate
062 *       subordinates of the entry specified by the base DN (but not the base
063 *       entry itself) should be considered.</LI>
064 *   <LI>{@code SUB} -- Indicates that the base entry itself and any subordinate
065 *       entries (to any depth) should be considered.</LI>
066 *   <LI>{@code SUBORDINATE_SUBTREE} -- Indicates that any subordinate entries
067 *       (to any depth) below the entry specified by the base DN should be
068 *       considered, but the base entry itself should not be considered, as
069 *       described in draft-sermersheim-ldap-subordinate-scope.</LI>
070 * </UL>
071 */
072@NotMutable()
073@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
074public final class SearchScope
075       implements Serializable
076{
077  /**
078   * The integer value for the "base" search scope.
079   */
080  public static final int BASE_INT_VALUE = 0;
081
082
083
084  /**
085   * A predefined baseObject scope value, which indicates that only the entry
086   * specified by the base DN should be considered.
087   */
088  @NotNull public static final SearchScope BASE =
089       new SearchScope("BASE", BASE_INT_VALUE);
090
091
092
093  /**
094   * The integer value for the "one" search scope.
095   */
096  public static final int ONE_INT_VALUE = 1;
097
098
099
100  /**
101   * A predefined singleLevel scope value, which indicates that only entries
102   * that are immediate subordinates of the entry specified by the base DN (but
103   * not the base entry itself) should be considered.
104   */
105  @NotNull public static final SearchScope ONE =
106       new SearchScope("ONE", ONE_INT_VALUE);
107
108
109
110  /**
111   * The integer value for the "sub" search scope.
112   */
113  public static final int SUB_INT_VALUE = 2;
114
115
116
117  /**
118   * A predefined wholeSubtree scope value, which indicates that the base entry
119   * itself and any subordinate entries (to any depth) should be considered.
120   */
121  @NotNull public static final SearchScope SUB =
122       new SearchScope("SUB", SUB_INT_VALUE);
123
124
125
126  /**
127   * The integer value for the "subordinate subtree" search scope.
128   */
129  public static final int SUBORDINATE_SUBTREE_INT_VALUE = 3;
130
131
132
133  /**
134   * A predefined subordinateSubtree scope value, which indicates that any
135   * subordinate entries (to any depth) below the entry specified by the base DN
136   * should be considered, but the base entry itself should not be considered.
137   */
138  @NotNull public static final SearchScope SUBORDINATE_SUBTREE =
139       new SearchScope("SUBORDINATE_SUBTREE", SUBORDINATE_SUBTREE_INT_VALUE);
140
141
142
143  /**
144   * The set of search scope objects created with undefined int values.
145   */
146  @NotNull private static final HashMap<Integer,SearchScope> UNDEFINED_SCOPES =
147       new HashMap<>(StaticUtils.computeMapCapacity(5));
148
149
150
151  /**
152   * The serial version UID for this serializable class.
153   */
154  private static final long serialVersionUID = 5381929718445793181L;
155
156
157
158  // The integer value for this search scope.
159  private final int intValue;
160
161  // The name to use for this search scope.
162  @NotNull private final String name;
163
164
165
166  /**
167   * Creates a new search scope with the specified integer value.
168   *
169   * @param  intValue  The integer value to use for this search scope.
170   */
171  private SearchScope(final int intValue)
172  {
173    this.intValue = intValue;
174
175    name = String.valueOf(intValue);
176  }
177
178
179
180  /**
181   * Creates a new search scope with the specified name and integer value.
182   *
183   * @param  name      The name to use for this search scope.
184   * @param  intValue  The integer value to use for this search scope.
185   */
186  private SearchScope(@NotNull final String name, final int intValue)
187  {
188    this.name     = name;
189    this.intValue = intValue;
190  }
191
192
193
194  /**
195   * Retrieves the name for this search scope.
196   *
197   * @return  The name for this search scope.
198   */
199  @NotNull()
200  public String getName()
201  {
202    return name;
203  }
204
205
206
207  /**
208   * Retrieves the integer value for this search scope.
209   *
210   * @return  The integer value for this search scope.
211   */
212  public int intValue()
213  {
214    return intValue;
215  }
216
217
218
219  /**
220   * Retrieves the search scope with the specified integer value.
221   *
222   * @param  intValue  The integer value for which to retrieve the corresponding
223   *                   search scope.
224   *
225   * @return  The search scope with the specified integer value, or a new search
226   *          scope if the provided value does not match any of the predefined
227   *          scopes.
228   */
229  @NotNull()
230  public static SearchScope valueOf(final int intValue)
231  {
232    switch (intValue)
233    {
234      case 0:
235        return BASE;
236      case 1:
237        return ONE;
238      case 2:
239        return SUB;
240      case 3:
241        return SUBORDINATE_SUBTREE;
242      default:
243        synchronized (UNDEFINED_SCOPES)
244        {
245          SearchScope s = UNDEFINED_SCOPES.get(intValue);
246          if (s == null)
247          {
248            s = new SearchScope(intValue);
249            UNDEFINED_SCOPES.put(intValue, s);
250          }
251
252          return s;
253        }
254    }
255  }
256
257
258
259  /**
260   * Retrieves the predefined search scope with the specified integer value.
261   *
262   * @param  intValue  The integer value for which to retrieve the corresponding
263   *                   search scope.
264   *
265   * @return  The search scope with the specified integer value, or {@code null}
266   *          if the provided integer value does not represent a defined scope.
267   */
268  @Nullable()
269  public static SearchScope definedValueOf(final int intValue)
270  {
271    switch (intValue)
272    {
273      case 0:
274        return BASE;
275      case 1:
276        return ONE;
277      case 2:
278        return SUB;
279      case 3:
280        return SUBORDINATE_SUBTREE;
281      default:
282        return null;
283    }
284  }
285
286
287
288  /**
289   * Retrieves an array of all search scopes defined in the LDAP SDK.
290   *
291   * @return  An array of all search scopes defined in the LDAP SDK.
292   */
293  @NotNull()
294  public static SearchScope[] values()
295  {
296    return new SearchScope[]
297    {
298      BASE,
299      ONE,
300      SUB,
301      SUBORDINATE_SUBTREE
302    };
303  }
304
305
306
307  /**
308   * The hash code for this search scope.
309   *
310   * @return  The hash code for this search scope.
311   */
312  @Override()
313  public int hashCode()
314  {
315    return intValue;
316  }
317
318
319
320  /**
321   * Indicates whether the provided object is equal to this search scope.
322   *
323   * @param  o  The object for which to make the determination.
324   *
325   * @return  {@code true} if the provided object is a search scope that is
326   *          equal to this search scope, or {@code false} if not.
327   */
328  @Override()
329  public boolean equals(@Nullable final Object o)
330  {
331    if (o == null)
332    {
333      return false;
334    }
335    else if (o == this)
336    {
337      return true;
338    }
339    else if (o instanceof SearchScope)
340    {
341      return (intValue == ((SearchScope) o).intValue);
342    }
343    else
344    {
345      return false;
346    }
347  }
348
349
350
351  /**
352   * Retrieves a string representation of this search scope.
353   *
354   * @return  A string representation of this search scope.
355   */
356  @Override()
357  @NotNull()
358  public String toString()
359  {
360    return name;
361  }
362}