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