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 java.util.Collection; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027 028import org.apache.directory.api.ldap.model.entry.Entry; 029import org.apache.directory.api.ldap.model.exception.LdapException; 030import org.apache.directory.api.ldap.model.message.Control; 031import org.apache.directory.api.ldap.model.name.Dn; 032import org.apache.directory.server.core.api.CoreSession; 033import org.apache.directory.server.core.api.LdapPrincipal; 034import org.apache.directory.server.core.api.partition.Partition; 035import org.apache.directory.server.core.api.partition.PartitionTxn; 036 037 038/** 039 * This abstract class stores common context elements, like the Dn, which is used 040 * in all the contexts. 041 * 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 */ 044public abstract class AbstractOperationContext implements OperationContext 045{ 046 protected static final Control[] EMPTY_CONTROLS = new Control[0]; 047 048 /** The Dn associated with the context */ 049 protected Dn dn; 050 051 /** The entry associated with the target entry of this OperationContext */ 052 protected Entry entry; 053 054 /** The original Entry */ 055 protected Entry originalEntry; 056 057 /** The associated request's controls */ 058 protected Map<String, Control> requestControls = new HashMap<>( 4 ); 059 060 /** The associated response's controls */ 061 protected Map<String, Control> responseControls = new HashMap<>( 4 ); 062 063 /** the Interceptors bypassed by this operation */ 064 protected Collection<String> byPassed; 065 066 /** The interceptors to call for this operation */ 067 protected List<String> interceptors; 068 069 /** The current interceptor position */ 070 protected int currentInterceptor; 071 072 protected LdapPrincipal authorizedPrincipal; 073 074 /** The core session */ 075 protected CoreSession session; 076 077 /** A flag used to tell if we should consider referrals as standard entries */ 078 protected boolean throwReferral; 079 080 /** The transaction this operation is ran into */ 081 protected PartitionTxn transaction; 082 083 /** The partition this operation will be applied on */ 084 protected Partition partition; 085 086 087 /** 088 * Creates a new instance of AbstractOperationContext. 089 * 090 * @param session The session to use 091 */ 092 public AbstractOperationContext( CoreSession session ) 093 { 094 this.session = session; 095 currentInterceptor = 0; 096 } 097 098 099 /** 100 * Creates a new instance of AbstractOperationContext. 101 * 102 * @param session The session to use 103 * @param dn The associated Dn 104 */ 105 public AbstractOperationContext( CoreSession session, Dn dn ) 106 { 107 this.dn = dn; 108 this.session = session; 109 110 // The flag is set to ignore, so that the revert operation can act on 111 // the entries, even if they are referrals. 112 ignoreReferral(); 113 } 114 115 116 /** 117 * {@inheritDoc} 118 */ 119 @Override 120 public CoreSession getSession() 121 { 122 return session; 123 } 124 125 126 /** 127 * {@inheritDoc} 128 */ 129 public void setSession( CoreSession session ) 130 { 131 this.session = session; 132 } 133 134 135 /** 136 * {@inheritDoc} 137 */ 138 protected void setAuthorizedPrincipal( LdapPrincipal authorizedPrincipal ) 139 { 140 this.authorizedPrincipal = authorizedPrincipal; 141 } 142 143 144 /** 145 * @return The associated Dn 146 */ 147 @Override 148 public Dn getDn() 149 { 150 return dn; 151 } 152 153 154 /** 155 * Set the context Dn 156 * 157 * @param dn The Dn to set 158 */ 159 @Override 160 public void setDn( Dn dn ) 161 { 162 this.dn = dn; 163 } 164 165 166 /** 167 * {@inheritDoc} 168 */ 169 @Override 170 public void addRequestControl( Control requestControl ) 171 { 172 requestControls.put( requestControl.getOid(), requestControl ); 173 } 174 175 176 /** 177 * {@inheritDoc} 178 */ 179 @Override 180 public Control getRequestControl( String numericOid ) 181 { 182 return requestControls.get( numericOid ); 183 } 184 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override 190 public boolean hasRequestControl( String numericOid ) 191 { 192 return requestControls.containsKey( numericOid ); 193 } 194 195 196 /** 197 * {@inheritDoc} 198 */ 199 @Override 200 public boolean hasRequestControls() 201 { 202 return !requestControls.isEmpty(); 203 } 204 205 206 /** 207 * {@inheritDoc} 208 */ 209 @Override 210 public void addResponseControl( Control responseControl ) 211 { 212 responseControls.put( responseControl.getOid(), responseControl ); 213 } 214 215 216 /** 217 * {@inheritDoc} 218 */ 219 @Override 220 public Control getResponseControl( String numericOid ) 221 { 222 return responseControls.get( numericOid ); 223 } 224 225 226 /** 227 * {@inheritDoc} 228 */ 229 @Override 230 public boolean hasResponseControl( String numericOid ) 231 { 232 return responseControls.containsKey( numericOid ); 233 } 234 235 236 /** 237 * {@inheritDoc} 238 */ 239 @Override 240 public Control[] getResponseControls() 241 { 242 if ( responseControls.isEmpty() ) 243 { 244 return EMPTY_CONTROLS; 245 } 246 247 return responseControls.values().toArray( EMPTY_CONTROLS ); 248 } 249 250 251 /** 252 * {@inheritDoc} 253 */ 254 @Override 255 public boolean hasResponseControls() 256 { 257 return !responseControls.isEmpty(); 258 } 259 260 261 /** 262 * {@inheritDoc} 263 */ 264 @Override 265 public int getResponseControlCount() 266 { 267 return responseControls.size(); 268 } 269 270 271 /** 272 * {@inheritDoc} 273 */ 274 @Override 275 public void addRequestControls( Control[] requestControls ) 276 { 277 for ( Control c : requestControls ) 278 { 279 this.requestControls.put( c.getOid(), c ); 280 } 281 } 282 283 284 /** 285 * {@inheritDoc} 286 */ 287 public void setRequestControls( Map<String, Control> requestControls ) 288 { 289 this.requestControls = requestControls; 290 } 291 292 293 /** 294 * @return the originalEntry 295 */ 296 public Entry getOriginalEntry() 297 { 298 return originalEntry; 299 } 300 301 302 /** 303 * @param originalEntry the originalEntry to set 304 */ 305 public void setOriginalEntry( Entry originalEntry ) 306 { 307 this.originalEntry = originalEntry; 308 } 309 310 311 /** 312 * {@inheritDoc} 313 */ 314 @Override 315 public final void setInterceptors( List<String> interceptors ) 316 { 317 this.interceptors = interceptors; 318 } 319 320 321 /** 322 * {@inheritDoc} 323 */ 324 @Override 325 public final String getNextInterceptor() 326 { 327 if ( currentInterceptor == interceptors.size() ) 328 { 329 return "FINAL"; 330 } 331 332 String interceptor = interceptors.get( currentInterceptor ); 333 currentInterceptor++; 334 335 return interceptor; 336 } 337 338 339 /** 340 * @return The number of the current interceptor in the list 341 */ 342 @Override 343 public int getCurrentInterceptor() 344 { 345 return currentInterceptor; 346 } 347 348 349 /** 350 * Sets the current interceptor number to a new value. 351 * 352 * @param currentInterceptor The new current interceptor value 353 */ 354 @Override 355 public void setCurrentInterceptor( int currentInterceptor ) 356 { 357 this.currentInterceptor = currentInterceptor; 358 } 359 360 361 private void setup( AbstractOperationContext opContext ) 362 { 363 opContext.setAuthorizedPrincipal( authorizedPrincipal ); 364 } 365 366 367 /** 368 * {@inheritDoc} 369 */ 370 @Override 371 public void delete( Dn dn ) throws LdapException 372 { 373 DeleteOperationContext deleteContext = new DeleteOperationContext( session, dn ); 374 setup( deleteContext ); 375 session.getDirectoryService().getOperationManager().delete( deleteContext ); 376 } 377 378 379 /** 380 * {@inheritDoc} 381 */ 382 @Override 383 public Entry lookup( LookupOperationContext lookupContext ) throws LdapException 384 { 385 return session.getDirectoryService().getOperationManager().lookup( lookupContext ); 386 } 387 388 389 // TODO - need synchronization here and where we update links 390 /** 391 * {@inheritDoc} 392 */ 393 @Override 394 public LookupOperationContext newLookupContext( Dn dn, String... attributes ) 395 { 396 LookupOperationContext lookupContext = new LookupOperationContext( session, dn, attributes ); 397 setup( lookupContext ); 398 399 return lookupContext; 400 } 401 402 403 /** 404 * {@inheritDoc} 405 */ 406 @Override 407 public LdapPrincipal getEffectivePrincipal() 408 { 409 if ( authorizedPrincipal != null ) 410 { 411 return authorizedPrincipal; 412 } 413 414 return session.getEffectivePrincipal(); 415 } 416 417 418 // ----------------------------------------------------------------------- 419 // OperationContext Linked List Methods 420 // ----------------------------------------------------------------------- 421 /** 422 * @param entry the entry to set 423 */ 424 @Override 425 public void setEntry( Entry entry ) 426 { 427 this.entry = entry; 428 } 429 430 431 /** 432 * @return the entry 433 */ 434 @Override 435 public Entry getEntry() 436 { 437 return entry; 438 } 439 440 441 /** 442 * Set the throwReferral flag to true 443 */ 444 @Override 445 public void throwReferral() 446 { 447 throwReferral = true; 448 } 449 450 451 /** 452 * @return <code>true</code> if the referrals are thrown 453 */ 454 @Override 455 public boolean isReferralThrown() 456 { 457 return throwReferral; 458 } 459 460 461 /** 462 * Set the throwReferral flag to false 463 */ 464 @Override 465 public void ignoreReferral() 466 { 467 throwReferral = false; 468 } 469 470 471 /** 472 * @return <code>true</code> if the referrals are ignored 473 */ 474 @Override 475 public boolean isReferralIgnored() 476 { 477 return !throwReferral; 478 } 479 480 481 /** 482 * @return the transaction 483 */ 484 @Override 485 public PartitionTxn getTransaction() 486 { 487 return transaction; 488 } 489 490 491 /** 492 * @param transaction the transaction to set 493 */ 494 @Override 495 public void setTransaction( PartitionTxn transaction ) 496 { 497 this.transaction = transaction; 498 } 499 500 501 /** 502 * {@inheritDoc} 503 */ 504 @Override 505 public Partition getPartition() 506 { 507 return partition; 508 } 509 510 511 /** 512 * {@inheritDoc} 513 */ 514 @Override 515 public void setPartition( Partition partition ) 516 { 517 this.partition = partition; 518 } 519}