001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.protocols.internal;
028    
029    
030    
031    import java.util.LinkedHashSet;
032    import java.util.LinkedList;
033    import java.util.List;
034    
035    import org.opends.server.api.ClientConnection;
036    import org.opends.server.core.SearchOperationBasis;
037    import org.opends.server.types.ByteString;
038    import org.opends.server.types.Control;
039    import org.opends.server.types.DN;
040    import org.opends.server.types.DereferencePolicy;
041    import org.opends.server.types.DirectoryException;
042    import org.opends.server.types.RawFilter;
043    import org.opends.server.types.SearchFilter;
044    import org.opends.server.types.SearchResultEntry;
045    import org.opends.server.types.SearchResultReference;
046    import org.opends.server.types.SearchScope;
047    
048    
049    
050    /**
051     * This class defines a subclass of the core search operation that is
052     * to be used for internal searches.  The primary difference between
053     * this class and the core search operation is that the search entries
054     * and references will be queued in memory rather than sent to a
055     * client since there is no real client.
056     */
057    @org.opends.server.types.PublicAPI(
058         stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
059         mayInstantiate=true,
060         mayExtend=false,
061         mayInvoke=true)
062    public final class InternalSearchOperation
063           extends SearchOperationBasis
064    {
065      // The internal search listener for this search, if one was
066      // provided.
067      private InternalSearchListener searchListener;
068    
069      // The set of matching entries returned for this search.
070      private LinkedList<SearchResultEntry> entryList;
071    
072      // The set of search references returned for this search.
073      private LinkedList<SearchResultReference> referenceList;
074    
075    
076    
077      /**
078       * Creates a new internal search operation with the provided
079       * information.
080       *
081       * @param  internalConnection  The internal client connection with
082       *                             which this internal search operation
083       *                             is associated.
084       * @param  operationID         The operation ID for this internal
085       *                             search.
086       * @param  messageID           The message ID for this internal
087       *                             search.
088       * @param  requestControls     The set of request controls for this
089       *                             internal search.
090       * @param  rawBaseDN           The raw base DN for this internal
091       *                             search.
092       * @param  scope               The scope for this internal search.
093       * @param  derefPolicy         The alias dereferencing policy for
094       *                             this internal search.
095       * @param  sizeLimit           The size limit for this internal
096       *                             search.
097       * @param  timeLimit           The time limit for this internal
098       *                             search.
099       * @param  typesOnly           The typesOnly flag for this internal
100       *                             search.
101       * @param  rawFilter           The raw filter for this internal
102       *                             search.
103       * @param  attributes          The names of the requested attributes
104       *                             for this internal search.
105       * @param  searchListener      The internal search listener that
106       *                             should be used to process the
107       *                             results, or <CODE>null</CODE> if
108       *                             they should be collected internally.
109       */
110      public InternalSearchOperation(
111                  ClientConnection internalConnection,
112                  long operationID, int messageID,
113                  List<Control> requestControls, ByteString rawBaseDN,
114                  SearchScope scope, DereferencePolicy derefPolicy,
115                  int sizeLimit, int timeLimit, boolean typesOnly,
116                  RawFilter rawFilter, LinkedHashSet<String> attributes,
117                  InternalSearchListener searchListener)
118      {
119        super(internalConnection, operationID, messageID, requestControls,
120              rawBaseDN, scope, derefPolicy, sizeLimit, timeLimit,
121              typesOnly, rawFilter, attributes);
122    
123    
124    
125    
126        if (searchListener == null)
127        {
128          this.searchListener = null;
129          this.entryList      = new LinkedList<SearchResultEntry>();
130          this.referenceList  = new LinkedList<SearchResultReference>();
131        }
132        else
133        {
134          this.searchListener = searchListener;
135          this.entryList      = null;
136          this.referenceList  = null;
137        }
138    
139        setInternalOperation(true);
140      }
141    
142    
143    
144      /**
145       * Creates a new internal search operation with the provided
146       * information.
147       *
148       * @param  internalConnection  The internal client connection with
149       *                             which this internal search operation
150       *                             is associated.
151       * @param  operationID         The operation ID for this internal
152       *                             search.
153       * @param  messageID           The message ID for this internal
154       *                             search.
155       * @param  requestControls     The set of request controls for this
156       *                             internal search.
157       * @param  baseDN              The base DN for this internal search.
158       * @param  scope               The scope for this internal search.
159       * @param  derefPolicy         The alias dereferencing policy for
160       *                             this internal search.
161       * @param  sizeLimit           The size limit for this internal
162       *                             search.
163       * @param  timeLimit           The time limit for this internal
164       *                             search.
165       * @param  typesOnly           The typesOnly flag for this internal
166       *                             search.
167       * @param  filter              The filter for this internal search.
168       * @param  attributes          The names of the requested attributes
169       *                             for this internal search.
170       * @param  searchListener      The internal search listener that
171       *                             should be used to process the
172       *                             results, or <CODE>null</CODE> if
173       *                             they should be collected internally.
174       */
175      public InternalSearchOperation(
176                  ClientConnection internalConnection,
177                  long operationID, int messageID,
178                  List<Control> requestControls, DN baseDN,
179                  SearchScope scope, DereferencePolicy derefPolicy,
180                  int sizeLimit, int timeLimit, boolean typesOnly,
181                  SearchFilter filter, LinkedHashSet<String> attributes,
182                  InternalSearchListener searchListener)
183      {
184        super(internalConnection, operationID, messageID, requestControls,
185              baseDN, scope, derefPolicy, sizeLimit, timeLimit,
186              typesOnly, filter, attributes);
187    
188    
189    
190    
191        if (searchListener == null)
192        {
193          this.searchListener = null;
194          this.entryList      = new LinkedList<SearchResultEntry>();
195          this.referenceList  = new LinkedList<SearchResultReference>();
196        }
197        else
198        {
199          this.searchListener = searchListener;
200          this.entryList      = null;
201          this.referenceList  = null;
202        }
203    
204        setInternalOperation(true);
205      }
206    
207    
208    
209      /**
210       * Retrieves the set of search result entries returned for this
211       * search.
212       *
213       * @return  The set of search result entries returned for this
214       *          search, or <CODE>null</CODE> if a custom internal search
215       *          listener is to be used.
216       */
217      public LinkedList<SearchResultEntry> getSearchEntries()
218      {
219        return entryList;
220      }
221    
222    
223    
224      /**
225       * Provides the provided search result entry to the internal search
226       * listener if one was provided, or stores it in an internal list
227       * otherwise.
228       *
229       * @param  searchEntry  The search result entry returned for this
230       *                      search.
231       *
232       * @throws  DirectoryException  If a problem occurs while processing
233       *                              the provided entry and the search
234       *                              should be terminated.
235       */
236      @org.opends.server.types.PublicAPI(
237           stability=org.opends.server.types.StabilityLevel.PRIVATE,
238           mayInstantiate=false,
239           mayExtend=false,
240           mayInvoke=false)
241      public void addSearchEntry(SearchResultEntry searchEntry)
242             throws DirectoryException
243      {
244        if (searchListener == null)
245        {
246          entryList.add(searchEntry);
247        }
248        else
249        {
250          searchListener.handleInternalSearchEntry(this, searchEntry);
251        }
252      }
253    
254    
255    
256      /**
257       * Retrieves the set of search result references returned for this
258       * search.
259       *
260       * @return  The set of search result references returned for this
261       *          search, or <CODE>null</CODE> if a custom internal search
262       *          listener is to be used.
263       */
264      public LinkedList<SearchResultReference> getSearchReferences()
265      {
266        return referenceList;
267      }
268    
269    
270    
271      /**
272       * Provides the provided search result reference to the internal
273       * search listener if one was provided, or stores it in an internal
274       * list otherwise.
275       *
276       * @param  searchReference  The search result reference returned for
277       *                          this search.
278       *
279       * @throws  DirectoryException  If a problem occurs while processing
280       *                              the provided reference and the
281       *                              search should be terminated.
282       */
283      @org.opends.server.types.PublicAPI(
284           stability=org.opends.server.types.StabilityLevel.PRIVATE,
285           mayInstantiate=false,
286           mayExtend=false,
287           mayInvoke=false)
288      public void addSearchReference(
289                       SearchResultReference searchReference)
290             throws DirectoryException
291      {
292        if (searchListener == null)
293        {
294          referenceList.add(searchReference);
295        }
296        else
297        {
298          searchListener.handleInternalSearchReference(this,
299                                                       searchReference);
300        }
301      }
302    
303    
304    
305      /**
306       * Sends the provided search result entry to the client.
307       *
308       * @param  searchEntry  The search result entry to be sent to the
309       *                      client.
310       *
311       * @throws  DirectoryException  If a problem occurs while attempting
312       *                              to send the entry to the client and
313       *                              the search should be terminated.
314       */
315      @org.opends.server.types.PublicAPI(
316           stability=org.opends.server.types.StabilityLevel.PRIVATE,
317           mayInstantiate=false,
318           mayExtend=false,
319           mayInvoke=false)
320      @Override()
321      public void sendSearchEntry(SearchResultEntry searchEntry)
322             throws DirectoryException
323      {
324        addSearchEntry(searchEntry);
325      }
326    
327    
328    
329      /**
330       * Sends the provided search result reference to the client.
331       *
332       * @param  searchReference  The search result reference to be sent
333       *                          to the client.
334       *
335       * @return  {@code true} if the client is able to accept referrals,
336       *          or {@code false} if the client cannot handle referrals
337       *          and no more attempts should be made to send them for the
338       *          associated search operation.
339       *
340       * @throws  DirectoryException  If a problem occurs while attempting
341       *                              to send the reference to the client
342       *                              and the search should be terminated.
343       */
344      @org.opends.server.types.PublicAPI(
345           stability=org.opends.server.types.StabilityLevel.PRIVATE,
346           mayInstantiate=false,
347           mayExtend=false,
348           mayInvoke=false)
349      @Override()
350      public boolean sendSearchReference(
351                          SearchResultReference searchReference)
352             throws DirectoryException
353      {
354        addSearchReference(searchReference);
355        return true;
356      }
357    }
358