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.text.ParseException; 024 import java.util.ArrayList; 025 import java.util.List; 026 027 import org.apache.directory.server.i18n.I18n; 028 import org.apache.directory.shared.ldap.constants.MetaSchemaConstants; 029 import org.apache.directory.shared.ldap.constants.SchemaConstants; 030 import org.apache.directory.shared.ldap.entry.EntryAttribute; 031 import org.apache.directory.shared.ldap.entry.Value; 032 import org.apache.directory.shared.ldap.exception.LdapException; 033 import org.apache.directory.shared.ldap.exception.LdapInvalidAttributeValueException; 034 import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException; 035 import org.apache.directory.shared.ldap.message.ResultCodeEnum; 036 import org.apache.directory.shared.ldap.schema.AttributeType; 037 import org.apache.directory.shared.ldap.schema.DITContentRule; 038 import org.apache.directory.shared.ldap.schema.DITStructureRule; 039 import org.apache.directory.shared.ldap.schema.LdapSyntax; 040 import org.apache.directory.shared.ldap.schema.MatchingRule; 041 import org.apache.directory.shared.ldap.schema.MatchingRuleUse; 042 import org.apache.directory.shared.ldap.schema.NameForm; 043 import org.apache.directory.shared.ldap.schema.ObjectClass; 044 import org.apache.directory.shared.ldap.schema.SchemaManager; 045 import org.apache.directory.shared.ldap.schema.parsers.AttributeTypeDescriptionSchemaParser; 046 import org.apache.directory.shared.ldap.schema.parsers.DITContentRuleDescriptionSchemaParser; 047 import org.apache.directory.shared.ldap.schema.parsers.DITStructureRuleDescriptionSchemaParser; 048 import org.apache.directory.shared.ldap.schema.parsers.LdapComparatorDescription; 049 import org.apache.directory.shared.ldap.schema.parsers.LdapComparatorDescriptionSchemaParser; 050 import org.apache.directory.shared.ldap.schema.parsers.LdapSyntaxDescriptionSchemaParser; 051 import org.apache.directory.shared.ldap.schema.parsers.MatchingRuleDescriptionSchemaParser; 052 import org.apache.directory.shared.ldap.schema.parsers.MatchingRuleUseDescriptionSchemaParser; 053 import org.apache.directory.shared.ldap.schema.parsers.NameFormDescriptionSchemaParser; 054 import org.apache.directory.shared.ldap.schema.parsers.NormalizerDescription; 055 import org.apache.directory.shared.ldap.schema.parsers.NormalizerDescriptionSchemaParser; 056 import org.apache.directory.shared.ldap.schema.parsers.ObjectClassDescriptionSchemaParser; 057 import org.apache.directory.shared.ldap.schema.parsers.SyntaxCheckerDescription; 058 import org.apache.directory.shared.ldap.schema.parsers.SyntaxCheckerDescriptionSchemaParser; 059 060 061 /** 062 * Parses descriptions using a number of different parsers for schema descriptions. 063 * Also checks to make sure some things are valid as it's parsing paramters of 064 * certain entity types. 065 * 066 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 067 * @version $Rev$ 068 */ 069 public class DescriptionParsers 070 { 071 /** Empty arrays of SchemaOjects */ 072 private static final LdapComparatorDescription[] EMPTY_COMPARATORS = new LdapComparatorDescription[0]; 073 private static final NormalizerDescription[] EMPTY_NORMALIZERS = new NormalizerDescription[0]; 074 private static final SyntaxCheckerDescription[] EMPTY_SYNTAX_CHECKERS = new SyntaxCheckerDescription[0]; 075 private static final LdapSyntax[] EMPTY_SYNTAXES = new LdapSyntax[0]; 076 private static final MatchingRule[] EMPTY_MATCHING_RULES = new MatchingRule[0]; 077 private static final AttributeType[] EMPTY_ATTRIBUTE_TYPES = new AttributeType[0]; 078 private static final ObjectClass[] EMPTY_OBJECT_CLASSES = new ObjectClass[0]; 079 private static final MatchingRuleUse[] EMPTY_MATCHING_RULE_USES = new MatchingRuleUse[0]; 080 private static final DITStructureRule[] EMPTY_DIT_STRUCTURE_RULES = new DITStructureRule[0]; 081 private static final DITContentRule[] EMPTY_DIT_CONTENT_RULES = new DITContentRule[0]; 082 private static final NameForm[] EMPTY_NAME_FORMS = new NameForm[0]; 083 084 /** The SchemaObject description's parsers */ 085 private final LdapComparatorDescriptionSchemaParser comparatorParser = new LdapComparatorDescriptionSchemaParser(); 086 private final NormalizerDescriptionSchemaParser normalizerParser = new NormalizerDescriptionSchemaParser(); 087 private final SyntaxCheckerDescriptionSchemaParser syntaxCheckerParser = new SyntaxCheckerDescriptionSchemaParser(); 088 private final LdapSyntaxDescriptionSchemaParser syntaxParser = new LdapSyntaxDescriptionSchemaParser(); 089 private final MatchingRuleDescriptionSchemaParser matchingRuleParser = new MatchingRuleDescriptionSchemaParser(); 090 private final AttributeTypeDescriptionSchemaParser attributeTypeParser = new AttributeTypeDescriptionSchemaParser(); 091 private final ObjectClassDescriptionSchemaParser objectClassParser = new ObjectClassDescriptionSchemaParser(); 092 private final MatchingRuleUseDescriptionSchemaParser matchingRuleUseParser = new MatchingRuleUseDescriptionSchemaParser(); 093 private final DITStructureRuleDescriptionSchemaParser ditStructureRuleParser = new DITStructureRuleDescriptionSchemaParser(); 094 private final DITContentRuleDescriptionSchemaParser ditContentRuleParser = new DITContentRuleDescriptionSchemaParser(); 095 private final NameFormDescriptionSchemaParser nameFormParser = new NameFormDescriptionSchemaParser(); 096 097 /** The SchemaManager instance */ 098 private final SchemaManager schemaManager; 099 100 /** 101 * Creates a description parser. 102 * 103 * @param globalRegistries the registries to use while creating new schema entities 104 */ 105 public DescriptionParsers( SchemaManager schemaManager ) 106 { 107 this.schemaManager = schemaManager; 108 } 109 110 111 /** 112 * Parse the SyntaxCheckers description 113 * 114 * @param attr The attribute containing the SC description 115 * @return The array of SyntaxCheckerDescription instances 116 * @throws LdapInvalidAttributeValueException If something went wrong 117 */ 118 public SyntaxCheckerDescription[] parseSyntaxCheckers( EntryAttribute attr ) throws LdapInvalidAttributeValueException 119 { 120 if ( ( attr == null ) || ( attr.size() == 0 ) ) 121 { 122 return EMPTY_SYNTAX_CHECKERS; 123 } 124 125 SyntaxCheckerDescription[] syntaxCheckerDescriptions = new SyntaxCheckerDescription[attr.size()]; 126 127 int pos = 0; 128 129 for ( Value<?> value : attr ) 130 { 131 try 132 { 133 syntaxCheckerDescriptions[pos++] = syntaxCheckerParser 134 .parseSyntaxCheckerDescription( value.getString() ); 135 } 136 catch ( ParseException e ) 137 { 138 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_405, 139 value ) ); 140 iave.initCause( e ); 141 throw iave; 142 } 143 } 144 145 return syntaxCheckerDescriptions; 146 } 147 148 149 public NormalizerDescription[] parseNormalizers( EntryAttribute attr ) throws LdapInvalidAttributeValueException 150 { 151 if ( attr == null || attr.size() == 0 ) 152 { 153 return EMPTY_NORMALIZERS; 154 } 155 156 NormalizerDescription[] normalizerDescriptions = new NormalizerDescription[attr.size()]; 157 158 int pos = 0; 159 160 for ( Value<?> value : attr ) 161 { 162 try 163 { 164 normalizerDescriptions[pos++] = normalizerParser.parseNormalizerDescription( value.getString() ); 165 } 166 catch ( ParseException e ) 167 { 168 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_406, 169 value.getString() ) ); 170 iave.initCause( e ); 171 throw iave; 172 } 173 } 174 175 return normalizerDescriptions; 176 } 177 178 179 public LdapComparatorDescription[] parseComparators( EntryAttribute attr ) throws LdapInvalidAttributeValueException 180 { 181 if ( attr == null || attr.size() == 0 ) 182 { 183 return EMPTY_COMPARATORS; 184 } 185 186 LdapComparatorDescription[] comparatorDescriptions = new LdapComparatorDescription[attr.size()]; 187 188 int pos = 0; 189 190 for ( Value<?> value : attr ) 191 { 192 try 193 { 194 comparatorDescriptions[pos++] = comparatorParser.parseComparatorDescription( value.getString() ); 195 } 196 catch ( ParseException e ) 197 { 198 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_407, 199 value.getString() ) ); 200 iave.initCause( e ); 201 throw iave; 202 } 203 } 204 205 return comparatorDescriptions; 206 } 207 208 209 /** 210 * Parses a set of attributeTypeDescriptions held within an attribute into 211 * schema entities. 212 * 213 * @param attr the attribute containing attributeTypeDescriptions 214 * @return the set of attributeType objects for the descriptions 215 * @throws LdapException if there are problems parsing the descriptions 216 */ 217 public AttributeType[] parseAttributeTypes( EntryAttribute attr ) throws LdapException 218 { 219 if ( attr == null || attr.size() == 0 ) 220 { 221 return EMPTY_ATTRIBUTE_TYPES; 222 } 223 224 AttributeType[] attributeTypes = new AttributeType[attr.size()]; 225 226 int pos = 0; 227 228 for ( Value<?> value : attr ) 229 { 230 AttributeType attributeType = null; 231 232 try 233 { 234 attributeType = attributeTypeParser.parseAttributeTypeDescription( value.getString() ); 235 } 236 catch ( ParseException e ) 237 { 238 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_408, 239 value.getString() ) ); 240 iave.initCause( e ); 241 throw iave; 242 } 243 244 // if the supertype is provided make sure it exists in some schema 245 if ( ( attributeType.getSuperiorOid() != null ) && !schemaManager.getAttributeTypeRegistry().contains( attributeType.getSuperiorOid() ) ) 246 { 247 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 248 I18n.err( I18n.ERR_409, attributeType.getSuperiorOid() ) ); 249 } 250 251 // if the syntax is provided by the description make sure it exists in some schema 252 if ( attributeType.getSyntaxOid() != null && !schemaManager.getLdapSyntaxRegistry().contains( attributeType.getSyntaxOid() ) ) 253 { 254 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 255 I18n.err( I18n.ERR_410, attributeType.getSyntaxOid() ) ); 256 } 257 258 // if the matchingRule is provided make sure it exists in some schema 259 if ( attributeType.getEqualityOid() != null && !schemaManager.getMatchingRuleRegistry().contains( attributeType.getEqualityOid() ) ) 260 { 261 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 262 I18n.err( I18n.ERR_411, attributeType.getEqualityOid() ) ); 263 } 264 265 // if the matchingRule is provided make sure it exists in some schema 266 if ( attributeType.getOrderingOid() != null && !schemaManager.getMatchingRuleRegistry().contains( attributeType.getOrderingOid() ) ) 267 { 268 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 269 I18n.err( I18n.ERR_412, attributeType.getOrderingOid() ) ); 270 } 271 272 // if the matchingRule is provided make sure it exists in some schema 273 if ( attributeType.getSubstringOid() != null && !schemaManager.getMatchingRuleRegistry().contains( attributeType.getSubstringOid() ) ) 274 { 275 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 276 I18n.err( I18n.ERR_413, attributeType.getSubstringOid() ) ); 277 } 278 279 // if the equality matching rule is null and no super type is specified then there is 280 // definitely no equality matchingRule that can be resolved. We cannot use an attribute 281 // without a matchingRule for search or for building indices not to mention lookups. 282 if ( attributeType.getEqualityOid() == null ) 283 { 284 if ( attributeType.getSuperiorOid() == null ) 285 { 286 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_414 ) ); 287 } 288 else 289 { 290 AttributeType superType = schemaManager 291 .lookupAttributeTypeRegistry( attributeType.getSuperiorOid() ); 292 293 if ( superType == null ) 294 { 295 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_415 ) ); 296 } 297 } 298 } 299 300 // a syntax is mandatory for an attributeType and if not provided by the description 301 // must be provided from some ancestor in the attributeType hierarchy; without either 302 // of these the description definitely cannot resolve a syntax and cannot be allowed. 303 // if a supertype exists then it must resolve a proper syntax somewhere in the hierarchy. 304 if ( attributeType.getSyntaxOid() == null && attributeType.getSuperiorOid() == null ) 305 { 306 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_416 ) ); 307 } 308 309 List<Throwable> errors = new ArrayList<Throwable>(); 310 311 attributeType.setRegistries( schemaManager.getRegistries() ); 312 313 /* 314 // Inject the schema 315 316 if ( ( attributeType.getExtensions() == null ) 317 || ( attributeType.getExtensions().get( MetaSchemaConstants.X_SCHEMA ) == null ) ) 318 { 319 throw new LdapUnwillingToPerformException( 320 "Cannot permit the addition of an attributeType not associated with a schema ", 321 ResultCodeEnum.UNWILLING_TO_PERFORM ); 322 } 323 324 String schemaName = attributeType.getExtensions().get( MetaSchemaConstants.X_SCHEMA ).get( 0 ); 325 attributeType.setSchemaName( schemaName ); 326 */ 327 328 attributeTypes[pos++] = attributeType; 329 } 330 331 return attributeTypes; 332 } 333 334 335 /** 336 * Parses a set of objectClassDescriptions held within an attribute into 337 * schema entities. 338 * 339 * @param attr the attribute containing objectClassDescriptions 340 * @return the set of objectClass objects for the descriptions 341 * @throws LdapException if there are problems parsing the descriptions 342 */ 343 public ObjectClass[] parseObjectClasses( EntryAttribute attr ) throws LdapException 344 { 345 if ( attr == null || attr.size() == 0 ) 346 { 347 return EMPTY_OBJECT_CLASSES; 348 } 349 350 ObjectClass[] objectClasses = new ObjectClass[attr.size()]; 351 352 int pos = 0; 353 354 for ( Value<?> value : attr ) 355 { 356 ObjectClass objectClass = null; 357 358 try 359 { 360 objectClass = objectClassParser.parseObjectClassDescription( value.getString() ); 361 } 362 catch ( ParseException e ) 363 { 364 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_417, 365 value.getString() ) ); 366 iave.initCause( e ); 367 throw iave; 368 } 369 370 // if the super objectClasses are provided make sure it exists in some schema 371 if ( objectClass.getSuperiorOids() != null && objectClass.getSuperiorOids().size() > 0 ) 372 { 373 for ( String superiorOid : objectClass.getSuperiorOids() ) 374 { 375 if ( superiorOid.equals( SchemaConstants.TOP_OC_OID ) 376 || superiorOid.equalsIgnoreCase( SchemaConstants.TOP_OC ) ) 377 { 378 continue; 379 } 380 381 if ( !schemaManager.getObjectClassRegistry().contains( superiorOid ) ) 382 { 383 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 384 I18n.err( I18n.ERR_418, superiorOid ) ); 385 } 386 } 387 } 388 389 // if the may list is provided make sure attributes exists in some schema 390 if ( objectClass.getMayAttributeTypeOids() != null && objectClass.getMayAttributeTypeOids().size() > 0 ) 391 { 392 for ( String mayAttrOid : objectClass.getMayAttributeTypeOids() ) 393 { 394 if ( !schemaManager.getAttributeTypeRegistry().contains( mayAttrOid ) ) 395 { 396 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 397 I18n.err( I18n.ERR_419, mayAttrOid ) ); 398 } 399 } 400 } 401 402 // if the must list is provided make sure attributes exists in some schema 403 if ( objectClass.getMustAttributeTypeOids() != null && objectClass.getMustAttributeTypeOids().size() > 0 ) 404 { 405 for ( String mustAttrOid : objectClass.getMustAttributeTypeOids() ) 406 { 407 if ( !schemaManager.getAttributeTypeRegistry().contains( mustAttrOid ) ) 408 { 409 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 410 I18n.err( I18n.ERR_420, mustAttrOid ) ); 411 } 412 } 413 } 414 415 List<Throwable> errors = new ArrayList<Throwable>(); 416 objectClass.setRegistries( schemaManager.getRegistries() ); 417 418 objectClasses[pos++] = objectClass; 419 } 420 421 return objectClasses; 422 } 423 424 425 /** 426 * Parses a set of matchingRuleUseDescriptions held within an attribute into 427 * schema entities. 428 * 429 * @param attr the attribute containing matchingRuleUseDescriptions 430 * @return the set of matchingRuleUse objects for the descriptions 431 * @throws LdapException if there are problems parsing the descriptions 432 */ 433 public MatchingRuleUse[] parseMatchingRuleUses( EntryAttribute attr ) throws LdapException 434 { 435 if ( attr == null || attr.size() == 0 ) 436 { 437 return EMPTY_MATCHING_RULE_USES; 438 } 439 440 MatchingRuleUse[] matchingRuleUses = new MatchingRuleUse[attr.size()]; 441 442 int pos = 0; 443 444 for ( Value<?> value : attr ) 445 { 446 MatchingRuleUse matchingRuleUse = null; 447 448 try 449 { 450 matchingRuleUse = matchingRuleUseParser.parseMatchingRuleUseDescription( value.getString() ); 451 matchingRuleUse.setSpecification( value.getString() ); 452 } 453 catch ( ParseException e ) 454 { 455 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_421, 456 value.getString() ) ); 457 iave.initCause( e ); 458 throw iave; 459 } 460 461 matchingRuleUses[pos++] = matchingRuleUse; 462 } 463 464 return matchingRuleUses; 465 } 466 467 468 /** 469 * Parses a set of ldapSyntaxes held within an attribute into 470 * schema entities. 471 * 472 * @param attr the attribute containing ldapSyntaxes 473 * @return the set of Syntax objects for the descriptions 474 * @throws LdapException if there are problems parsing the descriptions 475 */ 476 public LdapSyntax[] parseLdapSyntaxes( EntryAttribute attr ) throws LdapException 477 { 478 if ( attr == null || attr.size() == 0 ) 479 { 480 return EMPTY_SYNTAXES; 481 } 482 483 LdapSyntax[] syntaxes = new LdapSyntax[attr.size()]; 484 485 int pos = 0; 486 487 for ( Value<?> value : attr ) 488 { 489 LdapSyntax ldapSyntax = null; 490 491 try 492 { 493 ldapSyntax = syntaxParser.parseLdapSyntaxDescription( value.getString() ); 494 ldapSyntax.setSpecification( value.getString() ); 495 } 496 catch ( ParseException e ) 497 { 498 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_422, 499 value.getString() ) ); 500 iave.initCause( e ); 501 throw iave; 502 } 503 504 if ( !schemaManager.getSyntaxCheckerRegistry().contains( ldapSyntax.getOid() ) ) 505 { 506 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_423 ) ); 507 } 508 509 ldapSyntax.setHumanReadable( isHumanReadable( ldapSyntax ) ); 510 syntaxes[pos++] = ldapSyntax; 511 } 512 513 return syntaxes; 514 } 515 516 517 /** 518 * Parses a set of matchingRuleDescriptions held within an attribute into 519 * schema entities. 520 * 521 * @param attr the attribute containing matchingRuleDescriptions 522 * @return the set of matchingRule objects for the descriptions 523 * @throws LdapException if there are problems parsing the descriptions 524 */ 525 public MatchingRule[] parseMatchingRules( EntryAttribute attr ) throws LdapException 526 { 527 if ( attr == null || attr.size() == 0 ) 528 { 529 return EMPTY_MATCHING_RULES; 530 } 531 532 MatchingRule[] matchingRules = new MatchingRule[attr.size()]; 533 534 int pos = 0; 535 536 for ( Value<?> value : attr ) 537 { 538 MatchingRule matchingRule = null; 539 540 try 541 { 542 matchingRule = matchingRuleParser.parseMatchingRuleDescription( value.getString() ); 543 matchingRule.setSpecification( value.getString() ); 544 } 545 catch ( ParseException e ) 546 { 547 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_424, 548 value.getString() ) ); 549 iave.initCause( e ); 550 throw iave; 551 } 552 553 if ( !schemaManager.getLdapSyntaxRegistry().contains( matchingRule.getSyntaxOid() ) ) 554 { 555 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, 556 I18n.err( I18n.ERR_425, matchingRule.getSyntaxOid() ) ); 557 } 558 559 matchingRules[pos++] = matchingRule; 560 } 561 562 return matchingRules; 563 } 564 565 566 /** 567 * Parses a set of dITStructureRuleDescriptions held within an attribute into 568 * schema entities. 569 * 570 * @param attr the attribute containing dITStructureRuleDescriptions 571 * @return the set of DITStructureRule objects for the descriptions 572 * @throws LdapException if there are problems parsing the descriptions 573 */ 574 public DITStructureRule[] parseDitStructureRules( EntryAttribute attr ) throws LdapException 575 { 576 if ( attr == null || attr.size() == 0 ) 577 { 578 return EMPTY_DIT_STRUCTURE_RULES; 579 } 580 581 DITStructureRule[] ditStructureRules = new DITStructureRule[attr.size()]; 582 583 int pos = 0; 584 585 for ( Value<?> value : attr ) 586 { 587 DITStructureRule ditStructureRule = null; 588 589 try 590 { 591 ditStructureRule = ditStructureRuleParser.parseDITStructureRuleDescription( value.getString() ); 592 ditStructureRule.setSpecification( value.getString() ); 593 } 594 catch ( ParseException e ) 595 { 596 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_426, 597 value.getString() ) ); 598 iave.initCause( e ); 599 throw iave; 600 } 601 602 ditStructureRules[pos++] = ditStructureRule; 603 } 604 605 return ditStructureRules; 606 } 607 608 609 /** 610 * Parses a set of dITContentRuleDescriptions held within an attribute into 611 * schema entities. 612 * 613 * @param attr the attribute containing dITContentRuleDescriptions 614 * @return the set of DITContentRule objects for the descriptions 615 * @throws LdapException if there are problems parsing the descriptions 616 */ 617 public DITContentRule[] parseDitContentRules( EntryAttribute attr ) throws LdapException 618 { 619 if ( attr == null || attr.size() == 0 ) 620 { 621 return EMPTY_DIT_CONTENT_RULES; 622 } 623 624 DITContentRule[] ditContentRules = new DITContentRule[attr.size()]; 625 626 int pos = 0; 627 628 for ( Value<?> value : attr ) 629 { 630 DITContentRule ditContentRule = null; 631 632 try 633 { 634 ditContentRule = ditContentRuleParser.parseDITContentRuleDescription( value.getString() ); 635 ditContentRule.setSpecification( value.getString() ); 636 } 637 catch ( ParseException e ) 638 { 639 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_427, 640 value.getString() ) ); 641 iave.initCause( e ); 642 throw iave; 643 } 644 645 ditContentRules[pos++] = ditContentRule; 646 } 647 648 return ditContentRules; 649 } 650 651 652 /** 653 * Parses a set of nameFormDescriptions held within an attribute into 654 * schema entities. 655 * 656 * @param attr the attribute containing nameFormDescriptions 657 * @return the set of NameFormRule objects for the descriptions 658 * @throws LdapException if there are problems parsing the descriptions 659 */ 660 public NameForm[] parseNameForms( EntryAttribute attr ) throws LdapException 661 { 662 if ( attr == null || attr.size() == 0 ) 663 { 664 return EMPTY_NAME_FORMS; 665 } 666 667 NameForm[] nameForms = new NameForm[attr.size()]; 668 669 int pos = 0; 670 671 for ( Value<?> value : attr ) 672 { 673 NameForm nameForm = null; 674 675 try 676 { 677 nameForm = nameFormParser.parseNameFormDescription( value.getString() ); 678 nameForm.setSpecification( value.getString() ); 679 } 680 catch ( ParseException e ) 681 { 682 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_428, 683 value.getString() ) ); 684 iave.initCause( e ); 685 throw iave; 686 } 687 688 nameForms[pos++] = nameForm; 689 } 690 691 return nameForms; 692 } 693 694 695 /** 696 * Checks to see if the syntax description is human readable by checking 697 * for the presence of the X-IS-HUMAN_READABLE schema extension. 698 * 699 * @param desc the ldapSyntax 700 * @return true if the syntax is human readable, false otherwise 701 */ 702 private boolean isHumanReadable( LdapSyntax ldapSyntax ) 703 { 704 List<String> values = ldapSyntax.getExtensions().get( MetaSchemaConstants.X_IS_HUMAN_READABLE ); 705 706 if ( values == null || values.size() == 0 ) 707 { 708 return false; 709 } 710 else 711 { 712 String value = values.get( 0 ); 713 if ( value.equals( "TRUE" ) ) 714 { 715 return true; 716 } 717 else 718 { 719 return false; 720 } 721 } 722 } 723 }