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.api.ldap.model.message; 021 022 023import java.util.HashSet; 024import java.util.Set; 025 026import javax.naming.directory.SearchControls; 027 028import org.apache.directory.api.ldap.model.exception.LdapException; 029import org.apache.directory.api.ldap.model.schema.AttributeType; 030import org.apache.directory.api.ldap.model.schema.AttributeTypeOptions; 031import org.apache.directory.api.ldap.model.schema.SchemaManager; 032import org.apache.directory.api.ldap.model.schema.SchemaUtils; 033import org.apache.directory.api.util.Strings; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 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 */ 043public class SearchParams 044{ 045 /** The LoggerFactory used by this class */ 046 private static final Logger LOG = LoggerFactory.getLogger( SearchParams.class ); 047 048 /** The search scope. Default to OBJECT */ 049 private SearchScope scope = SearchScope.OBJECT; 050 051 /** The time limit. Default to 0 (infinite) */ 052 private int timeLimit = 0; 053 054 /** The size limit. Default to 0 (infinite) */ 055 private long sizeLimit = 0; 056 057 /** If we should return only types. Default to false */ 058 private boolean typesOnly = false; 059 060 /** The aliasDerefMode. Default to DEREF_ALWAYS */ 061 private AliasDerefMode aliasDerefMode = AliasDerefMode.DEREF_ALWAYS; 062 063 /** The list of attributes to return, as Strings. Default to an empty set */ 064 private Set<String> returningAttributesStr; 065 066 /** The list of attributes to return, once it has been normalized. Default to an empty set */ 067 private Set<AttributeTypeOptions> returningAttributes; 068 069 /** The set of controls for this search. Default to an empty set */ 070 private Set<Control> controls; 071 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<>(); 080 returningAttributesStr = new HashSet<>(); 081 controls = new HashSet<>(); 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 ( LdapException 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 control the controls to set 267 */ 268 public void addControl( Control control ) 269 { 270 this.controls.add( control ); 271 } 272 273 274 /** 275 * Creates a {@link SearchParams} from JNDI search controls. 276 * 277 * @param searchControls the search controls 278 * @param aliasDerefMode the alias deref mode 279 * @return the search params 280 */ 281 public static SearchParams toSearchParams( SearchControls searchControls, AliasDerefMode aliasDerefMode ) 282 { 283 SearchParams searchParams = new SearchParams(); 284 285 searchParams.setAliasDerefMode( aliasDerefMode ); 286 searchParams.setTimeLimit( searchControls.getTimeLimit() ); 287 searchParams.setSizeLimit( searchControls.getCountLimit() ); 288 searchParams.setScope( SearchScope.getSearchScope( searchControls.getSearchScope() ) ); 289 searchParams.setTypesOnly( searchControls.getReturningObjFlag() ); 290 291 if ( searchControls.getReturningAttributes() != null ) 292 { 293 for ( String returningAttribute : searchControls.getReturningAttributes() ) 294 { 295 searchParams.addReturningAttributes( returningAttribute ); 296 } 297 } 298 299 return searchParams; 300 } 301 302 303 /** 304 * {@inheritDoc} 305 */ 306 @Override 307 public String toString() 308 { 309 StringBuilder sb = new StringBuilder(); 310 311 sb.append( "Search parameters :\n" ); 312 sb.append( " scope : " ).append( scope ).append( "\n" ); 313 sb.append( " Alias dereferencing : " ).append( aliasDerefMode ).append( "\n" ); 314 sb.append( " types only : " ).append( typesOnly ).append( "\n" ); 315 316 if ( !returningAttributesStr.isEmpty() ) 317 { 318 sb.append( " returning attributes : " ).append( Strings.setToString( returningAttributesStr ) ) 319 .append( "\n" ); 320 } 321 322 if ( timeLimit > 0 ) 323 { 324 sb.append( " timeLimit : " ).append( timeLimit ).append( "\n" ); 325 } 326 else 327 { 328 sb.append( " no timeLimit\n" ); 329 } 330 331 if ( timeLimit > 0 ) 332 { 333 sb.append( " sizeLimit : " ).append( sizeLimit ).append( "\n" ); 334 } 335 else 336 { 337 sb.append( " no sizeLimit\n" ); 338 } 339 340 if ( !controls.isEmpty() ) 341 { 342 for ( Control control : controls ) 343 { 344 sb.append( " control : " ). 345 append( control.getOid() ).append( "/" ). 346 append( control.getClass().getName() ).append( "\n" ); 347 } 348 } 349 350 return sb.toString(); 351 } 352}