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.server.core.schema; 021 022 023 import java.util.ArrayList; 024 import java.util.HashMap; 025 import java.util.HashSet; 026 import java.util.List; 027 import java.util.Map; 028 import java.util.Set; 029 030 import javax.naming.NamingException; 031 import javax.naming.directory.SearchControls; 032 033 import org.apache.directory.server.constants.ServerDNConstants; 034 import org.apache.directory.server.core.filtering.EntryFilteringCursor; 035 import org.apache.directory.server.core.interceptor.context.LookupOperationContext; 036 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext; 037 import org.apache.directory.server.core.interceptor.context.SearchOperationContext; 038 import org.apache.directory.server.core.partition.Partition; 039 import org.apache.directory.server.i18n.I18n; 040 import org.apache.directory.shared.ldap.constants.MetaSchemaConstants; 041 import org.apache.directory.shared.ldap.constants.SchemaConstants; 042 import org.apache.directory.shared.ldap.entry.StringValue; 043 import org.apache.directory.shared.ldap.entry.DefaultServerAttribute; 044 import org.apache.directory.shared.ldap.entry.EntryAttribute; 045 import org.apache.directory.shared.ldap.entry.Modification; 046 import org.apache.directory.shared.ldap.entry.ModificationOperation; 047 import org.apache.directory.shared.ldap.entry.ServerEntry; 048 import org.apache.directory.shared.ldap.entry.ServerModification; 049 import org.apache.directory.shared.ldap.filter.AndNode; 050 import org.apache.directory.shared.ldap.filter.BranchNode; 051 import org.apache.directory.shared.ldap.filter.EqualityNode; 052 import org.apache.directory.shared.ldap.filter.ExprNode; 053 import org.apache.directory.shared.ldap.filter.OrNode; 054 import org.apache.directory.shared.ldap.filter.PresenceNode; 055 import org.apache.directory.shared.ldap.filter.SearchScope; 056 import org.apache.directory.shared.ldap.filter.SimpleNode; 057 import org.apache.directory.shared.ldap.message.AliasDerefMode; 058 import org.apache.directory.shared.ldap.name.DN; 059 import org.apache.directory.shared.ldap.name.RDN; 060 import org.apache.directory.shared.ldap.schema.AttributeType; 061 import org.apache.directory.shared.ldap.schema.AttributeTypeOptions; 062 import org.apache.directory.shared.ldap.schema.MatchingRule; 063 import org.apache.directory.shared.ldap.schema.ObjectClass; 064 import org.apache.directory.shared.ldap.schema.SchemaManager; 065 import org.apache.directory.shared.ldap.schema.loader.ldif.SchemaEntityFactory; 066 import org.apache.directory.shared.ldap.schema.registries.Schema; 067 import org.apache.directory.shared.ldap.schema.syntaxCheckers.NumericOidSyntaxChecker; 068 import org.apache.directory.shared.ldap.util.DateUtils; 069 import org.slf4j.Logger; 070 import org.slf4j.LoggerFactory; 071 072 073 /** 074 * A specialized data access object for managing schema objects in the 075 * schema partition. 076 * 077 * WARNING: 078 * This dao operates directly on a partition. Hence no interceptors are available 079 * to perform the various expected services of respective interceptors. Take care 080 * to normalize all filters and distinguished names. 081 * 082 * A single write operation exists for enabling schemas needed for operating indices 083 * in partitions and enabling schemas that are dependencies of other schemas that 084 * are enabled. In both these limited cases there is no need to worry about issues 085 * with a lack of replication propagation because these same updates will take place 086 * on replicas when the original operation is propagated or when replicas start up. 087 * 088 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 089 * @version $Rev$ 090 */ 091 public class SchemaPartitionDaoImpl implements SchemaPartitionDao 092 { 093 /** static class logger */ 094 private final Logger LOG = LoggerFactory.getLogger( getClass() ); 095 private static final NumericOidSyntaxChecker NUMERIC_OID_CHECKER = new NumericOidSyntaxChecker(); 096 private static final String[] SCHEMA_ATTRIBUTES = new String[] 097 { SchemaConstants.CREATORS_NAME_AT_OID, "m-dependencies", SchemaConstants.OBJECT_CLASS_AT_OID, 098 SchemaConstants.CN_AT_OID, "m-disabled" }; 099 100 private final Partition partition; 101 private final SchemaEntityFactory factory; 102 private final SchemaManager schemaManager; 103 104 private final String M_NAME_OID; 105 private final String CN_OID; 106 private final String M_OID_OID; 107 private final String OBJECTCLASS_OID; 108 private final String M_SYNTAX_OID; 109 private final String M_ORDERING_OID; 110 private final String M_SUBSTRING_OID; 111 private final String M_EQUALITY_OID; 112 private final String M_SUP_ATTRIBUTE_TYPE_OID; 113 private final String M_MUST_OID; 114 private final String M_MAY_OID; 115 private final String M_AUX_OID; 116 private final String M_OC_OID; 117 private final String M_SUP_OBJECT_CLASS_OID; 118 private final String M_DEPENDENCIES_OID; 119 120 private final Set<AttributeTypeOptions> schemaAttributesToReturn = new HashSet<AttributeTypeOptions>(); 121 private final AttributeType disabledAttributeType; 122 123 124 /** 125 * Creates a schema dao object backing information within a schema partition. 126 * 127 * @param partition the schema partition 128 * @param registries the bootstrap registries that were used to start up the schema partition 129 * @throws NamingException if there are problems initializing this schema partion dao 130 */ 131 public SchemaPartitionDaoImpl( Partition partition, SchemaManager schemaManager ) throws Exception 132 { 133 this.partition = partition; 134 this.factory = new SchemaEntityFactory(); 135 this.schemaManager = schemaManager; 136 137 this.M_NAME_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_NAME_AT ); 138 this.CN_OID = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.CN_AT ); 139 this.disabledAttributeType = schemaManager.lookupAttributeTypeRegistry( MetaSchemaConstants.M_DISABLED_AT ); 140 this.M_OID_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_OID_AT ); 141 this.OBJECTCLASS_OID = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.OBJECT_CLASS_AT ); 142 this.M_SYNTAX_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SYNTAX_AT ); 143 this.M_ORDERING_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_ORDERING_AT ); 144 this.M_EQUALITY_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_EQUALITY_AT ); 145 this.M_SUBSTRING_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SUBSTR_AT ); 146 this.M_SUP_ATTRIBUTE_TYPE_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SUP_ATTRIBUTE_TYPE_AT ); 147 this.M_MUST_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_MUST_AT ); 148 this.M_MAY_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_MAY_AT ); 149 this.M_AUX_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_AUX_AT ); 150 this.M_OC_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_OC_AT ); 151 this.M_SUP_OBJECT_CLASS_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SUP_OBJECT_CLASS_AT ); 152 this.M_DEPENDENCIES_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_DEPENDENCIES_AT ); 153 154 for ( String attrId : SCHEMA_ATTRIBUTES ) 155 { 156 AttributeTypeOptions ato = new AttributeTypeOptions( schemaManager.lookupAttributeTypeRegistry( attrId ) ); 157 schemaAttributesToReturn.add( ato ); 158 } 159 } 160 161 162 /* (non-Javadoc) 163 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#getSchemas() 164 */ 165 public Map<String, Schema> getSchemas() throws Exception 166 { 167 Map<String, Schema> schemas = new HashMap<String, Schema>(); 168 EntryFilteringCursor list = listSchemas(); 169 170 while ( list.next() ) 171 { 172 ServerEntry sr = list.get(); 173 Schema schema = factory.getSchema( sr ); 174 schemas.put( schema.getSchemaName(), schema ); 175 } 176 177 return schemas; 178 } 179 180 181 /* (non-Javadoc) 182 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#getSchemaNames() 183 */ 184 public Set<String> getSchemaNames() throws Exception 185 { 186 Set<String> schemaNames = new HashSet<String>(); 187 EntryFilteringCursor list = listSchemas(); 188 189 while ( list.next() ) 190 { 191 ServerEntry sr = list.get(); 192 schemaNames.add( sr.get( SchemaConstants.CN_AT ).getString() ); 193 } 194 195 return schemaNames; 196 } 197 198 199 private EntryFilteringCursor listSchemas() throws Exception 200 { 201 DN base = new DN( SchemaConstants.OU_SCHEMA ); 202 base.normalize( schemaManager.getNormalizerMapping() ); 203 ExprNode filter = new EqualityNode<String>( schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.OBJECT_CLASS_AT ), 204 new StringValue( MetaSchemaConstants.META_SCHEMA_OC ) ); 205 206 SearchOperationContext searchContext = new SearchOperationContext( null ); 207 searchContext.setDn( base ); 208 searchContext.setScope( SearchScope.ONELEVEL ); 209 searchContext.setReturningAttributes( schemaAttributesToReturn ); 210 searchContext.setFilter( filter ); 211 return partition.search( searchContext ); 212 } 213 214 215 /* (non-Javadoc) 216 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#getSchema(java.lang.String) 217 */ 218 public Schema getSchema( String schemaName ) throws Exception 219 { 220 DN dn = new DN( "cn=" + schemaName + ",ou=schema" ); 221 dn.normalize( schemaManager.getNormalizerMapping() ); 222 return factory.getSchema( partition.lookup( new LookupOperationContext( null, dn ) ) ); 223 } 224 225 226 /* (non-Javadoc) 227 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasMatchingRule(java.lang.String) 228 */ 229 public boolean hasMatchingRule( String oid ) throws Exception 230 { 231 BranchNode filter = new AndNode(); 232 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( 233 MetaSchemaConstants.META_MATCHING_RULE_OC ) ) ); 234 235 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) ) 236 { 237 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) ); 238 } 239 else 240 { 241 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) ); 242 } 243 244 SearchControls searchControls = new SearchControls(); 245 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 246 EntryFilteringCursor cursor = null; 247 248 try 249 { 250 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 251 filter, searchControls ); 252 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 253 254 cursor = partition.search( searchOperationContext ); 255 256 if ( !cursor.next() ) 257 { 258 return false; 259 } 260 261 if ( cursor.next() ) 262 { 263 throw new NamingException( I18n.err( I18n.ERR_430, oid ) ); 264 } 265 266 return true; 267 } 268 finally 269 { 270 if ( cursor != null ) 271 { 272 cursor.close(); 273 } 274 } 275 } 276 277 278 /* (non-Javadoc) 279 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasAttributeType(java.lang.String) 280 */ 281 public boolean hasAttributeType( String oid ) throws Exception 282 { 283 BranchNode filter = new AndNode(); 284 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( 285 MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC ) ) ); 286 287 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) ) 288 { 289 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) ); 290 } 291 else 292 { 293 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) ); 294 } 295 296 SearchControls searchControls = new SearchControls(); 297 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 298 EntryFilteringCursor cursor = null; 299 300 try 301 { 302 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 303 filter, searchControls ); 304 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 305 306 cursor = partition.search( searchOperationContext ); 307 308 if ( !cursor.next() ) 309 { 310 return false; 311 } 312 313 if ( cursor.next() ) 314 { 315 throw new NamingException( I18n.err( I18n.ERR_431, oid ) ); 316 } 317 318 return true; 319 } 320 finally 321 { 322 if ( cursor != null ) 323 { 324 cursor.close(); 325 } 326 } 327 } 328 329 330 /* (non-Javadoc) 331 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasObjectClass(java.lang.String) 332 */ 333 public boolean hasObjectClass( String oid ) throws Exception 334 { 335 BranchNode filter = new AndNode(); 336 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 337 new StringValue( MetaSchemaConstants.META_OBJECT_CLASS_OC ) ) ); 338 339 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) ) 340 { 341 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) ); 342 } 343 else 344 { 345 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) ); 346 } 347 348 SearchControls searchControls = new SearchControls(); 349 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 350 EntryFilteringCursor cursor = null; 351 352 try 353 { 354 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 355 filter, searchControls ); 356 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 357 358 cursor = partition.search( searchOperationContext ); 359 360 if ( !cursor.next() ) 361 { 362 return false; 363 } 364 365 if ( cursor.next() ) 366 { 367 throw new NamingException( I18n.err( I18n.ERR_431, oid ) ); 368 } 369 370 return true; 371 } 372 finally 373 { 374 if ( cursor != null ) 375 { 376 cursor.close(); 377 } 378 } 379 } 380 381 382 /* (non-Javadoc) 383 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasSyntax(java.lang.String) 384 */ 385 public boolean hasSyntax( String oid ) throws Exception 386 { 387 BranchNode filter = new AndNode(); 388 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 389 new StringValue( MetaSchemaConstants.META_SYNTAX_OC ) ) ); 390 391 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) ) 392 { 393 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) ); 394 } 395 else 396 { 397 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) ); 398 } 399 400 SearchControls searchControls = new SearchControls(); 401 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 402 EntryFilteringCursor cursor = null; 403 404 try 405 { 406 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 407 filter, searchControls ); 408 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 409 410 cursor = partition.search( searchOperationContext ); 411 412 if ( !cursor.next() ) 413 { 414 return false; 415 } 416 417 if ( cursor.next() ) 418 { 419 throw new NamingException( I18n.err( I18n.ERR_432, oid ) ); 420 } 421 422 return true; 423 } 424 finally 425 { 426 if ( cursor != null ) 427 { 428 cursor.close(); 429 } 430 } 431 } 432 433 434 /* (non-Javadoc) 435 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasSyntaxChecker(java.lang.String) 436 */ 437 public boolean hasSyntaxChecker( String oid ) throws Exception 438 { 439 BranchNode filter = new AndNode(); 440 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 441 new StringValue( MetaSchemaConstants.META_SYNTAX_CHECKER_OC ) ) ); 442 443 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) ) 444 { 445 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) ); 446 } 447 else 448 { 449 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) ); 450 } 451 452 SearchControls searchControls = new SearchControls(); 453 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 454 EntryFilteringCursor cursor = null; 455 456 try 457 { 458 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 459 filter, searchControls ); 460 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 461 462 cursor = partition.search( searchOperationContext ); 463 464 if ( !cursor.next() ) 465 { 466 return false; 467 } 468 469 if ( cursor.next() ) 470 { 471 throw new NamingException( I18n.err( I18n.ERR_433, oid ) ); 472 } 473 474 return true; 475 } 476 finally 477 { 478 if ( cursor != null ) 479 { 480 cursor.close(); 481 } 482 } 483 } 484 485 486 /* (non-Javadoc) 487 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#findSchema(java.lang.String) 488 */ 489 public String findSchema( String entityName ) throws Exception 490 { 491 DN dn = findDn( entityName ); 492 if ( dn == null ) 493 { 494 return null; 495 } 496 497 RDN rdn = dn.getRdn( 1 ); 498 499 if ( !rdn.getNormType().equalsIgnoreCase( CN_OID ) ) 500 { 501 throw new NamingException( I18n.err( I18n.ERR_434, dn.getNormName(), CN_OID, rdn.getNormType() ) ); 502 } 503 504 return ( String ) rdn.getNormValue(); 505 } 506 507 508 /* (non-Javadoc) 509 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#findDn(java.lang.String) 510 */ 511 public DN findDn( String entityName ) throws Exception 512 { 513 ServerEntry sr = find( entityName ); 514 DN dn = sr.getDn(); 515 dn.normalize( schemaManager.getNormalizerMapping() ); 516 return dn; 517 } 518 519 520 /* (non-Javadoc) 521 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#find(java.lang.String) 522 */ 523 public ServerEntry find( String entityName ) throws Exception 524 { 525 BranchNode filter = new OrNode(); 526 SimpleNode<String> nameAVA = new EqualityNode<String>( M_NAME_OID, 527 new StringValue( entityName.toLowerCase() ) ); 528 SimpleNode<String> oidAVA = new EqualityNode<String>( M_OID_OID, 529 new StringValue( entityName.toLowerCase() ) ); 530 filter.addNode( nameAVA ); 531 filter.addNode( oidAVA ); 532 SearchControls searchControls = new SearchControls(); 533 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 534 EntryFilteringCursor cursor = null; 535 536 try 537 { 538 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 539 filter, searchControls ); 540 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 541 542 cursor = partition.search( searchOperationContext ); 543 544 if ( !cursor.next() ) 545 { 546 return null; 547 } 548 549 ServerEntry sr = cursor.get(); 550 551 if ( cursor.next() ) 552 { 553 throw new NamingException( I18n.err( I18n.ERR_435, entityName ) ); 554 } 555 556 return sr; 557 } 558 finally 559 { 560 if ( cursor != null ) 561 { 562 cursor.close(); 563 } 564 } 565 } 566 567 568 /* (non-Javadoc) 569 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#enableSchema(java.lang.String) 570 */ 571 public void enableSchema( String schemaName ) throws Exception 572 { 573 DN dn = new DN( "cn=" + schemaName + ",ou=schema" ); 574 dn.normalize( schemaManager.getNormalizerMapping() ); 575 ServerEntry entry = partition.lookup( new LookupOperationContext( null, dn ) ); 576 EntryAttribute disabledAttr = entry.get( disabledAttributeType ); 577 List<Modification> mods = new ArrayList<Modification>( 3 ); 578 579 if ( disabledAttr == null ) 580 { 581 LOG.warn( "Does not make sense: you're trying to enable {} schema which is already enabled", schemaName ); 582 return; 583 } 584 585 boolean isDisabled = disabledAttr.contains( "TRUE" ); 586 587 if ( !isDisabled ) 588 { 589 LOG.warn( "Does not make sense: you're trying to enable {} schema which is already enabled", schemaName ); 590 return; 591 } 592 593 mods.add( new ServerModification( ModificationOperation.REMOVE_ATTRIBUTE, new DefaultServerAttribute( 594 MetaSchemaConstants.M_DISABLED_AT, schemaManager.lookupAttributeTypeRegistry( MetaSchemaConstants.M_DISABLED_AT ) ) ) ); 595 596 mods.add( new ServerModification( ModificationOperation.ADD_ATTRIBUTE, new DefaultServerAttribute( 597 SchemaConstants.MODIFIERS_NAME_AT, schemaManager.lookupAttributeTypeRegistry( SchemaConstants.MODIFIERS_NAME_AT ), 598 ServerDNConstants.ADMIN_SYSTEM_DN ) ) ); 599 600 mods.add( new ServerModification( ModificationOperation.ADD_ATTRIBUTE, new DefaultServerAttribute( 601 SchemaConstants.MODIFY_TIMESTAMP_AT, schemaManager.lookupAttributeTypeRegistry( SchemaConstants.MODIFY_TIMESTAMP_AT ), DateUtils 602 .getGeneralizedTime() ) ) ); 603 604 partition.modify( new ModifyOperationContext( null, dn, mods ) ); 605 } 606 607 608 /* (non-Javadoc) 609 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listSyntaxDependents(java.lang.String) 610 */ 611 public Set<ServerEntry> listSyntaxDependents( String numericOid ) throws Exception 612 { 613 Set<ServerEntry> set = new HashSet<ServerEntry>(); 614 BranchNode filter = new AndNode(); 615 616 // subfilter for (| (objectClass=metaMatchingRule) (objectClass=metaAttributeType)) 617 BranchNode or = new OrNode(); 618 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 619 new StringValue( MetaSchemaConstants.META_MATCHING_RULE_OC.toLowerCase() ) ) ); 620 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 621 new StringValue( MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC.toLowerCase() ) ) ); 622 623 filter.addNode( or ); 624 filter.addNode( new EqualityNode<String>( M_SYNTAX_OID, new StringValue( numericOid.toLowerCase() ) ) ); 625 626 SearchControls searchControls = new SearchControls(); 627 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 628 EntryFilteringCursor cursor = null; 629 630 try 631 { 632 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 633 filter, searchControls ); 634 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 635 636 cursor = partition.search( searchOperationContext ); 637 638 while ( cursor.next() ) 639 { 640 set.add( cursor.get() ); 641 } 642 } 643 finally 644 { 645 if ( cursor != null ) 646 { 647 cursor.close(); 648 } 649 } 650 651 return set; 652 } 653 654 655 /* (non-Javadoc) 656 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listMatchingRuleDependents(org.apache.directory.shared.ldap.schema.MatchingRule) 657 */ 658 public Set<ServerEntry> listMatchingRuleDependents( MatchingRule mr ) throws Exception 659 { 660 Set<ServerEntry> set = new HashSet<ServerEntry>(); 661 BranchNode filter = new AndNode(); 662 663 // ( objectClass = metaAttributeType ) 664 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( 665 MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC.toLowerCase() ) ) ); 666 667 BranchNode or = new OrNode(); 668 or.addNode( new EqualityNode<String>( M_ORDERING_OID, new StringValue( mr.getOid() ) ) ); 669 or.addNode( new EqualityNode<String>( M_SUBSTRING_OID, new StringValue( mr.getOid() ) ) ); 670 or.addNode( new EqualityNode<String>( M_EQUALITY_OID, new StringValue( mr.getOid() ) ) ); 671 filter.addNode( or ); 672 673 List<String> names = mr.getNames(); 674 675 if ( ( names != null ) && ( names.size() > 0 ) ) 676 { 677 for ( String name : names ) 678 { 679 or.addNode( new EqualityNode<String>( M_ORDERING_OID, new StringValue( name.toLowerCase() ) ) ); 680 or.addNode( new EqualityNode<String>( M_SUBSTRING_OID, new StringValue( name.toLowerCase() ) ) ); 681 or.addNode( new EqualityNode<String>( M_EQUALITY_OID, new StringValue( name.toLowerCase() ) ) ); 682 } 683 } 684 685 SearchControls searchControls = new SearchControls(); 686 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 687 EntryFilteringCursor cursor = null; 688 689 try 690 { 691 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 692 filter, searchControls ); 693 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 694 695 cursor = partition.search( searchOperationContext ); 696 697 while ( cursor.next() ) 698 { 699 set.add( cursor.get() ); 700 } 701 } 702 finally 703 { 704 if ( cursor != null ) 705 { 706 cursor.close(); 707 } 708 } 709 710 return set; 711 } 712 713 714 /* (non-Javadoc) 715 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listAllNames() 716 */ 717 public EntryFilteringCursor listAllNames() throws Exception 718 { 719 SearchControls searchControls = new SearchControls(); 720 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 721 BranchNode filter = new AndNode(); 722 723 // (& (m-oid=*) (m-name=*) ) 724 filter.addNode( new PresenceNode( M_OID_OID ) ); 725 filter.addNode( new PresenceNode( M_NAME_OID ) ); 726 727 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 728 filter, searchControls ); 729 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 730 731 return partition.search( searchOperationContext ); 732 } 733 734 735 /* (non-Javadoc) 736 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listAttributeTypeDependents(org.apache.directory.shared.ldap.schema.AttributeType) 737 */ 738 public Set<ServerEntry> listAttributeTypeDependents( AttributeType at ) throws Exception 739 { 740 /* 741 * Right now the following inefficient filter is being used: 742 * 743 * ( & 744 * ( | ( objectClass = metaAttributeType ) ( objectClass = metaObjectClass ) ) 745 * ( | ( m-oid = $oid ) ( m-must = $oid ) ( m-supAttributeType = $oid ) ) 746 * ) 747 * 748 * the reason why this is inefficient is because the or terms have large scan counts 749 * and several loops are going to be required. The following search is better because 750 * it constrains the results better: 751 * 752 * ( | 753 * ( & ( objectClass = metaAttributeType ) ( m-supAttributeType = $oid ) ) 754 * ( & ( objectClass = metaObjectClass ) ( | ( m-may = $oid ) ( m-must = $oid ) ) ) 755 * ) 756 */ 757 758 Set<ServerEntry> set = new HashSet<ServerEntry>(); 759 BranchNode filter = new AndNode(); 760 761 // ( objectClass = metaAttributeType ) 762 BranchNode or = new OrNode(); 763 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 764 new StringValue( MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC.toLowerCase() ) ) ); 765 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 766 new StringValue( MetaSchemaConstants.META_OBJECT_CLASS_OC.toLowerCase() ) ) ); 767 filter.addNode( or ); 768 769 or = new OrNode(); 770 or.addNode( new EqualityNode<String>( M_MAY_OID, new StringValue( at.getOid() ) ) ); 771 or.addNode( new EqualityNode<String>( M_MUST_OID, new StringValue( at.getOid() ) ) ); 772 or.addNode( new EqualityNode<String>( M_SUP_ATTRIBUTE_TYPE_OID, new StringValue( at.getOid() ) ) ); 773 filter.addNode( or ); 774 775 SearchControls searchControls = new SearchControls(); 776 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 777 EntryFilteringCursor cursor = null; 778 779 try 780 { 781 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 782 filter, searchControls ); 783 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 784 785 cursor = partition.search( searchOperationContext ); 786 787 while ( cursor.next() ) 788 { 789 set.add( cursor.get() ); 790 } 791 } 792 finally 793 { 794 if ( cursor != null ) 795 { 796 cursor.close(); 797 } 798 } 799 800 return set; 801 } 802 803 804 /* (non-Javadoc) 805 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listSchemaDependents(java.lang.String) 806 */ 807 public Set<ServerEntry> listSchemaDependents( String schemaName ) throws Exception 808 { 809 /* 810 * The following filter is being used: 811 * 812 * ( & ( objectClass = metaSchema ) ( m-dependencies = $schemaName ) ) 813 */ 814 815 Set<ServerEntry> set = new HashSet<ServerEntry>(); 816 BranchNode filter = new AndNode(); 817 818 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, 819 new StringValue( MetaSchemaConstants.META_SCHEMA_OC.toLowerCase() ) ) ); 820 filter.addNode( new EqualityNode<String>( M_DEPENDENCIES_OID, 821 new StringValue( schemaName.toLowerCase() ) ) ); 822 823 SearchControls searchControls = new SearchControls(); 824 searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE ); 825 EntryFilteringCursor cursor = null; 826 827 try 828 { 829 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 830 filter, searchControls ); 831 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 832 833 cursor = partition.search( searchOperationContext ); 834 835 while ( cursor.next() ) 836 { 837 set.add( cursor.get() ); 838 } 839 } 840 finally 841 { 842 if ( cursor != null ) 843 { 844 cursor.close(); 845 } 846 } 847 848 return set; 849 } 850 851 852 /* (non-Javadoc) 853 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listEnabledSchemaDependents(java.lang.String) 854 */ 855 public Set<ServerEntry> listEnabledSchemaDependents( String schemaName ) throws Exception 856 { 857 Set<ServerEntry> set = new HashSet<ServerEntry>(); 858 BranchNode filter = new AndNode(); 859 860 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( 861 MetaSchemaConstants.META_SCHEMA_OC.toLowerCase() ) ) ); 862 filter.addNode( new EqualityNode<String>( M_DEPENDENCIES_OID, new StringValue( 863 schemaName.toLowerCase() ) ) ); 864 865 SearchControls searchControls = new SearchControls(); 866 searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE ); 867 EntryFilteringCursor cursor = null; 868 869 try 870 { 871 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 872 filter, searchControls ); 873 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 874 875 cursor = partition.search( searchOperationContext ); 876 877 while ( cursor.next() ) 878 { 879 ServerEntry sr = cursor.get(); 880 EntryAttribute disabled = sr.get( disabledAttributeType ); 881 882 if ( disabled == null ) 883 { 884 set.add( sr ); 885 } 886 else if ( disabled.get().equals( "FALSE" ) ) 887 { 888 set.add( sr ); 889 } 890 } 891 } 892 finally 893 { 894 if ( cursor != null ) 895 { 896 cursor.close(); 897 } 898 } 899 900 return set; 901 } 902 903 904 /* (non-Javadoc) 905 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listObjectClassDependents(org.apache.directory.shared.ldap.schema.ObjectClass) 906 */ 907 public Set<ServerEntry> listObjectClassDependents( ObjectClass oc ) throws Exception 908 { 909 /* 910 * Right now the following inefficient filter is being used: 911 * 912 * ( & 913 * ( | ( objectClass = metaObjectClass ) ( objectClass = metaDITContentRule ) 914 * ( objectClass = metaNameForm ) ) 915 * ( | ( m-oc = $oid ) ( m-aux = $oid ) ( m-supObjectClass = $oid ) ) 916 * ) 917 * 918 * The reason why this is inefficient is because the or terms have large scan counts 919 * and several loops are going to be required. For example all the objectClasses and 920 * all the metaDITContentRules and all the metaNameForm candidates will be a massive 921 * number. This is probably going to be bigger than the 2nd term where a candidate 922 * satisfies one of the terms. 923 * 924 * The following search is better because it constrains the results better: 925 * 926 * ( | 927 * ( & ( objectClass = metaNameForm ) ( m-oc = $oid ) ) 928 * ( & ( objectClass = metaObjectClass ) ( m-supObjectClass = $oid ) ) 929 * ( & ( objectClass = metaDITContentRule ) ( m-aux = $oid ) ) 930 * ) 931 */ 932 933 Set<ServerEntry> set = new HashSet<ServerEntry>(); 934 BranchNode filter = new AndNode(); 935 936 BranchNode or = new OrNode(); 937 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( MetaSchemaConstants.META_NAME_FORM_OC 938 .toLowerCase() ) ) ); 939 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( MetaSchemaConstants.META_OBJECT_CLASS_OC 940 .toLowerCase() ) ) ); 941 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( 942 MetaSchemaConstants.META_DIT_CONTENT_RULE_OC.toLowerCase() ) ) ); 943 filter.addNode( or ); 944 945 or = new OrNode(); 946 or.addNode( new EqualityNode<String>( M_AUX_OID, new StringValue( oc.getOid() ) ) ); 947 or.addNode( new EqualityNode<String>( M_OC_OID, new StringValue( oc.getOid() ) ) ); 948 or.addNode( new EqualityNode<String>( M_SUP_OBJECT_CLASS_OID, new StringValue( oc.getOid() ) ) ); 949 filter.addNode( or ); 950 951 SearchControls searchControls = new SearchControls(); 952 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE ); 953 EntryFilteringCursor cursor = null; 954 955 try 956 { 957 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(), 958 filter, searchControls ); 959 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS ); 960 961 cursor = partition.search( searchOperationContext ); 962 963 while ( cursor.next() ) 964 { 965 set.add( cursor.get() ); 966 } 967 } 968 finally 969 { 970 if ( cursor != null ) 971 { 972 cursor.close(); 973 } 974 } 975 976 return set; 977 } 978 }