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.schema.loader; 021 022 023import java.io.File; 024import java.io.FileNotFoundException; 025import java.io.FilenameFilter; 026import java.io.IOException; 027import java.util.ArrayList; 028import java.util.List; 029 030import org.apache.directory.api.i18n.I18n; 031import org.apache.directory.api.ldap.model.constants.SchemaConstants; 032import org.apache.directory.api.ldap.model.entry.Entry; 033import org.apache.directory.api.ldap.model.exception.LdapException; 034import org.apache.directory.api.ldap.model.ldif.LdifEntry; 035import org.apache.directory.api.ldap.model.ldif.LdifReader; 036import org.apache.directory.api.ldap.model.schema.registries.AbstractSchemaLoader; 037import org.apache.directory.api.ldap.model.schema.registries.Schema; 038import org.apache.directory.api.util.Strings; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042 043/** 044 * Loads schema data from LDIF files containing entries representing schema 045 * objects, using the meta schema format. 046 * 047 * This class is used only for tests. 048 * 049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 050 */ 051public class LdifSchemaLoader extends AbstractSchemaLoader 052{ 053 /** ldif file extension used */ 054 private static final String LDIF_EXT = "ldif"; 055 056 /** ou=schema LDIF file name */ 057 private static final String OU_SCHEMA_LDIF = "ou=schema." + LDIF_EXT; 058 059 /** static class logger */ 060 private static final Logger LOG = LoggerFactory.getLogger( LdifSchemaLoader.class ); 061 062 /** Speedup for DEBUG mode */ 063 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 064 065 /** directory containing the schema LDIF file for ou=schema */ 066 private final File baseDirectory; 067 068 /** a filter for listing all the LDIF files within a directory */ 069 private final FilenameFilter ldifFilter = new FilenameFilter() 070 { 071 @Override 072 public boolean accept( File file, String name ) 073 { 074 return name.endsWith( LDIF_EXT ); 075 } 076 }; 077 078 079 /** 080 * Creates a new LDIF based SchemaLoader. The constructor checks to make 081 * sure the supplied base directory exists and contains a schema.ldif file 082 * and if not complains about it. 083 * 084 * @param baseDirectory the schema LDIF base directory 085 * @throws LdapException if the base directory does not exist or does not 086 * a valid schema.ldif file 087 * @throws IOException If we can't load the schema 088 */ 089 public LdifSchemaLoader( File baseDirectory ) throws LdapException, IOException 090 { 091 this.baseDirectory = baseDirectory; 092 093 if ( !baseDirectory.exists() ) 094 { 095 String msg = "Provided baseDirectory '" + baseDirectory.getAbsolutePath() + "' does not exist."; 096 LOG.error( msg ); 097 throw new IllegalArgumentException( msg ); 098 } 099 100 File schemaLdif = new File( baseDirectory, OU_SCHEMA_LDIF ); 101 102 if ( !schemaLdif.exists() ) 103 { 104 String msg = I18n.err( I18n.ERR_10004, schemaLdif.getAbsolutePath() ); 105 LOG.error( msg ); 106 throw new FileNotFoundException( msg ); 107 } 108 109 if ( IS_DEBUG ) 110 { 111 LOG.debug( "Using '{}' as the base schema load directory.", baseDirectory ); 112 } 113 114 initializeSchemas(); 115 } 116 117 118 /** 119 * Scans for LDIF files just describing the various schema contained in 120 * the schema repository. 121 * 122 * @throws LdapException 123 */ 124 private void initializeSchemas() throws LdapException, IOException 125 { 126 if ( IS_DEBUG ) 127 { 128 LOG.debug( "Initializing schema" ); 129 } 130 131 File schemaDirectory = new File( baseDirectory, SchemaConstants.OU_SCHEMA ); 132 String[] ldifFiles = schemaDirectory.list( ldifFilter ); 133 134 if ( ldifFiles != null ) 135 { 136 for ( String ldifFile : ldifFiles ) 137 { 138 File file = new File( schemaDirectory, ldifFile ); 139 140 try ( LdifReader reader = new LdifReader( file ) ) 141 { 142 LdifEntry entry = reader.next(); 143 Schema schema = getSchema( entry.getEntry() ); 144 145 if ( schema == null ) 146 { 147 // The entry was not a schema, skip it 148 continue; 149 } 150 151 schemaMap.put( schema.getSchemaName(), schema ); 152 153 if ( IS_DEBUG ) 154 { 155 LOG.debug( "Schema Initialized ... \n{}", schema ); 156 } 157 } 158 catch ( LdapException e ) 159 { 160 LOG.error( I18n.err( I18n.ERR_10003, ldifFile ), e ); 161 throw e; 162 } 163 } 164 } 165 } 166 167 168 /** 169 * Utility method to get the file for a schema directory. 170 * 171 * @param schema the schema to get the file for 172 * @return the file for the specific schema directory 173 */ 174 private File getSchemaDirectory( Schema schema ) 175 { 176 return new File( new File( baseDirectory, SchemaConstants.OU_SCHEMA ), "cn=" 177 + Strings.lowerCase( schema.getSchemaName() ) ); 178 } 179 180 181 /** 182 * {@inheritDoc} 183 */ 184 @Override 185 public List<Entry> loadComparators( Schema... schemas ) throws LdapException, IOException 186 { 187 List<Entry> comparatorList = new ArrayList<>(); 188 189 if ( schemas == null ) 190 { 191 return comparatorList; 192 } 193 194 for ( Schema schema : schemas ) 195 { 196 File comparatorsDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.COMPARATORS_PATH ); 197 198 if ( !comparatorsDirectory.exists() ) 199 { 200 return comparatorList; 201 } 202 203 File[] comparators = comparatorsDirectory.listFiles( ldifFilter ); 204 205 if ( comparators != null ) 206 { 207 for ( File ldifFile : comparators ) 208 { 209 LdifReader reader = new LdifReader( ldifFile ); 210 LdifEntry entry = reader.next(); 211 reader.close(); 212 213 comparatorList.add( entry.getEntry() ); 214 } 215 } 216 } 217 218 return comparatorList; 219 } 220 221 222 /** 223 * {@inheritDoc} 224 */ 225 @Override 226 public List<Entry> loadSyntaxCheckers( Schema... schemas ) throws LdapException, IOException 227 { 228 List<Entry> syntaxCheckerList = new ArrayList<>(); 229 230 if ( schemas == null ) 231 { 232 return syntaxCheckerList; 233 } 234 235 for ( Schema schema : schemas ) 236 { 237 File syntaxCheckersDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.SYNTAX_CHECKERS_PATH ); 238 239 if ( !syntaxCheckersDirectory.exists() ) 240 { 241 return syntaxCheckerList; 242 } 243 244 File[] syntaxCheckerFiles = syntaxCheckersDirectory.listFiles( ldifFilter ); 245 246 if ( syntaxCheckerFiles != null ) 247 { 248 for ( File ldifFile : syntaxCheckerFiles ) 249 { 250 LdifReader reader = new LdifReader( ldifFile ); 251 LdifEntry entry = reader.next(); 252 reader.close(); 253 254 syntaxCheckerList.add( entry.getEntry() ); 255 } 256 } 257 } 258 259 return syntaxCheckerList; 260 } 261 262 263 /** 264 * {@inheritDoc} 265 */ 266 @Override 267 public List<Entry> loadNormalizers( Schema... schemas ) throws LdapException, IOException 268 { 269 List<Entry> normalizerList = new ArrayList<>(); 270 271 if ( schemas == null ) 272 { 273 return normalizerList; 274 } 275 276 for ( Schema schema : schemas ) 277 { 278 File normalizersDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.NORMALIZERS_PATH ); 279 280 if ( !normalizersDirectory.exists() ) 281 { 282 return normalizerList; 283 } 284 285 File[] normalizerFiles = normalizersDirectory.listFiles( ldifFilter ); 286 287 if ( normalizerFiles != null ) 288 { 289 for ( File ldifFile : normalizerFiles ) 290 { 291 LdifReader reader = new LdifReader( ldifFile ); 292 LdifEntry entry = reader.next(); 293 reader.close(); 294 295 normalizerList.add( entry.getEntry() ); 296 } 297 } 298 } 299 300 return normalizerList; 301 } 302 303 304 /** 305 * {@inheritDoc} 306 */ 307 @Override 308 public List<Entry> loadMatchingRules( Schema... schemas ) throws LdapException, IOException 309 { 310 List<Entry> matchingRuleList = new ArrayList<>(); 311 312 if ( schemas == null ) 313 { 314 return matchingRuleList; 315 } 316 317 for ( Schema schema : schemas ) 318 { 319 File matchingRulesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.MATCHING_RULES_PATH ); 320 321 if ( !matchingRulesDirectory.exists() ) 322 { 323 return matchingRuleList; 324 } 325 326 File[] matchingRuleFiles = matchingRulesDirectory.listFiles( ldifFilter ); 327 328 if ( matchingRuleFiles != null ) 329 { 330 for ( File ldifFile : matchingRuleFiles ) 331 { 332 LdifReader reader = new LdifReader( ldifFile ); 333 LdifEntry entry = reader.next(); 334 reader.close(); 335 336 matchingRuleList.add( entry.getEntry() ); 337 } 338 } 339 } 340 341 return matchingRuleList; 342 } 343 344 345 /** 346 * {@inheritDoc} 347 */ 348 @Override 349 public List<Entry> loadSyntaxes( Schema... schemas ) throws LdapException, IOException 350 { 351 List<Entry> syntaxList = new ArrayList<>(); 352 353 if ( schemas == null ) 354 { 355 return syntaxList; 356 } 357 358 for ( Schema schema : schemas ) 359 { 360 File syntaxesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.SYNTAXES_PATH ); 361 362 if ( !syntaxesDirectory.exists() ) 363 { 364 return syntaxList; 365 } 366 367 File[] syntaxFiles = syntaxesDirectory.listFiles( ldifFilter ); 368 369 if ( syntaxFiles != null ) 370 { 371 for ( File ldifFile : syntaxFiles ) 372 { 373 LdifReader reader = new LdifReader( ldifFile ); 374 LdifEntry entry = reader.next(); 375 reader.close(); 376 377 syntaxList.add( entry.getEntry() ); 378 } 379 } 380 } 381 382 return syntaxList; 383 } 384 385 386 /** 387 * {@inheritDoc} 388 */ 389 @Override 390 public List<Entry> loadAttributeTypes( Schema... schemas ) throws LdapException, IOException 391 { 392 List<Entry> attributeTypeList = new ArrayList<>(); 393 394 if ( schemas == null ) 395 { 396 return attributeTypeList; 397 } 398 399 for ( Schema schema : schemas ) 400 { 401 // check that the attributeTypes directory exists for the schema 402 File attributeTypesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.ATTRIBUTE_TYPES_PATH ); 403 404 if ( !attributeTypesDirectory.exists() ) 405 { 406 return attributeTypeList; 407 } 408 409 // get list of attributeType LDIF schema files in attributeTypes 410 File[] attributeTypeFiles = attributeTypesDirectory.listFiles( ldifFilter ); 411 412 if ( attributeTypeFiles != null ) 413 { 414 for ( File ldifFile : attributeTypeFiles ) 415 { 416 LdifReader reader = new LdifReader( ldifFile ); 417 LdifEntry entry = reader.next(); 418 reader.close(); 419 420 attributeTypeList.add( entry.getEntry() ); 421 } 422 } 423 } 424 425 return attributeTypeList; 426 } 427 428 429 /** 430 * {@inheritDoc} 431 */ 432 @Override 433 public List<Entry> loadMatchingRuleUses( Schema... schemas ) throws LdapException, IOException 434 { 435 List<Entry> matchingRuleUseList = new ArrayList<>(); 436 437 if ( schemas == null ) 438 { 439 return matchingRuleUseList; 440 } 441 442 for ( Schema schema : schemas ) 443 { 444 File matchingRuleUsesDirectory = new File( getSchemaDirectory( schema ), 445 SchemaConstants.MATCHING_RULE_USE_PATH ); 446 447 if ( !matchingRuleUsesDirectory.exists() ) 448 { 449 return matchingRuleUseList; 450 } 451 452 File[] matchingRuleUseFiles = matchingRuleUsesDirectory.listFiles( ldifFilter ); 453 454 if ( matchingRuleUseFiles != null ) 455 { 456 for ( File ldifFile : matchingRuleUseFiles ) 457 { 458 LdifReader reader = new LdifReader( ldifFile ); 459 LdifEntry entry = reader.next(); 460 reader.close(); 461 462 matchingRuleUseList.add( entry.getEntry() ); 463 } 464 } 465 } 466 467 return matchingRuleUseList; 468 } 469 470 471 /** 472 * {@inheritDoc} 473 */ 474 @Override 475 public List<Entry> loadNameForms( Schema... schemas ) throws LdapException, IOException 476 { 477 List<Entry> nameFormList = new ArrayList<>(); 478 479 if ( schemas == null ) 480 { 481 return nameFormList; 482 } 483 484 for ( Schema schema : schemas ) 485 { 486 File nameFormsDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.NAME_FORMS_PATH ); 487 488 if ( !nameFormsDirectory.exists() ) 489 { 490 return nameFormList; 491 } 492 493 File[] nameFormFiles = nameFormsDirectory.listFiles( ldifFilter ); 494 495 if ( nameFormFiles != null ) 496 { 497 for ( File ldifFile : nameFormFiles ) 498 { 499 LdifReader reader = new LdifReader( ldifFile ); 500 LdifEntry entry = reader.next(); 501 reader.close(); 502 503 nameFormList.add( entry.getEntry() ); 504 } 505 } 506 } 507 508 return nameFormList; 509 } 510 511 512 /** 513 * {@inheritDoc} 514 */ 515 @Override 516 public List<Entry> loadDitContentRules( Schema... schemas ) throws LdapException, IOException 517 { 518 List<Entry> ditContentRuleList = new ArrayList<>(); 519 520 if ( schemas == null ) 521 { 522 return ditContentRuleList; 523 } 524 525 for ( Schema schema : schemas ) 526 { 527 File ditContentRulesDirectory = new File( getSchemaDirectory( schema ), 528 SchemaConstants.DIT_CONTENT_RULES_PATH ); 529 530 if ( !ditContentRulesDirectory.exists() ) 531 { 532 return ditContentRuleList; 533 } 534 535 File[] ditContentRuleFiles = ditContentRulesDirectory.listFiles( ldifFilter ); 536 537 if ( ditContentRuleFiles != null ) 538 { 539 for ( File ldifFile : ditContentRuleFiles ) 540 { 541 LdifReader reader = new LdifReader( ldifFile ); 542 LdifEntry entry = reader.next(); 543 reader.close(); 544 545 ditContentRuleList.add( entry.getEntry() ); 546 } 547 } 548 } 549 550 return ditContentRuleList; 551 } 552 553 554 /** 555 * {@inheritDoc} 556 */ 557 @Override 558 public List<Entry> loadDitStructureRules( Schema... schemas ) throws LdapException, IOException 559 { 560 List<Entry> ditStructureRuleList = new ArrayList<>(); 561 562 if ( schemas == null ) 563 { 564 return ditStructureRuleList; 565 } 566 567 for ( Schema schema : schemas ) 568 { 569 File ditStructureRulesDirectory = new File( getSchemaDirectory( schema ), 570 SchemaConstants.DIT_STRUCTURE_RULES_PATH ); 571 572 if ( !ditStructureRulesDirectory.exists() ) 573 { 574 return ditStructureRuleList; 575 } 576 577 File[] ditStructureRuleFiles = ditStructureRulesDirectory.listFiles( ldifFilter ); 578 579 if ( ditStructureRuleFiles != null ) 580 { 581 for ( File ldifFile : ditStructureRuleFiles ) 582 { 583 LdifReader reader = new LdifReader( ldifFile ); 584 LdifEntry entry = reader.next(); 585 reader.close(); 586 587 ditStructureRuleList.add( entry.getEntry() ); 588 } 589 } 590 } 591 592 return ditStructureRuleList; 593 } 594 595 596 /** 597 * {@inheritDoc} 598 */ 599 @Override 600 public List<Entry> loadObjectClasses( Schema... schemas ) throws LdapException, IOException 601 { 602 List<Entry> objectClassList = new ArrayList<>(); 603 604 if ( schemas == null ) 605 { 606 return objectClassList; 607 } 608 609 for ( Schema schema : schemas ) 610 { 611 // get objectClasses directory, check if exists, return if not 612 File objectClassesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.OBJECT_CLASSES_PATH ); 613 614 if ( !objectClassesDirectory.exists() ) 615 { 616 return objectClassList; 617 } 618 619 // get list of objectClass LDIF files from directory and load 620 File[] objectClassFiles = objectClassesDirectory.listFiles( ldifFilter ); 621 622 if ( objectClassFiles != null ) 623 { 624 for ( File ldifFile : objectClassFiles ) 625 { 626 LdifReader reader = new LdifReader( ldifFile ); 627 LdifEntry entry = reader.next(); 628 reader.close(); 629 630 objectClassList.add( entry.getEntry() ); 631 } 632 } 633 } 634 635 return objectClassList; 636 } 637}