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.schemaloader; 021 022 023import java.io.File; 024import java.io.IOException; 025import java.io.InputStream; 026import java.net.URL; 027import java.util.ArrayList; 028import java.util.List; 029import java.util.Map; 030import java.util.regex.Pattern; 031 032import org.apache.directory.api.i18n.I18n; 033import org.apache.directory.api.ldap.model.constants.SchemaConstants; 034import org.apache.directory.api.ldap.model.entry.Entry; 035import org.apache.directory.api.ldap.model.exception.LdapException; 036import org.apache.directory.api.ldap.model.ldif.LdifEntry; 037import org.apache.directory.api.ldap.model.ldif.LdifReader; 038import org.apache.directory.api.ldap.model.schema.registries.AbstractSchemaLoader; 039import org.apache.directory.api.ldap.model.schema.registries.Schema; 040import org.apache.directory.api.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor; 041import org.apache.directory.api.ldap.schemaextractor.impl.ResourceMap; 042import org.apache.directory.api.util.Strings; 043import org.slf4j.Logger; 044import org.slf4j.LoggerFactory; 045 046 047/** 048 * Loads schema data from LDIF files containing entries representing schema 049 * objects, using the meta schema format. 050 * 051 * This class is used only for tests. 052 * 053 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 054 */ 055public class JarLdifSchemaLoader extends AbstractSchemaLoader 056{ 057 /** 058 * Filesystem path separator pattern, either forward slash or backslash. 059 * java.util.regex.Pattern is immutable so only one instance is needed for all uses. 060 */ 061 private static final String SEPARATOR_PATTERN = "[/\\Q\\\\E]"; 062 063 /** ldif file extension used */ 064 private static final String LDIF_EXT = "ldif"; 065 066 /** static class logger */ 067 private static final Logger LOG = LoggerFactory.getLogger( JarLdifSchemaLoader.class ); 068 069 /** Speedup for DEBUG mode */ 070 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 071 072 /** a map of all the resources in this jar */ 073 private static final Map<String, Boolean> RESOURCE_MAP = ResourceMap.getResources( Pattern 074 .compile( "schema" + SEPARATOR_PATTERN + "ou=schema.*" ) ); 075 076 077 /** 078 * Creates a new LDIF based SchemaLoader. The constructor checks to make 079 * sure the supplied base directory exists and contains a schema.ldif file 080 * and if not complains about it. 081 * 082 * @throws Exception if the base directory does not exist or does not 083 * a valid schema.ldif file 084 */ 085 public JarLdifSchemaLoader() throws Exception 086 { 087 initializeSchemas(); 088 } 089 090 091 private URL getResource( String resource, String msg ) throws IOException 092 { 093 if ( RESOURCE_MAP.get( resource ) ) 094 { 095 return DefaultSchemaLdifExtractor.getUniqueResource( resource, msg ); 096 } 097 else 098 { 099 return new File( resource ).toURI().toURL(); 100 } 101 } 102 103 104 /** 105 * Scans for LDIF files just describing the various schema contained in 106 * the schema repository. 107 * 108 * @throws Exception 109 */ 110 private void initializeSchemas() throws Exception 111 { 112 if ( IS_DEBUG ) 113 { 114 LOG.debug( "Initializing schema" ); 115 } 116 117 Pattern pat = Pattern.compile( "schema" + SEPARATOR_PATTERN + "ou=schema" 118 + SEPARATOR_PATTERN + "cn=[a-z0-9-_]*\\." + LDIF_EXT ); 119 120 for ( String file : RESOURCE_MAP.keySet() ) 121 { 122 if ( pat.matcher( file ).matches() ) 123 { 124 URL resource = getResource( file, "schema LDIF file" ); 125 InputStream in = resource.openStream(); 126 127 try 128 { 129 LdifReader reader = new LdifReader( in ); 130 LdifEntry entry = reader.next(); 131 reader.close(); 132 Schema schema = getSchema( entry.getEntry() ); 133 schemaMap.put( schema.getSchemaName(), schema ); 134 135 if ( IS_DEBUG ) 136 { 137 LOG.debug( "Schema Initialized ... \n{}", schema ); 138 } 139 } 140 catch ( Exception e ) 141 { 142 LOG.error( I18n.err( I18n.ERR_10003, file ), e ); 143 throw e; 144 } 145 finally 146 { 147 in.close(); 148 } 149 } 150 } 151 } 152 153 154 /** 155 * Utility method to get a regex.Pattern fragment for the path for a schema directory. 156 * 157 * @param schema the schema to get the path for 158 * @return the regex.Pattern fragment for the path for the specified schema directory 159 */ 160 private String getSchemaDirectoryString( Schema schema ) 161 { 162 return "schema" + "/" + "ou=schema" + "/" 163 + "cn=" + Strings.lowerCase( schema.getSchemaName() ) + "/"; 164 } 165 166 167 /** 168 * {@inheritDoc} 169 */ 170 public List<Entry> loadComparators( Schema... schemas ) throws LdapException, IOException 171 { 172 List<Entry> comparatorList = new ArrayList<Entry>(); 173 174 if ( schemas == null ) 175 { 176 return comparatorList; 177 } 178 179 for ( Schema schema : schemas ) 180 { 181 String start = getSchemaDirectoryString( schema ) 182 + SchemaConstants.COMPARATORS_PATH + "/" + "m-oid="; 183 String end = "." + LDIF_EXT; 184 185 for ( String resourcePath : RESOURCE_MAP.keySet() ) 186 { 187 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 188 { 189 URL resource = getResource( resourcePath, "comparator LDIF file" ); 190 LdifReader reader = new LdifReader( resource.openStream() ); 191 LdifEntry entry = reader.next(); 192 reader.close(); 193 194 comparatorList.add( entry.getEntry() ); 195 } 196 } 197 } 198 199 return comparatorList; 200 } 201 202 203 /** 204 * {@inheritDoc} 205 */ 206 public List<Entry> loadSyntaxCheckers( Schema... schemas ) throws LdapException, IOException 207 { 208 List<Entry> syntaxCheckerList = new ArrayList<Entry>(); 209 210 if ( schemas == null ) 211 { 212 return syntaxCheckerList; 213 } 214 215 for ( Schema schema : schemas ) 216 { 217 String start = getSchemaDirectoryString( schema ) 218 + SchemaConstants.SYNTAX_CHECKERS_PATH + "/" + "m-oid="; 219 String end = "." + LDIF_EXT; 220 221 for ( String resourcePath : RESOURCE_MAP.keySet() ) 222 { 223 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 224 { 225 URL resource = getResource( resourcePath, "syntaxChecker LDIF file" ); 226 LdifReader reader = new LdifReader( resource.openStream() ); 227 LdifEntry entry = reader.next(); 228 reader.close(); 229 230 syntaxCheckerList.add( entry.getEntry() ); 231 } 232 } 233 } 234 235 return syntaxCheckerList; 236 } 237 238 239 /** 240 * {@inheritDoc} 241 */ 242 public List<Entry> loadNormalizers( Schema... schemas ) throws LdapException, IOException 243 { 244 List<Entry> normalizerList = new ArrayList<Entry>(); 245 246 if ( schemas == null ) 247 { 248 return normalizerList; 249 } 250 251 for ( Schema schema : schemas ) 252 { 253 String start = getSchemaDirectoryString( schema ) 254 + SchemaConstants.NORMALIZERS_PATH + "/" + "m-oid="; 255 String end = "." + LDIF_EXT; 256 257 for ( String resourcePath : RESOURCE_MAP.keySet() ) 258 { 259 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 260 { 261 URL resource = getResource( resourcePath, "normalizer LDIF file" ); 262 LdifReader reader = new LdifReader( resource.openStream() ); 263 LdifEntry entry = reader.next(); 264 reader.close(); 265 266 normalizerList.add( entry.getEntry() ); 267 } 268 } 269 } 270 271 return normalizerList; 272 } 273 274 275 /** 276 * {@inheritDoc} 277 */ 278 public List<Entry> loadMatchingRules( Schema... schemas ) throws LdapException, IOException 279 { 280 List<Entry> matchingRuleList = new ArrayList<Entry>(); 281 282 if ( schemas == null ) 283 { 284 return matchingRuleList; 285 } 286 287 for ( Schema schema : schemas ) 288 { 289 String start = getSchemaDirectoryString( schema ) 290 + SchemaConstants.MATCHING_RULES_PATH + "/" + "m-oid="; 291 String end = "." + LDIF_EXT; 292 293 for ( String resourcePath : RESOURCE_MAP.keySet() ) 294 { 295 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 296 { 297 URL resource = getResource( resourcePath, "matchingRules LDIF file" ); 298 LdifReader reader = new LdifReader( resource.openStream() ); 299 LdifEntry entry = reader.next(); 300 reader.close(); 301 302 matchingRuleList.add( entry.getEntry() ); 303 } 304 } 305 } 306 307 return matchingRuleList; 308 } 309 310 311 /** 312 * {@inheritDoc} 313 */ 314 public List<Entry> loadSyntaxes( Schema... schemas ) throws LdapException, IOException 315 { 316 List<Entry> syntaxList = new ArrayList<Entry>(); 317 318 if ( schemas == null ) 319 { 320 return syntaxList; 321 } 322 323 for ( Schema schema : schemas ) 324 { 325 String start = getSchemaDirectoryString( schema ) 326 + SchemaConstants.SYNTAXES_PATH + "/" + "m-oid="; 327 String end = "." + LDIF_EXT; 328 329 for ( String resourcePath : RESOURCE_MAP.keySet() ) 330 { 331 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 332 { 333 URL resource = getResource( resourcePath, "syntax LDIF file" ); 334 LdifReader reader = new LdifReader( resource.openStream() ); 335 LdifEntry entry = reader.next(); 336 reader.close(); 337 338 syntaxList.add( entry.getEntry() ); 339 } 340 } 341 } 342 343 return syntaxList; 344 } 345 346 347 /** 348 * {@inheritDoc} 349 */ 350 public List<Entry> loadAttributeTypes( Schema... schemas ) throws LdapException, IOException 351 { 352 List<Entry> attributeTypeList = new ArrayList<Entry>(); 353 354 if ( schemas == null ) 355 { 356 return attributeTypeList; 357 } 358 359 for ( Schema schema : schemas ) 360 { 361 // check that the attributeTypes directory exists for the schema 362 String start = getSchemaDirectoryString( schema ) 363 + SchemaConstants.ATTRIBUTE_TYPES_PATH + "/" + "m-oid="; 364 String end = "." + LDIF_EXT; 365 366 // get list of attributeType LDIF schema files in attributeTypes 367 for ( String resourcePath : RESOURCE_MAP.keySet() ) 368 { 369 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 370 { 371 URL resource = getResource( resourcePath, "attributeType LDIF file" ); 372 LdifReader reader = new LdifReader( resource.openStream() ); 373 LdifEntry entry = reader.next(); 374 reader.close(); 375 376 attributeTypeList.add( entry.getEntry() ); 377 } 378 } 379 } 380 381 return attributeTypeList; 382 } 383 384 385 /** 386 * {@inheritDoc} 387 */ 388 public List<Entry> loadMatchingRuleUses( Schema... schemas ) throws LdapException, IOException 389 { 390 List<Entry> matchingRuleUseList = new ArrayList<Entry>(); 391 392 if ( schemas == null ) 393 { 394 return matchingRuleUseList; 395 } 396 397 for ( Schema schema : schemas ) 398 { 399 String start = getSchemaDirectoryString( schema ) 400 + SchemaConstants.MATCHING_RULE_USE_PATH + "/" + "m-oid="; 401 String end = "." + LDIF_EXT; 402 403 for ( String resourcePath : RESOURCE_MAP.keySet() ) 404 { 405 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 406 { 407 URL resource = getResource( resourcePath, "matchingRuleUse LDIF file" ); 408 LdifReader reader = new LdifReader( resource.openStream() ); 409 LdifEntry entry = reader.next(); 410 reader.close(); 411 412 matchingRuleUseList.add( entry.getEntry() ); 413 } 414 } 415 } 416 417 return matchingRuleUseList; 418 } 419 420 421 /** 422 * {@inheritDoc} 423 */ 424 public List<Entry> loadNameForms( Schema... schemas ) throws LdapException, IOException 425 { 426 List<Entry> nameFormList = new ArrayList<Entry>(); 427 428 if ( schemas == null ) 429 { 430 return nameFormList; 431 } 432 433 for ( Schema schema : schemas ) 434 { 435 String start = getSchemaDirectoryString( schema ) 436 + SchemaConstants.NAME_FORMS_PATH + "/" + "m-oid="; 437 String end = "." + LDIF_EXT; 438 439 for ( String resourcePath : RESOURCE_MAP.keySet() ) 440 { 441 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 442 { 443 URL resource = getResource( resourcePath, "nameForm LDIF file" ); 444 LdifReader reader = new LdifReader( resource.openStream() ); 445 LdifEntry entry = reader.next(); 446 reader.close(); 447 448 nameFormList.add( entry.getEntry() ); 449 } 450 } 451 } 452 453 return nameFormList; 454 } 455 456 457 /** 458 * {@inheritDoc} 459 */ 460 public List<Entry> loadDitContentRules( Schema... schemas ) throws LdapException, IOException 461 { 462 List<Entry> ditContentRulesList = new ArrayList<Entry>(); 463 464 if ( schemas == null ) 465 { 466 return ditContentRulesList; 467 } 468 469 for ( Schema schema : schemas ) 470 { 471 String start = getSchemaDirectoryString( schema ) 472 + SchemaConstants.DIT_CONTENT_RULES_PATH + "/" + "m-oid="; 473 String end = "." + LDIF_EXT; 474 475 for ( String resourcePath : RESOURCE_MAP.keySet() ) 476 { 477 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 478 { 479 URL resource = getResource( resourcePath, "ditContentRule LDIF file" ); 480 LdifReader reader = new LdifReader( resource.openStream() ); 481 LdifEntry entry = reader.next(); 482 reader.close(); 483 484 ditContentRulesList.add( entry.getEntry() ); 485 } 486 } 487 } 488 489 return ditContentRulesList; 490 } 491 492 493 /** 494 * {@inheritDoc} 495 */ 496 public List<Entry> loadDitStructureRules( Schema... schemas ) throws LdapException, IOException 497 { 498 List<Entry> ditStructureRuleList = new ArrayList<Entry>(); 499 500 if ( schemas == null ) 501 { 502 return ditStructureRuleList; 503 } 504 505 for ( Schema schema : schemas ) 506 { 507 String start = getSchemaDirectoryString( schema ) 508 + SchemaConstants.DIT_STRUCTURE_RULES_PATH + "/" + "m-oid="; 509 String end = "." + LDIF_EXT; 510 511 for ( String resourcePath : RESOURCE_MAP.keySet() ) 512 { 513 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 514 { 515 URL resource = getResource( resourcePath, "ditStructureRule LDIF file" ); 516 LdifReader reader = new LdifReader( resource.openStream() ); 517 LdifEntry entry = reader.next(); 518 reader.close(); 519 520 ditStructureRuleList.add( entry.getEntry() ); 521 } 522 } 523 } 524 525 return ditStructureRuleList; 526 } 527 528 529 /** 530 * {@inheritDoc} 531 */ 532 public List<Entry> loadObjectClasses( Schema... schemas ) throws LdapException, IOException 533 { 534 List<Entry> objectClassList = new ArrayList<Entry>(); 535 536 if ( schemas == null ) 537 { 538 return objectClassList; 539 } 540 541 for ( Schema schema : schemas ) 542 { 543 // get objectClasses directory, check if exists, return if not 544 String start = getSchemaDirectoryString( schema ) 545 + SchemaConstants.OBJECT_CLASSES_PATH + "/" + "m-oid="; 546 String end = "." + LDIF_EXT; 547 548 for ( String resourcePath : RESOURCE_MAP.keySet() ) 549 { 550 if ( resourcePath.startsWith( start ) && resourcePath.endsWith( end ) ) 551 { 552 URL resource = getResource( resourcePath, "objectClass LDIF file" ); 553 LdifReader reader = new LdifReader( resource.openStream() ); 554 LdifEntry entry = reader.next(); 555 reader.close(); 556 557 objectClassList.add( entry.getEntry() ); 558 } 559 } 560 } 561 562 return objectClassList; 563 } 564}