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