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     */
020    package org.apache.directory.shared.ldap.message;
021    
022    import java.util.HashSet;
023    import java.util.Set;
024    
025    import javax.naming.directory.SearchControls;
026    
027    import org.apache.directory.shared.ldap.exception.LdapException;
028    import org.apache.directory.shared.ldap.filter.SearchScope;
029    import org.apache.directory.shared.ldap.message.control.Control;
030    import org.apache.directory.shared.ldap.schema.AttributeType;
031    import org.apache.directory.shared.ldap.schema.AttributeTypeOptions;
032    import org.apache.directory.shared.ldap.schema.SchemaManager;
033    import org.apache.directory.shared.ldap.schema.SchemaUtils;
034    import org.apache.directory.shared.ldap.util.StringTools;
035    import org.slf4j.Logger;
036    import org.slf4j.LoggerFactory;
037    
038    /**
039     * A container for Search parameters. It replaces the SearchControls.
040     *
041     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042     * @version $Rev$, $Date$
043     */
044    public class SearchParams
045    {
046        /** The LoggerFactory used by this class */
047        private static Logger LOG = LoggerFactory.getLogger( SearchParams.class );
048     
049        /** The search scope. Default to OBJECT */
050        private SearchScope scope = SearchScope.OBJECT;
051        
052        /** The time limit. Default to 0 (infinite) */
053        private int timeLimit = 0;
054        
055        /** The size limit. Default to 0 (infinite) */
056        private long sizeLimit = 0;
057        
058        /** If we should return only types. Default to false */
059        private boolean typesOnly = false;
060        
061        /** The aliasDerefMode. Default to DEREF_ALWAYS */
062        private AliasDerefMode aliasDerefMode = AliasDerefMode.DEREF_ALWAYS;
063        
064        /** The list of attributes to return, as Strings. Default to an empty set */
065        private Set<String> returningAttributesStr;
066        
067        /** The list of attributes to return, once it has been normalized. Default to an empty set */
068        private Set<AttributeTypeOptions> returningAttributes;
069        
070        /** The set of controls for this search. Default to an empty set */
071        private Set<Control> controls;
072        
073        /** TODO : Remove me ! */
074        private SearchControls searchControls;
075    
076        /**
077         * Creates a new instance of SearchContext, with all the values set to 
078         * default.
079         */
080        public SearchParams()
081        {
082            returningAttributes = new HashSet<AttributeTypeOptions>();
083            returningAttributesStr = new HashSet<String>();
084            controls = new HashSet<Control>();
085        }
086    
087        
088        /**
089         * @return the scope
090         */
091        public SearchScope getScope()
092        {
093            return scope;
094        }
095        
096    
097        /**
098         * @param scope the scope to set
099         */
100        public void setScope( SearchScope scope )
101        {
102            this.scope = scope;
103        }
104        
105    
106        /**
107         * @return the timeLimit
108         */
109        public int getTimeLimit()
110        {
111            return timeLimit;
112        }
113        
114    
115        /**
116         * @param timeLimit the timeLimit to set
117         */
118        public void setTimeLimit( int timeLimit )
119        {
120            this.timeLimit = timeLimit;
121        }
122        
123    
124        /**
125         * @return the sizeLimit
126         */
127        public long getSizeLimit()
128        {
129            return sizeLimit;
130        }
131        
132    
133        /**
134         * @param sizeLimit the sizeLimit to set
135         */
136        public void setSizeLimit( long sizeLimit )
137        {
138            this.sizeLimit = sizeLimit;
139        }
140        
141    
142        /**
143         * @return the typesOnly
144         */
145        public boolean isTypesOnly()
146        {
147            return typesOnly;
148        }
149        
150    
151        /**
152         * @param typesOnly the typesOnly to set
153         */
154        public void setTypesOnly( boolean typesOnly )
155        {
156            this.typesOnly = typesOnly;
157        }
158        
159    
160        /**
161         * @return the aliasDerefMode
162         */
163        public AliasDerefMode getAliasDerefMode()
164        {
165            return aliasDerefMode;
166        }
167        
168    
169        /**
170         * @param aliasDerefMode the aliasDerefMode to set
171         */
172        public void setAliasDerefMode( AliasDerefMode aliasDerefMode )
173        {
174            this.aliasDerefMode = aliasDerefMode;
175        }
176        
177    
178        /**
179         * @return the returningAttributes
180         */
181        public Set<AttributeTypeOptions> getReturningAttributes()
182        {
183            return returningAttributes;
184        }
185    
186        
187        /**
188         * @return the returningAttributes
189         */
190        public Set<String> getReturningAttributesStr()
191        {
192            return returningAttributesStr;
193        }
194    
195        
196        /**
197         * Normalize the ReturningAttributes. It reads all the String from the returningAttributesString,
198         * and grab the associated AttributeType from the schema to store it into the returningAttributes
199         * Set.
200         *
201         * @param schemaManager The schema manager
202         */
203        public void normalize( SchemaManager schemaManager )
204        {
205            for ( String returnAttribute : returningAttributesStr )
206            {
207                try
208                {
209                    String id = SchemaUtils.stripOptions( returnAttribute );
210                    Set<String> options = SchemaUtils.getOptions( returnAttribute );
211                    
212                    AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( id );
213                    AttributeTypeOptions attrOptions = new AttributeTypeOptions( attributeType, options );
214                   
215                    returningAttributes.add( attrOptions );
216                }
217                catch ( LdapException ne )
218                {
219                    LOG.warn( "Requested attribute {} does not exist in the schema, it will be ignored", returnAttribute );
220                    // Unknown attributes should be silently ignored, as RFC 2251 states
221                }
222            }
223        }
224    
225        
226        /**
227         * @param returningAttributes the returningAttributes to set
228         */
229        public void setReturningAttributes( String... returningAttributes )
230        {
231            if ( returningAttributes != null )
232            {
233                for ( String returnAttribute : returningAttributes )
234                {
235                    this.returningAttributesStr.add( returnAttribute );
236                }
237            }
238        }
239    
240    
241        /**
242         * @param returningAttribute the returningAttributes to add
243         */
244        public void addReturningAttributes( String returningAttribute )
245        {
246            this.returningAttributesStr.add( returningAttribute );
247        }
248    
249    
250        /**
251         * @return the controls
252         */
253        public Set<Control> getControls()
254        {
255            return controls;
256        }
257    
258    
259        /**
260         * @param controls the controls to set
261         */
262        public void setControls( Set<Control> controls )
263        {
264            this.controls = controls;
265        }
266    
267    
268        /**
269         * @param controls the controls to set
270         */
271        public void addControl( Control control )
272        {
273            this.controls.add( control );
274        }
275        
276        
277        public SearchControls getSearchControls()
278        {
279            return searchControls;
280        }
281    
282    
283        public static SearchParams toSearchParams( SearchControls searchControls, AliasDerefMode aliasDerefMode )
284        {
285            SearchParams searchParams = new SearchParams();
286            
287            searchParams.setAliasDerefMode( aliasDerefMode );
288            searchParams.setTimeLimit( searchControls.getTimeLimit() );
289            searchParams.setSizeLimit( searchControls.getCountLimit() );
290            searchParams.setScope( SearchScope.getSearchScope( searchControls.getSearchScope() ) );
291            searchParams.setTypesOnly( searchControls.getReturningObjFlag() );
292            
293            if ( searchControls.getReturningAttributes() != null )
294            {
295                for ( String returningAttribute : searchControls.getReturningAttributes() )
296                {
297                    searchParams.addReturningAttributes( returningAttribute );
298                }
299            }
300            
301            searchParams.searchControls = searchControls;
302            
303            return searchParams;
304        }
305        
306        
307        
308        /**
309         * {@inheritDoc}
310         */
311        public String toString()
312        {
313            StringBuilder sb = new StringBuilder();
314    
315            sb.append( "Search parameters :\n" );
316            sb.append( "    scope : " ).append( scope ).append( "\n" );
317            sb.append( "    Alias dereferencing : " ).append( aliasDerefMode ).append( "\n" );
318            sb.append( "    types only : " ).append( typesOnly ).append( "\n" );
319            
320            if ( returningAttributesStr.size() != 0 )
321            {
322                sb.append( "    returning attributes : " ).append( StringTools.setToString( returningAttributesStr ) ).append( "\n" );
323            }
324            
325            if ( timeLimit > 0 )
326            {
327                sb.append( "    timeLimit : " ).append( timeLimit ).append( "\n" );
328            }
329            else
330            {
331                sb.append( "    no timeLimit\n" );
332            }
333    
334            if ( timeLimit > 0 )
335            {
336                sb.append( "    sizeLimit : " ).append( sizeLimit ).append( "\n" );
337            }
338            else
339            {
340                sb.append( "    no sizeLimit\n" );
341            }
342    
343            if ( controls.size() != 0 )
344            {
345                for ( Control control : controls )
346                {
347                    sb.append( "    control : " ).
348                        append( control.getOid() ).append( "/" ).
349                        append( control.getClass().getName() ).append( "\n" );
350                }
351            }
352            
353            return sb.toString();
354        }
355    }