001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 * 
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 * 
019 */
020package org.apache.directory.server.core.api.interceptor.context;
021
022
023import static org.apache.directory.api.ldap.model.message.SearchScope.ONELEVEL;
024
025import javax.naming.directory.SearchControls;
026
027import org.apache.directory.api.ldap.model.filter.ExprNode;
028import org.apache.directory.api.ldap.model.message.AliasDerefMode;
029import org.apache.directory.api.ldap.model.message.MessageTypeEnum;
030import org.apache.directory.api.ldap.model.message.SearchRequest;
031import org.apache.directory.api.ldap.model.message.SearchScope;
032import org.apache.directory.api.ldap.model.message.controls.ManageDsaIT;
033import org.apache.directory.api.ldap.model.name.Dn;
034import org.apache.directory.api.util.StringConstants;
035import org.apache.directory.server.core.api.CoreSession;
036import org.apache.directory.server.core.api.OperationEnum;
037
038
039/**
040 * A Search context used for Interceptors. It contains all the informations
041 * needed for the search operation, and used by all the interceptors
042 *
043 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
044 */
045public class SearchOperationContext extends FilteringOperationContext
046{
047    /** A flag describing the way alias should be handled */
048    private AliasDerefMode aliasDerefMode = AliasDerefMode.DEREF_ALWAYS;
049
050    /** The sizeLimit for this search operation */
051    private long sizeLimit = 0;
052
053    /** The timeLimit for this search operation */
054    private int timeLimit = 0;
055
056    /** The scope for this search : default to One Level */
057    private SearchScope scope = ONELEVEL;
058
059    /** A flag if the search operation is abandoned */
060    protected boolean abandoned = false;
061
062    /** The filter */
063    private ExprNode filter;
064
065
066    /** flag to indicate if this search is done for replication */
067    private boolean syncreplSearch;
068    
069    /**
070     * Creates a new instance of SearchOperationContext.
071     * 
072     * @param session The session to use
073     */
074    public SearchOperationContext( CoreSession session )
075    {
076        super( session );
077
078        if ( session != null )
079        {
080            setInterceptors( session.getDirectoryService().getInterceptors( OperationEnum.SEARCH ) );
081        }
082    }
083
084
085    /**
086     * Creates a new instance of SearchOperationContext.
087     * 
088     * @param session The session to use
089     * @param searchRequest The SearchRequest to process
090     */
091    public SearchOperationContext( CoreSession session, SearchRequest searchRequest )
092    {
093        super( session, searchRequest.getBase(), searchRequest.getAttributes().toArray( StringConstants.EMPTY_STRINGS ) );
094
095        if ( session != null )
096        {
097            setInterceptors( session.getDirectoryService().getInterceptors( OperationEnum.SEARCH ) );
098        }
099
100        this.filter = searchRequest.getFilter();
101        this.abandoned = searchRequest.isAbandoned();
102        this.aliasDerefMode = searchRequest.getDerefAliases();
103
104        this.requestControls = searchRequest.getControls();
105        this.scope = searchRequest.getScope();
106        this.sizeLimit = searchRequest.getSizeLimit();
107        this.timeLimit = searchRequest.getTimeLimit();
108        this.typesOnly = searchRequest.getTypesOnly();
109
110        throwReferral = !requestControls.containsKey( ManageDsaIT.OID );
111    }
112
113
114    /**
115     * Creates a new instance of SearchOperationContext.
116     * 
117     * @param session The session to use
118     * @param dn the dn of the search base
119     * @param filter the filter AST to use for the search
120     * @param searchControls the search controls
121     */
122    public SearchOperationContext( CoreSession session, Dn dn, ExprNode filter, SearchControls searchControls )
123    {
124        super( session, dn, searchControls.getReturningAttributes() );
125        this.filter = filter;
126        scope = SearchScope.getSearchScope( searchControls.getSearchScope() );
127        timeLimit = searchControls.getTimeLimit();
128        sizeLimit = searchControls.getCountLimit();
129        typesOnly = searchControls.getReturningObjFlag();
130
131        if ( session != null )
132        {
133            setInterceptors( session.getDirectoryService().getInterceptors( OperationEnum.SEARCH ) );
134        }
135    }
136
137
138    /**
139     * Creates a new instance of SearchOperationContext.
140     * 
141     * @param session the session this operation is associated with
142     * @param dn the search base
143     * @param scope the search scope
144     * @param filter the filter AST to use for the search
145     * @param returningAttributes the attributes to return
146     */
147    public SearchOperationContext( CoreSession session, Dn dn, SearchScope scope,
148        ExprNode filter, String... returningAttributes )
149    {
150        super( session, dn, returningAttributes );
151        this.scope = scope;
152        this.filter = filter;
153
154        if ( session != null )
155        {
156            setInterceptors( session.getDirectoryService().getInterceptors( OperationEnum.SEARCH ) );
157        }
158    }
159
160
161    /**
162     * Checks whether or not the ManageDsaITControl is present.  If not
163     * present then the filter is modified to force the return of all referral
164     * entries regardless of whether or not the filter matches the referral
165     * entry.
166     * 
167     * @return <tt>true</tt> if the ManageDSAIt control is present
168     */
169    public boolean hasManageDsaItControl()
170    {
171        return super.hasRequestControl( ManageDsaIT.OID );
172    }
173
174
175    /**
176     * @return The filter
177     */
178    public ExprNode getFilter()
179    {
180        return filter;
181    }
182
183
184    /**
185     * Set the filter into the context.
186     *
187     * @param filter The filter to set
188     */
189    public void setFilter( ExprNode filter )
190    {
191        this.filter = filter;
192    }
193
194
195    /**
196     * @return the operation name
197     */
198    public String getName()
199    {
200        return MessageTypeEnum.SEARCH_REQUEST.name();
201    }
202
203
204    /**
205     * @return true if this is a syncrepl specific search
206     */
207    public boolean isSyncreplSearch()
208    {
209        return syncreplSearch;
210    }
211
212
213    /**
214     * Sets the flag to indicate if this is a syncrepl specific search or not
215     * 
216     * @param syncreplSearch The flag indicating it's a syncrepl search
217     */
218    public void setSyncreplSearch( boolean syncreplSearch )
219    {
220        this.syncreplSearch = syncreplSearch;
221    }
222
223
224    /**
225     * @return The alias dereferencing mode
226     */
227    public AliasDerefMode getAliasDerefMode()
228    {
229        return aliasDerefMode;
230    }
231
232
233    /**
234     * Set the Alias dereferencing mode
235     * @param aliasDerefMode Th erequested mode
236     */
237    public void setAliasDerefMode( AliasDerefMode aliasDerefMode )
238    {
239        this.aliasDerefMode = aliasDerefMode;
240    }
241
242
243    /**
244     * @return the sizeLimit
245     */
246    public long getSizeLimit()
247    {
248        return sizeLimit;
249    }
250
251
252    /**
253     * @param sizeLimit the sizeLimit to set
254     */
255    public void setSizeLimit( long sizeLimit )
256    {
257        this.sizeLimit = sizeLimit;
258    }
259
260
261    /**
262     * @return the timeLimit
263     */
264    public int getTimeLimit()
265    {
266        return timeLimit;
267    }
268
269
270    /**
271     * @param timeLimit the timeLimit to set
272     */
273    public void setTimeLimit( int timeLimit )
274    {
275        this.timeLimit = timeLimit;
276    }
277
278
279    /**
280     * @return the scope
281     */
282    public SearchScope getScope()
283    {
284        return scope;
285    }
286
287
288    /**
289     * @param scope the scope to set
290     */
291    public void setScope( SearchScope scope )
292    {
293        this.scope = scope;
294    }
295
296
297    /**
298     * @return the abandoned
299     */
300    public boolean isAbandoned()
301    {
302        return abandoned;
303    }
304
305
306    /**
307     * @param abandoned the abandoned to set
308     */
309    public void setAbandoned( boolean abandoned )
310    {
311        this.abandoned = abandoned;
312    }
313
314
315    /**
316     * @see Object#toString()
317     */
318    @Override
319    public String toString()
320    {
321        return "SearchContext for Dn '" + getDn().getName() + "', filter :'"
322            + filter + "'";
323    }
324}