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.NamingException;
026    import javax.naming.directory.SearchControls;
027    
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        /**
074         * Creates a new instance of SearchContext, with all the values set to 
075         * default.
076         */
077        public SearchParams()
078        {
079            returningAttributes = new HashSet<AttributeTypeOptions>();
080            returningAttributesStr = new HashSet<String>();
081            controls = new HashSet<Control>();
082        }
083    
084        
085        /**
086         * @return the scope
087         */
088        public SearchScope getScope()
089        {
090            return scope;
091        }
092        
093    
094        /**
095         * @param scope the scope to set
096         */
097        public void setScope( SearchScope scope )
098        {
099            this.scope = scope;
100        }
101        
102    
103        /**
104         * @return the timeLimit
105         */
106        public int getTimeLimit()
107        {
108            return timeLimit;
109        }
110        
111    
112        /**
113         * @param timeLimit the timeLimit to set
114         */
115        public void setTimeLimit( int timeLimit )
116        {
117            this.timeLimit = timeLimit;
118        }
119        
120    
121        /**
122         * @return the sizeLimit
123         */
124        public long getSizeLimit()
125        {
126            return sizeLimit;
127        }
128        
129    
130        /**
131         * @param sizeLimit the sizeLimit to set
132         */
133        public void setSizeLimit( long sizeLimit )
134        {
135            this.sizeLimit = sizeLimit;
136        }
137        
138    
139        /**
140         * @return the typesOnly
141         */
142        public boolean isTypesOnly()
143        {
144            return typesOnly;
145        }
146        
147    
148        /**
149         * @param typesOnly the typesOnly to set
150         */
151        public void setTypesOnly( boolean typesOnly )
152        {
153            this.typesOnly = typesOnly;
154        }
155        
156    
157        /**
158         * @return the aliasDerefMode
159         */
160        public AliasDerefMode getAliasDerefMode()
161        {
162            return aliasDerefMode;
163        }
164        
165    
166        /**
167         * @param aliasDerefMode the aliasDerefMode to set
168         */
169        public void setAliasDerefMode( AliasDerefMode aliasDerefMode )
170        {
171            this.aliasDerefMode = aliasDerefMode;
172        }
173        
174    
175        /**
176         * @return the returningAttributes
177         */
178        public Set<AttributeTypeOptions> getReturningAttributes()
179        {
180            return returningAttributes;
181        }
182    
183        
184        /**
185         * @return the returningAttributes
186         */
187        public Set<String> getReturningAttributesStr()
188        {
189            return returningAttributesStr;
190        }
191    
192        
193        /**
194         * Normalize the ReturningAttributes. It reads all the String from the returningAttributesString,
195         * and grab the associated AttributeType from the schema to store it into the returningAttributes
196         * Set.
197         *
198         * @param schemaManager The schema manager
199         */
200        public void normalize( SchemaManager schemaManager )
201        {
202            for ( String returnAttribute : returningAttributesStr )
203            {
204                try
205                {
206                    String id = SchemaUtils.stripOptions( returnAttribute );
207                    Set<String> options = SchemaUtils.getOptions( returnAttribute );
208                    
209                    AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( id );
210                    AttributeTypeOptions attrOptions = new AttributeTypeOptions( attributeType, options );
211                   
212                    returningAttributes.add( attrOptions );
213                }
214                catch ( NamingException ne )
215                {
216                    LOG.warn( "Requested attribute {} does not exist in the schema, it will be ignored", returnAttribute );
217                    // Unknown attributes should be silently ignored, as RFC 2251 states
218                }
219            }
220        }
221    
222        
223        /**
224         * @param returningAttributes the returningAttributes to set
225         */
226        public void setReturningAttributes( String... returningAttributes )
227        {
228            if ( returningAttributes != null )
229            {
230                for ( String returnAttribute : returningAttributes )
231                {
232                    this.returningAttributesStr.add( returnAttribute );
233                }
234            }
235        }
236    
237    
238        /**
239         * @param returningAttribute the returningAttributes to add
240         */
241        public void addReturningAttributes( String returningAttribute )
242        {
243            this.returningAttributesStr.add( returningAttribute );
244        }
245    
246    
247        /**
248         * @return the controls
249         */
250        public Set<Control> getControls()
251        {
252            return controls;
253        }
254    
255    
256        /**
257         * @param controls the controls to set
258         */
259        public void setControls( Set<Control> controls )
260        {
261            this.controls = controls;
262        }
263    
264    
265        /**
266         * @param controls the controls to set
267         */
268        public void addControl( Control control )
269        {
270            this.controls.add( control );
271        }
272        
273        
274        public static SearchParams toSearchParams( SearchControls searchControls, AliasDerefMode aliasDerefMode )
275        {
276            SearchParams searchParams = new SearchParams();
277            
278            searchParams.setAliasDerefMode( aliasDerefMode );
279            searchParams.setTimeLimit( searchControls.getTimeLimit() );
280            searchParams.setSizeLimit( searchControls.getCountLimit() );
281            searchParams.setScope( SearchScope.getSearchScope( searchControls.getSearchScope() ) );
282            searchParams.setTypesOnly( searchControls.getReturningObjFlag() );
283            return searchParams;
284        }
285        
286        
287        
288        /**
289         * {@inheritDoc}
290         */
291        public String toString()
292        {
293            StringBuilder sb = new StringBuilder();
294    
295            sb.append( "Search parameters :\n" );
296            sb.append( "    scope : " ).append( scope ).append( "\n" );
297            sb.append( "    Alias dereferencing : " ).append( aliasDerefMode ).append( "\n" );
298            sb.append( "    types only : " ).append( typesOnly ).append( "\n" );
299            
300            if ( returningAttributesStr.size() != 0 )
301            {
302                sb.append( "    returning attributes : " ).append( StringTools.setToString( returningAttributesStr ) ).append( "\n" );
303            }
304            
305            if ( timeLimit > 0 )
306            {
307                sb.append( "    timeLimit : " ).append( timeLimit ).append( "\n" );
308            }
309            else
310            {
311                sb.append( "    no timeLimit\n" );
312            }
313    
314            if ( timeLimit > 0 )
315            {
316                sb.append( "    sizeLimit : " ).append( sizeLimit ).append( "\n" );
317            }
318            else
319            {
320                sb.append( "    no sizeLimit\n" );
321            }
322    
323            if ( controls.size() != 0 )
324            {
325                for ( Control control : controls )
326                {
327                    sb.append( "    control : " ).
328                        append( control.getOid() ).append( "/" ).
329                        append( control.getClass().getName() ).append( "\n" );
330                }
331            }
332            
333            return sb.toString();
334        }
335    }