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