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