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