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.schema.registries; 021 022 023 import java.util.ArrayList; 024 import java.util.Collection; 025 import java.util.HashMap; 026 import java.util.HashSet; 027 import java.util.List; 028 import java.util.Map; 029 import java.util.Set; 030 031 import org.apache.directory.shared.i18n.I18n; 032 import org.apache.directory.shared.ldap.constants.MetaSchemaConstants; 033 import org.apache.directory.shared.ldap.constants.SchemaConstants; 034 import org.apache.directory.shared.ldap.entry.Entry; 035 import org.apache.directory.shared.ldap.entry.EntryAttribute; 036 import org.apache.directory.shared.ldap.entry.Value; 037 import org.apache.directory.shared.ldap.util.StringTools; 038 import org.slf4j.Logger; 039 import org.slf4j.LoggerFactory; 040 041 042 /** 043 * An abstract class with a utility method and setListener() implemented. 044 * 045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 046 * @version $Rev$ 047 */ 048 public abstract class AbstractSchemaLoader implements SchemaLoader 049 { 050 /** static class logger */ 051 private static final Logger LOG = LoggerFactory.getLogger( AbstractSchemaLoader.class ); 052 053 protected SchemaLoaderListener listener; 054 055 /** 056 * A map of all available schema names to schema objects. This map is 057 * populated when this class is created with all the schemas present in 058 * the LDIF based schema repository. 059 */ 060 protected final Map<String, Schema> schemaMap = new HashMap<String, Schema>(); 061 062 063 public void setListener( SchemaLoaderListener listener ) 064 { 065 this.listener = listener; 066 } 067 068 069 protected final void notifyListenerOrRegistries( Schema schema, Registries registries ) 070 { 071 if ( listener != null ) 072 { 073 listener.schemaLoaded( schema ); 074 } 075 076 if ( registries instanceof SchemaLoaderListener ) 077 { 078 if ( registries != listener ) 079 { 080 SchemaLoaderListener listener = ( SchemaLoaderListener ) registries; 081 listener.schemaLoaded( schema ); 082 } 083 } 084 } 085 086 087 /** 088 * {@inheritDoc} 089 */ 090 public final Collection<Schema> getAllEnabled() throws Exception 091 { 092 Collection<Schema> enabledSchemas = new ArrayList<Schema>(); 093 094 for ( Schema schema : schemaMap.values() ) 095 { 096 if ( schema.isEnabled() ) 097 { 098 enabledSchemas.add( schema ); 099 } 100 } 101 102 return enabledSchemas; 103 } 104 105 106 /** 107 * {@inheritDoc} 108 */ 109 public final Collection<Schema> getAllSchemas() throws Exception 110 { 111 return schemaMap.values(); 112 } 113 114 115 /** 116 * {@inheritDoc} 117 */ 118 public Schema getSchema( String schemaName ) 119 { 120 return schemaMap.get( StringTools.toLowerCase( schemaName ) ); 121 } 122 123 124 /** 125 * {@inheritDoc} 126 */ 127 public void addSchema( Schema schema ) 128 { 129 schemaMap.put( schema.getSchemaName(), schema ); 130 } 131 132 133 /** 134 * {@inheritDoc} 135 */ 136 public void removeSchema( Schema schema ) 137 { 138 schemaMap.remove( schema.getSchemaName() ); 139 } 140 141 142 protected Schema getSchema( Entry entry ) throws Exception 143 { 144 EntryAttribute objectClasses = entry.get( SchemaConstants.OBJECT_CLASS_AT ); 145 boolean isSchema = false; 146 147 for ( Value<?> value : objectClasses ) 148 { 149 if ( MetaSchemaConstants.META_SCHEMA_OC.equalsIgnoreCase( value.getString() ) ) 150 { 151 isSchema = true; 152 break; 153 } 154 } 155 156 if ( !isSchema ) 157 { 158 return null; 159 } 160 161 String name; 162 String owner; 163 String[] dependencies = StringTools.EMPTY_STRINGS; 164 boolean isDisabled = false; 165 166 if ( entry == null ) 167 { 168 throw new NullPointerException( I18n.err( I18n.ERR_04261 ) ); 169 } 170 171 if ( entry.get( SchemaConstants.CN_AT ) == null ) 172 { 173 throw new NullPointerException( I18n.err( I18n.ERR_04262 ) ); 174 } 175 176 name = entry.get( SchemaConstants.CN_AT ).getString(); 177 178 if ( entry.get( SchemaConstants.CREATORS_NAME_AT ) == null ) 179 { 180 throw new NullPointerException( "entry must have a valid " + SchemaConstants.CREATORS_NAME_AT 181 + " attribute" ); 182 } 183 184 owner = entry.get( SchemaConstants.CREATORS_NAME_AT ).getString(); 185 186 if ( entry.get( MetaSchemaConstants.M_DISABLED_AT ) != null ) 187 { 188 String value = entry.get( MetaSchemaConstants.M_DISABLED_AT ).getString(); 189 value = value.toUpperCase(); 190 isDisabled = value.equals( "TRUE" ); 191 } 192 193 if ( entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT ) != null ) 194 { 195 Set<String> depsSet = new HashSet<String>(); 196 EntryAttribute depsAttr = entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT ); 197 198 for ( Value<?> value : depsAttr ) 199 { 200 depsSet.add( value.getString() ); 201 } 202 203 dependencies = depsSet.toArray( StringTools.EMPTY_STRINGS ); 204 } 205 206 return new DefaultSchema( name, owner, dependencies, isDisabled ) 207 { 208 }; 209 } 210 211 212 /** 213 * {@inheritDoc} 214 * 215 public List<Throwable> loadWithDependencies( Registries registries, boolean check, Schema... schemas ) throws Exception 216 { 217 // Relax the controls at first 218 List<Throwable> errors = new ArrayList<Throwable>(); 219 boolean wasRelaxed = registries.isRelaxed(); 220 registries.setRelaxed( true ); 221 222 Map<String,Schema> notLoaded = new HashMap<String,Schema>(); 223 224 for ( Schema schema : schemas ) 225 { 226 if ( ! registries.isSchemaLoaded( schema.getSchemaName() ) ) 227 { 228 notLoaded.put( schema.getSchemaName(), schema ); 229 } 230 } 231 232 for ( Schema schema : notLoaded.values() ) 233 { 234 Stack<String> beenthere = new Stack<String>(); 235 loadDepsFirst( schema, beenthere, notLoaded, schema, registries ); 236 } 237 238 // At the end, check the registries if required 239 if ( check ) 240 { 241 errors = registries.checkRefInteg(); 242 } 243 244 // Restore the Registries isRelaxed flag 245 registries.setRelaxed( wasRelaxed ); 246 247 return errors; 248 } 249 250 251 /** 252 * Register the comparator contained in the given LdifEntry into the registries. 253 * 254 * @param registries The Registries 255 * @param entry The LdifEntry containing the comparator description 256 * @param schema The associated schema 257 * @throws Exception If the registering failed 258 * 259 protected LdapComparator<?> registerComparator( Registries registries, LdifEntry entry, Schema schema ) 260 throws Exception 261 { 262 return registerComparator( registries, entry.getEntry(), schema ); 263 } 264 265 266 /** 267 * Register the comparator contained in the given Entry into the registries. 268 * 269 * @param registries The Registries 270 * @param entry The Entry containing the comparator description 271 * @param schema The associated schema 272 * @throws Exception If the registering failed 273 * 274 protected LdapComparator<?> registerComparator( Registries registries, Entry entry, Schema schema ) 275 throws Exception 276 { 277 LdapComparator<?> comparator = 278 factory.getLdapComparator( entry, registries, schema.getSchemaName() ); 279 comparator.setOid( entry.get( MetaSchemaConstants.M_OID_AT ).getString() ); 280 281 if ( registries.isRelaxed() ) 282 { 283 if ( registries.acceptDisabled() ) 284 { 285 registries.register( comparator ); 286 } 287 else if ( schema.isEnabled() && comparator.isEnabled() ) 288 { 289 registries.register( comparator ); 290 } 291 } 292 else 293 { 294 if ( schema.isEnabled() && comparator.isEnabled() ) 295 { 296 registries.register( comparator ); 297 } 298 } 299 300 return comparator; 301 } 302 303 304 /** 305 * Register the SyntaxChecker contained in the given LdifEntry into the registries. 306 * 307 * @param registries The Registries 308 * @param entry The LdifEntry containing the SyntaxChecker description 309 * @param schema The associated schema 310 * @return the created SyntaxChecker instance 311 * @throws Exception If the registering failed 312 * 313 protected SyntaxChecker registerSyntaxChecker( Registries registries, LdifEntry entry, Schema schema) 314 throws Exception 315 { 316 SyntaxChecker syntaxChecker = 317 factory.getSyntaxChecker( entry.getEntry(), registries, schema.getSchemaName() ); 318 syntaxChecker.setOid( entry.get( MetaSchemaConstants.M_OID_AT ).getString() ); 319 320 if ( registries.isRelaxed() ) 321 { 322 if ( registries.acceptDisabled() ) 323 { 324 registries.register( syntaxChecker ); 325 } 326 else if ( schema.isEnabled() && syntaxChecker.isEnabled() ) 327 { 328 registries.register( syntaxChecker ); 329 } 330 } 331 else 332 { 333 if ( schema.isEnabled() && syntaxChecker.isEnabled() ) 334 { 335 registries.register( syntaxChecker ); 336 } 337 } 338 339 return syntaxChecker; 340 } 341 342 343 /** 344 * Register the Normalizer contained in the given LdifEntry into the registries. 345 * 346 * @param registries The Registries 347 * @param entry The LdifEntry containing the Normalizer description 348 * @param schema The associated schema 349 * @return the created Normalizer instance 350 * @throws Exception If the registering failed 351 * 352 protected Normalizer registerNormalizer( Registries registries, LdifEntry entry, Schema schema) 353 throws Exception 354 { 355 Normalizer normalizer = 356 factory.getNormalizer( entry.getEntry(), registries, schema.getSchemaName() ); 357 358 if ( registries.isRelaxed() ) 359 { 360 if ( registries.acceptDisabled() ) 361 { 362 registries.register( normalizer ); 363 } 364 else if ( schema.isEnabled() && normalizer.isEnabled() ) 365 { 366 registries.register( normalizer ); 367 } 368 } 369 else 370 { 371 if ( schema.isEnabled() && normalizer.isEnabled() ) 372 { 373 registries.register( normalizer ); 374 } 375 } 376 377 return normalizer; 378 } 379 380 381 /** 382 * Register the MatchingRule contained in the given LdifEntry into the registries. 383 * 384 * @param registries The Registries 385 * @param entry The LdifEntry containing the MatchingRule description 386 * @param schema The associated schema 387 * @return the created MatchingRule instance 388 * @throws Exception If the registering failed 389 * 390 protected MatchingRule registerMatchingRule( Registries registries, LdifEntry entry, Schema schema) 391 throws Exception 392 { 393 MatchingRule matchingRule = factory.getMatchingRule( 394 entry.getEntry(), registries, schema.getSchemaName() ); 395 396 if ( registries.isRelaxed() ) 397 { 398 if ( registries.acceptDisabled() ) 399 { 400 registries.register( matchingRule ); 401 } 402 else if ( schema.isEnabled() && matchingRule.isEnabled() ) 403 { 404 registries.register( matchingRule ); 405 } 406 } 407 else 408 { 409 if ( schema.isEnabled() && matchingRule.isEnabled() ) 410 { 411 registries.register( matchingRule ); 412 } 413 } 414 415 return matchingRule; 416 } 417 418 419 /** 420 * Register the Syntax contained in the given LdifEntry into the registries. 421 * 422 * @param registries The Registries 423 * @param entry The LdifEntry containing the Syntax description 424 * @param schema The associated schema 425 * @return the created Syntax instance 426 * @throws Exception If the registering failed 427 * 428 protected LdapSyntax registerSyntax( Registries registries, LdifEntry entry, Schema schema) 429 throws Exception 430 { 431 LdapSyntax syntax = factory.getSyntax( 432 entry.getEntry(), registries, schema.getSchemaName() ); 433 434 if ( registries.isRelaxed() ) 435 { 436 if ( registries.acceptDisabled() ) 437 { 438 registries.register( syntax ); 439 } 440 else if ( schema.isEnabled() && syntax.isEnabled() ) 441 { 442 registries.register( syntax ); 443 } 444 } 445 else 446 { 447 if ( schema.isEnabled() && syntax.isEnabled() ) 448 { 449 registries.register( syntax ); 450 } 451 } 452 453 return syntax; 454 } 455 456 457 /** 458 * Register the AttributeType contained in the given LdifEntry into the registries. 459 * 460 * @param registries The Registries 461 * @param entry The LdifEntry containing the AttributeType description 462 * @param schema The associated schema 463 * @return the created AttributeType instance 464 * @throws Exception If the registering failed 465 * 466 protected AttributeType registerAttributeType( Registries registries, LdifEntry entry, Schema schema ) 467 throws Exception 468 { 469 AttributeType attributeType = factory.getAttributeType( entry.getEntry(), registries, schema.getSchemaName() ); 470 471 if ( registries.isRelaxed() ) 472 { 473 if ( registries.acceptDisabled() ) 474 { 475 registries.register( attributeType ); 476 } 477 else if ( schema.isEnabled() && attributeType.isEnabled() ) 478 { 479 registries.register( attributeType ); 480 } 481 } 482 else 483 { 484 if ( schema.isEnabled() && attributeType.isEnabled() ) 485 { 486 registries.register( attributeType ); 487 } 488 } 489 490 return attributeType; 491 } 492 493 494 /** 495 * Register the MatchingRuleUse contained in the given LdifEntry into the registries. 496 * 497 * @param registries The Registries 498 * @param entry The LdifEntry containing the MatchingRuleUse description 499 * @param schema The associated schema 500 * @return the created MatchingRuleUse instance 501 * @throws Exception If the registering failed 502 * 503 protected MatchingRuleUse registerMatchingRuleUse( Registries registries, LdifEntry entry, Schema schema) 504 throws Exception 505 { 506 throw new NotImplementedException( "Need to implement factory " + 507 "method for creating a MatchingRuleUse" ); 508 } 509 510 511 /** 512 * Register the NameForm contained in the given LdifEntry into the registries. 513 * 514 * @param registries The Registries 515 * @param entry The LdifEntry containing the NameForm description 516 * @param schema The associated schema 517 * @return the created NameForm instance 518 * @throws Exception If the registering failed 519 * 520 protected NameForm registerNameForm( Registries registries, LdifEntry entry, Schema schema) 521 throws Exception 522 { 523 throw new NotImplementedException( "Need to implement factory " + 524 "method for creating a NameForm" ); 525 } 526 527 528 /** 529 * Register the DitContentRule contained in the given LdifEntry into the registries. 530 * 531 * @param registries The Registries 532 * @param entry The LdifEntry containing the DitContentRule description 533 * @param schema The associated schema 534 * @return the created DitContentRule instance 535 * @throws Exception If the registering failed 536 * 537 protected DITContentRule registerDitContentRule( Registries registries, LdifEntry entry, Schema schema) 538 throws Exception 539 { 540 throw new NotImplementedException( "Need to implement factory " + 541 "method for creating a DitContentRule" ); 542 } 543 544 545 /** 546 * Register the DitStructureRule contained in the given LdifEntry into the registries. 547 * 548 * @param registries The Registries 549 * @param entry The LdifEntry containing the DitStructureRule description 550 * @param schema The associated schema 551 * @return the created DitStructureRule instance 552 * @throws Exception If the registering failed 553 * 554 protected DITStructureRule registerDitStructureRule( Registries registries, LdifEntry entry, Schema schema) 555 throws Exception 556 { 557 throw new NotImplementedException( "Need to implement factory " + 558 "method for creating a DitStructureRule" ); 559 } 560 561 562 /** 563 * Register the ObjectClass contained in the given LdifEntry into the registries. 564 * 565 * @param registries The Registries 566 * @param entry The LdifEntry containing the ObjectClass description 567 * @param schema The associated schema 568 * @return the created ObjectClass instance 569 * @throws Exception If the registering failed 570 * 571 protected ObjectClass registerObjectClass( Registries registries, LdifEntry entry, Schema schema) 572 throws Exception 573 { 574 return registerObjectClass( registries, entry.getEntry(), schema ); 575 } 576 577 578 /** 579 * Register the ObjectClass contained in the given LdifEntry into the registries. 580 * 581 * @param registries The Registries 582 * @param entry The Entry containing the ObjectClass description 583 * @param schema The associated schema 584 * @return the created ObjectClass instance 585 * @throws Exception If the registering failed 586 * 587 protected ObjectClass registerObjectClass( Registries registries, Entry entry, Schema schema) 588 throws Exception 589 { 590 ObjectClass objectClass = factory.getObjectClass( entry, registries, schema.getSchemaName() ); 591 592 if ( registries.isRelaxed() ) 593 { 594 if ( registries.acceptDisabled() ) 595 { 596 registries.register( objectClass ); 597 } 598 else if ( schema.isEnabled() && objectClass.isEnabled() ) 599 { 600 registries.register( objectClass ); 601 } 602 } 603 else 604 { 605 if ( schema.isEnabled() && objectClass.isEnabled() ) 606 { 607 registries.register( objectClass ); 608 } 609 } 610 611 return objectClass; 612 } 613 614 615 public EntityFactory getFactory() 616 { 617 return factory; 618 } 619 */ 620 621 public Object getDao() 622 { 623 return null; 624 } 625 626 627 private Schema[] buildSchemaArray( String... schemaNames ) throws Exception 628 { 629 Schema[] schemas = new Schema[schemaNames.length]; 630 int pos = 0; 631 632 for ( String schemaName : schemaNames ) 633 { 634 schemas[pos++] = getSchema( schemaName ); 635 } 636 637 return schemas; 638 } 639 640 641 /** 642 * {@inheritDoc} 643 */ 644 public List<Entry> loadAttributeTypes( String... schemaNames ) throws Exception 645 { 646 if ( schemaNames == null ) 647 { 648 return new ArrayList<Entry>(); 649 } 650 651 return loadAttributeTypes( buildSchemaArray( schemaNames ) ); 652 } 653 654 655 /** 656 * {@inheritDoc} 657 */ 658 public List<Entry> loadComparators( String... schemaNames ) throws Exception 659 { 660 if ( schemaNames == null ) 661 { 662 return new ArrayList<Entry>(); 663 } 664 665 return loadComparators( buildSchemaArray( schemaNames ) ); 666 } 667 668 669 /** 670 * {@inheritDoc} 671 */ 672 public List<Entry> loadDitContentRules( String... schemaNames ) throws Exception 673 { 674 if ( schemaNames == null ) 675 { 676 return new ArrayList<Entry>(); 677 } 678 679 return loadDitContentRules( buildSchemaArray( schemaNames ) ); 680 } 681 682 683 /** 684 * {@inheritDoc} 685 */ 686 public List<Entry> loadDitStructureRules( String... schemaNames ) throws Exception 687 { 688 if ( schemaNames == null ) 689 { 690 return new ArrayList<Entry>(); 691 } 692 693 return loadDitStructureRules( buildSchemaArray( schemaNames ) ); 694 } 695 696 697 /** 698 * {@inheritDoc} 699 */ 700 public List<Entry> loadMatchingRules( String... schemaNames ) throws Exception 701 { 702 if ( schemaNames == null ) 703 { 704 return new ArrayList<Entry>(); 705 } 706 707 return loadMatchingRules( buildSchemaArray( schemaNames ) ); 708 } 709 710 711 /** 712 * {@inheritDoc} 713 */ 714 public List<Entry> loadMatchingRuleUses( String... schemaNames ) throws Exception 715 { 716 if ( schemaNames == null ) 717 { 718 return new ArrayList<Entry>(); 719 } 720 721 return loadMatchingRuleUses( buildSchemaArray( schemaNames ) ); 722 } 723 724 725 /** 726 * {@inheritDoc} 727 */ 728 public List<Entry> loadNameForms( String... schemaNames ) throws Exception 729 { 730 if ( schemaNames == null ) 731 { 732 return new ArrayList<Entry>(); 733 } 734 735 return loadNameForms( buildSchemaArray( schemaNames ) ); 736 } 737 738 739 /** 740 * {@inheritDoc} 741 */ 742 public List<Entry> loadNormalizers( String... schemaNames ) throws Exception 743 { 744 if ( schemaNames == null ) 745 { 746 return new ArrayList<Entry>(); 747 } 748 749 return loadNormalizers( buildSchemaArray( schemaNames ) ); 750 } 751 752 753 /** 754 * {@inheritDoc} 755 */ 756 public List<Entry> loadObjectClasses( String... schemaNames ) throws Exception 757 { 758 if ( schemaNames == null ) 759 { 760 return new ArrayList<Entry>(); 761 } 762 763 return loadObjectClasses( buildSchemaArray( schemaNames ) ); 764 } 765 766 767 /** 768 * {@inheritDoc} 769 */ 770 public List<Entry> loadSyntaxes( String... schemaNames ) throws Exception 771 { 772 if ( schemaNames == null ) 773 { 774 return new ArrayList<Entry>(); 775 } 776 777 return loadSyntaxes( buildSchemaArray( schemaNames ) ); 778 } 779 780 781 /** 782 * {@inheritDoc} 783 */ 784 public List<Entry> loadSyntaxCheckers( String... schemaNames ) throws Exception 785 { 786 if ( schemaNames == null ) 787 { 788 return new ArrayList<Entry>(); 789 } 790 791 return loadSyntaxCheckers( buildSchemaArray( schemaNames ) ); 792 } 793 }