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 }