View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    * 
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   * 
19   */
20  package org.apache.directory.server.core.api.schema;
21  
22  
23  import java.text.ParseException;
24  
25  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
26  import org.apache.directory.api.ldap.model.entry.Attribute;
27  import org.apache.directory.api.ldap.model.entry.Value;
28  import org.apache.directory.api.ldap.model.exception.LdapException;
29  import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
30  import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
31  import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
32  import org.apache.directory.api.ldap.model.schema.AttributeType;
33  import org.apache.directory.api.ldap.model.schema.DitContentRule;
34  import org.apache.directory.api.ldap.model.schema.DitStructureRule;
35  import org.apache.directory.api.ldap.model.schema.LdapSyntax;
36  import org.apache.directory.api.ldap.model.schema.MatchingRule;
37  import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
38  import org.apache.directory.api.ldap.model.schema.NameForm;
39  import org.apache.directory.api.ldap.model.schema.ObjectClass;
40  import org.apache.directory.api.ldap.model.schema.SchemaManager;
41  import org.apache.directory.api.ldap.model.schema.parsers.AttributeTypeDescriptionSchemaParser;
42  import org.apache.directory.api.ldap.model.schema.parsers.DitContentRuleDescriptionSchemaParser;
43  import org.apache.directory.api.ldap.model.schema.parsers.DitStructureRuleDescriptionSchemaParser;
44  import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription;
45  import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescriptionSchemaParser;
46  import org.apache.directory.api.ldap.model.schema.parsers.LdapSyntaxDescriptionSchemaParser;
47  import org.apache.directory.api.ldap.model.schema.parsers.MatchingRuleDescriptionSchemaParser;
48  import org.apache.directory.api.ldap.model.schema.parsers.MatchingRuleUseDescriptionSchemaParser;
49  import org.apache.directory.api.ldap.model.schema.parsers.NameFormDescriptionSchemaParser;
50  import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription;
51  import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescriptionSchemaParser;
52  import org.apache.directory.api.ldap.model.schema.parsers.ObjectClassDescriptionSchemaParser;
53  import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription;
54  import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescriptionSchemaParser;
55  import org.apache.directory.server.i18n.I18n;
56  
57  
58  /**
59   * TODO: move to apacheds-core?
60   * 
61   * Parses descriptions using a number of different parsers for schema descriptions.
62   * Also checks to make sure some things are valid as it's parsing paramters of
63   * certain entity types.
64   *
65   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
66   */
67  public class DescriptionParsers
68  {
69      /** Empty arrays of SchemaObjects */
70      private static final LdapComparatorDescription[] EMPTY_COMPARATORS = new LdapComparatorDescription[0];
71      private static final NormalizerDescription[] EMPTY_NORMALIZERS = new NormalizerDescription[0];
72      private static final SyntaxCheckerDescription[] EMPTY_SYNTAX_CHECKERS = new SyntaxCheckerDescription[0];
73      private static final LdapSyntax[] EMPTY_SYNTAXES = new LdapSyntax[0];
74      private static final MatchingRule[] EMPTY_MATCHING_RULES = new MatchingRule[0];
75      private static final AttributeType[] EMPTY_ATTRIBUTE_TYPES = new AttributeType[0];
76      private static final ObjectClass[] EMPTY_OBJECT_CLASSES = new ObjectClass[0];
77      private static final MatchingRuleUse[] EMPTY_MATCHING_RULE_USES = new MatchingRuleUse[0];
78      private static final DitStructureRule[] EMPTY_DIT_STRUCTURE_RULES = new DitStructureRule[0];
79      private static final DitContentRule[] EMPTY_DIT_CONTENT_RULES = new DitContentRule[0];
80      private static final NameForm[] EMPTY_NAME_FORMS = new NameForm[0];
81  
82      /** The SchemaObject description's parsers */
83      private final LdapComparatorDescriptionSchemaParser comparatorParser = new LdapComparatorDescriptionSchemaParser();
84      private final NormalizerDescriptionSchemaParser normalizerParser = new NormalizerDescriptionSchemaParser();
85      private final SyntaxCheckerDescriptionSchemaParser syntaxCheckerParser = new SyntaxCheckerDescriptionSchemaParser();
86      private final LdapSyntaxDescriptionSchemaParser syntaxParser = new LdapSyntaxDescriptionSchemaParser();
87      private final MatchingRuleDescriptionSchemaParser matchingRuleParser = new MatchingRuleDescriptionSchemaParser();
88      private final AttributeTypeDescriptionSchemaParser attributeTypeParser = new AttributeTypeDescriptionSchemaParser();
89      private final ObjectClassDescriptionSchemaParser objectClassParser = new ObjectClassDescriptionSchemaParser();
90      private final MatchingRuleUseDescriptionSchemaParser matchingRuleUseParser = new MatchingRuleUseDescriptionSchemaParser();
91      private final DitStructureRuleDescriptionSchemaParser ditStructureRuleParser = new DitStructureRuleDescriptionSchemaParser();
92      private final DitContentRuleDescriptionSchemaParser ditContentRuleParser = new DitContentRuleDescriptionSchemaParser();
93      private final NameFormDescriptionSchemaParser nameFormParser = new NameFormDescriptionSchemaParser();
94  
95      /** The SchemaManager instance */
96      private final SchemaManager schemaManager;
97  
98  
99      /**
100      * Creates a description parser.
101      * 
102      * @param schemaManager The server schemaManager to use while creating new schema entities
103      */
104     public DescriptionParsers( SchemaManager schemaManager )
105     {
106         this.schemaManager = schemaManager;
107     }
108 
109 
110     /**
111      * Parse the SyntaxCheckers description
112      *
113      * @param attr The attribute containing the SC description
114      * @return The array of SyntaxCheckerDescription instances
115      * @throws LdapInvalidAttributeValueException If something went wrong
116      */
117     public SyntaxCheckerDescription[] parseSyntaxCheckers( Attribute attr ) throws LdapInvalidAttributeValueException
118     {
119         if ( ( attr == null ) || ( attr.size() == 0 ) )
120         {
121             return EMPTY_SYNTAX_CHECKERS;
122         }
123 
124         SyntaxCheckerDescription[] syntaxCheckerDescriptions = new SyntaxCheckerDescription[attr.size()];
125 
126         int pos = 0;
127 
128         for ( Value value : attr )
129         {
130             try
131             {
132                 syntaxCheckerDescriptions[pos++] = syntaxCheckerParser
133                     .parse( value.getString() );
134             }
135             catch ( ParseException e )
136             {
137                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
138                     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( Attribute 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.parse( value.getString() );
165             }
166             catch ( ParseException e )
167             {
168                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
169                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_406,
170                         value.getString() ) );
171                 iave.initCause( e );
172                 throw iave;
173             }
174         }
175 
176         return normalizerDescriptions;
177     }
178 
179 
180     public LdapComparatorDescription[] parseComparators( Attribute attr ) throws LdapInvalidAttributeValueException
181     {
182         if ( attr == null || attr.size() == 0 )
183         {
184             return EMPTY_COMPARATORS;
185         }
186 
187         LdapComparatorDescription[] comparatorDescriptions = new LdapComparatorDescription[attr.size()];
188 
189         int pos = 0;
190 
191         for ( Value value : attr )
192         {
193             try
194             {
195                 comparatorDescriptions[pos++] = comparatorParser.parse( value.getString() );
196             }
197             catch ( ParseException e )
198             {
199                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
200                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_407,
201                         value.getString() ) );
202                 iave.initCause( e );
203                 throw iave;
204             }
205         }
206 
207         return comparatorDescriptions;
208     }
209 
210 
211     /**
212      * Parses a set of attributeTypeDescriptions held within an attribute into
213      * schema entities.
214      * 
215      * @param attr the attribute containing attributeTypeDescriptions
216      * @return the set of attributeType objects for the descriptions
217      * @throws LdapException if there are problems parsing the descriptions
218      */
219     public AttributeType[] parseAttributeTypes( Attribute attr ) throws LdapException
220     {
221         if ( ( attr == null ) || ( attr.size() == 0 ) )
222         {
223             return EMPTY_ATTRIBUTE_TYPES;
224         }
225 
226         AttributeType[] attributeTypes = new AttributeType[attr.size()];
227 
228         int pos = 0;
229 
230         for ( Value value : attr )
231         {
232             AttributeType attributeType = null;
233 
234             try
235             {
236                 attributeType = attributeTypeParser.parse( value.getString() );
237             }
238             catch ( ParseException e )
239             {
240                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
241                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_408,
242                         value.getString() ) );
243                 iave.initCause( e );
244                 throw iave;
245             }
246 
247             // if the supertype is provided make sure it exists in some schema
248             if ( ( attributeType.getSuperiorOid() != null )
249                 && !schemaManager.getAttributeTypeRegistry().contains( attributeType.getSuperiorOid() ) )
250             {
251                 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
252                     I18n.err( I18n.ERR_409, attributeType.getSuperiorOid() ) );
253             }
254 
255             // if the syntax is provided by the description make sure it exists in some schema
256             if ( ( attributeType.getSyntaxOid() != null )
257                 && !schemaManager.getLdapSyntaxRegistry().contains( attributeType.getSyntaxOid() ) )
258             {
259                 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
260                     I18n.err( I18n.ERR_410, attributeType.getSyntaxOid() ) );
261             }
262 
263             // if the matchingRule is provided make sure it exists in some schema
264             if ( ( attributeType.getEqualityOid() != null )
265                 && !schemaManager.getMatchingRuleRegistry().contains( attributeType.getEqualityOid() ) )
266             {
267                 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
268                     I18n.err( I18n.ERR_411, attributeType.getEqualityOid() ) );
269             }
270 
271             // if the matchingRule is provided make sure it exists in some schema
272             if ( ( attributeType.getOrderingOid() != null )
273                 && !schemaManager.getMatchingRuleRegistry().contains( attributeType.getOrderingOid() ) )
274             {
275                 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
276                     I18n.err( I18n.ERR_412, attributeType.getOrderingOid() ) );
277             }
278 
279             // if the matchingRule is provided make sure it exists in some schema
280             if ( ( attributeType.getSubstringOid() != null )
281                 && !schemaManager.getMatchingRuleRegistry().contains( attributeType.getSubstringOid() ) )
282             {
283                 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
284                     I18n.err( I18n.ERR_413, attributeType.getSubstringOid() ) );
285             }
286 
287             attributeTypes[pos++] = attributeType;
288         }
289 
290         return attributeTypes;
291     }
292 
293 
294     /**
295      * Parses a set of objectClassDescriptions held within an attribute into
296      * schema entities.
297      * 
298      * @param attr the attribute containing objectClassDescriptions
299      * @return the set of objectClass objects for the descriptions
300      * @throws LdapException if there are problems parsing the descriptions
301      */
302     public ObjectClass[] parseObjectClasses( Attribute attr ) throws LdapException
303     {
304         if ( attr == null || attr.size() == 0 )
305         {
306             return EMPTY_OBJECT_CLASSES;
307         }
308 
309         ObjectClass[] objectClasses = new ObjectClass[attr.size()];
310 
311         int pos = 0;
312 
313         for ( Value value : attr )
314         {
315             ObjectClass objectClass = null;
316 
317             try
318             {
319                 objectClass = objectClassParser.parse( value.getString() );
320             }
321             catch ( ParseException e )
322             {
323                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
324                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_417,
325                         value.getString() ) );
326                 iave.initCause( e );
327                 throw iave;
328             }
329 
330             // if the super objectClasses are provided make sure it exists in some schema
331             if ( objectClass.getSuperiorOids() != null && !objectClass.getSuperiorOids().isEmpty() )
332             {
333                 for ( String superiorOid : objectClass.getSuperiorOids() )
334                 {
335                     if ( superiorOid.equals( SchemaConstants.TOP_OC_OID )
336                         || superiorOid.equalsIgnoreCase( SchemaConstants.TOP_OC ) )
337                     {
338                         continue;
339                     }
340 
341                     if ( !schemaManager.getObjectClassRegistry().contains( superiorOid ) )
342                     {
343                         throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
344                             I18n.err( I18n.ERR_418, superiorOid ) );
345                     }
346                 }
347             }
348 
349             // if the may list is provided make sure attributes exists in some schema
350             if ( objectClass.getMayAttributeTypeOids() != null && !objectClass.getMayAttributeTypeOids().isEmpty() )
351             {
352                 for ( String mayAttrOid : objectClass.getMayAttributeTypeOids() )
353                 {
354                     if ( !schemaManager.getAttributeTypeRegistry().contains( mayAttrOid ) )
355                     {
356                         throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
357                             I18n.err( I18n.ERR_419, mayAttrOid ) );
358                     }
359                 }
360             }
361 
362             // if the must list is provided make sure attributes exists in some schema
363             if ( objectClass.getMustAttributeTypeOids() != null && !objectClass.getMustAttributeTypeOids().isEmpty() )
364             {
365                 for ( String mustAttrOid : objectClass.getMustAttributeTypeOids() )
366                 {
367                     if ( !schemaManager.getAttributeTypeRegistry().contains( mustAttrOid ) )
368                     {
369                         throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
370                             I18n.err( I18n.ERR_420, mustAttrOid ) );
371                     }
372                 }
373             }
374 
375             objectClasses[pos++] = objectClass;
376         }
377 
378         return objectClasses;
379     }
380 
381 
382     /**
383      * Parses a set of matchingRuleUseDescriptions held within an attribute into
384      * schema entities.
385      * 
386      * @param attr the attribute containing matchingRuleUseDescriptions
387      * @return the set of matchingRuleUse objects for the descriptions
388      * @throws org.apache.directory.api.ldap.model.exception.LdapException if there are problems parsing the descriptions
389      */
390     public MatchingRuleUse[] parseMatchingRuleUses( Attribute attr ) throws LdapException
391     {
392         if ( attr == null || attr.size() == 0 )
393         {
394             return EMPTY_MATCHING_RULE_USES;
395         }
396 
397         MatchingRuleUse[] matchingRuleUses = new MatchingRuleUse[attr.size()];
398 
399         int pos = 0;
400 
401         for ( Value value : attr )
402         {
403             MatchingRuleUse matchingRuleUse = null;
404 
405             try
406             {
407                 matchingRuleUse = matchingRuleUseParser.parse( value.getString() );
408                 matchingRuleUse.setSpecification( value.getString() );
409             }
410             catch ( ParseException e )
411             {
412                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
413                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_421,
414                         value.getString() ) );
415                 iave.initCause( e );
416                 throw iave;
417             }
418 
419             matchingRuleUses[pos++] = matchingRuleUse;
420         }
421 
422         return matchingRuleUses;
423     }
424 
425 
426     /**
427      * Parses a set of ldapSyntaxes held within an attribute into
428      * schema entities.
429      * 
430      * @param attr the attribute containing ldapSyntaxes
431      * @return the set of Syntax objects for the descriptions
432      * @throws org.apache.directory.api.ldap.model.exception.LdapException if there are problems parsing the descriptions
433      */
434     public LdapSyntax[] parseLdapSyntaxes( Attribute attr ) throws LdapException
435     {
436         if ( attr == null || attr.size() == 0 )
437         {
438             return EMPTY_SYNTAXES;
439         }
440 
441         LdapSyntax[] syntaxes = new LdapSyntax[attr.size()];
442 
443         int pos = 0;
444 
445         for ( Value value : attr )
446         {
447             LdapSyntax ldapSyntax = null;
448 
449             try
450             {
451                 ldapSyntax = syntaxParser.parse( value.getString() );
452                 ldapSyntax.setSpecification( value.getString() );
453             }
454             catch ( ParseException e )
455             {
456                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
457                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_422,
458                         value.getString() ) );
459                 iave.initCause( e );
460                 throw iave;
461             }
462 
463             if ( !schemaManager.getSyntaxCheckerRegistry().contains( ldapSyntax.getOid() ) )
464             {
465                 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_423 ) );
466             }
467 
468             // Call this method once to initialize the flags
469             ldapSyntax.isHumanReadable();
470             
471             syntaxes[pos++] = ldapSyntax;
472         }
473 
474         return syntaxes;
475     }
476 
477 
478     /**
479      * Parses a set of matchingRuleDescriptions held within an attribute into
480      * schema entities.
481      * 
482      * @param attr the attribute containing matchingRuleDescriptions
483      * @return the set of matchingRule objects for the descriptions
484      * @throws LdapException if there are problems parsing the descriptions
485      */
486     public MatchingRule[] parseMatchingRules( Attribute attr ) throws LdapException
487     {
488         if ( attr == null || attr.size() == 0 )
489         {
490             return EMPTY_MATCHING_RULES;
491         }
492 
493         MatchingRule[] matchingRules = new MatchingRule[attr.size()];
494 
495         int pos = 0;
496 
497         for ( Value value : attr )
498         {
499             MatchingRule matchingRule = null;
500 
501             try
502             {
503                 matchingRule = matchingRuleParser.parse( value.getString() );
504                 matchingRule.setSpecification( value.getString() );
505             }
506             catch ( ParseException e )
507             {
508                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
509                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_424,
510                         value.getString() ) );
511                 iave.initCause( e );
512                 throw iave;
513             }
514 
515             if ( !schemaManager.getLdapSyntaxRegistry().contains( matchingRule.getSyntaxOid() ) )
516             {
517                 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
518                     I18n.err( I18n.ERR_425, matchingRule.getSyntaxOid() ) );
519             }
520 
521             matchingRules[pos++] = matchingRule;
522         }
523 
524         return matchingRules;
525     }
526 
527 
528     /**
529      * Parses a set of dITStructureRuleDescriptions held within an attribute into
530      * schema entities.
531      * 
532      * @param attr the attribute containing dITStructureRuleDescriptions
533      * @return the set of DitStructureRule objects for the descriptions
534      * @throws LdapException if there are problems parsing the descriptions
535      */
536     public DitStructureRule[] parseDitStructureRules( Attribute attr ) throws LdapException
537     {
538         if ( attr == null || attr.size() == 0 )
539         {
540             return EMPTY_DIT_STRUCTURE_RULES;
541         }
542 
543         DitStructureRule[] ditStructureRules = new DitStructureRule[attr.size()];
544 
545         int pos = 0;
546 
547         for ( Value value : attr )
548         {
549             DitStructureRule ditStructureRule = null;
550 
551             try
552             {
553                 ditStructureRule = ditStructureRuleParser.parse( value.getString() );
554                 ditStructureRule.setSpecification( value.getString() );
555             }
556             catch ( ParseException e )
557             {
558                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
559                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_426,
560                         value.getString() ) );
561                 iave.initCause( e );
562                 throw iave;
563             }
564 
565             ditStructureRules[pos++] = ditStructureRule;
566         }
567 
568         return ditStructureRules;
569     }
570 
571 
572     /**
573      * Parses a set of dITContentRuleDescriptions held within an attribute into
574      * schema entities.
575      * 
576      * @param attr the attribute containing dITContentRuleDescriptions
577      * @return the set of DitContentRule objects for the descriptions
578      * @throws LdapException if there are problems parsing the descriptions
579      */
580     public DitContentRule[] parseDitContentRules( Attribute attr ) throws LdapException
581     {
582         if ( attr == null || attr.size() == 0 )
583         {
584             return EMPTY_DIT_CONTENT_RULES;
585         }
586 
587         DitContentRule[] ditContentRules = new DitContentRule[attr.size()];
588 
589         int pos = 0;
590 
591         for ( Value value : attr )
592         {
593             DitContentRule ditContentRule = null;
594 
595             try
596             {
597                 ditContentRule = ditContentRuleParser.parse( value.getString() );
598                 ditContentRule.setSpecification( value.getString() );
599             }
600             catch ( ParseException e )
601             {
602                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
603                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_427,
604                         value.getString() ) );
605                 iave.initCause( e );
606                 throw iave;
607             }
608 
609             ditContentRules[pos++] = ditContentRule;
610         }
611 
612         return ditContentRules;
613     }
614 
615 
616     /**
617      * Parses a set of nameFormDescriptions held within an attribute into
618      * schema entities.
619      * 
620      * @param attr the attribute containing nameFormDescriptions
621      * @return the set of NameFormRule objects for the descriptions
622      * @throws LdapException if there are problems parsing the descriptions
623      */
624     public NameForm[] parseNameForms( Attribute attr ) throws LdapException
625     {
626         if ( attr == null || attr.size() == 0 )
627         {
628             return EMPTY_NAME_FORMS;
629         }
630 
631         NameForm[] nameForms = new NameForm[attr.size()];
632 
633         int pos = 0;
634 
635         for ( Value value : attr )
636         {
637             NameForm nameForm = null;
638 
639             try
640             {
641                 nameForm = nameFormParser.parse( value.getString() );
642                 nameForm.setSpecification( value.getString() );
643             }
644             catch ( ParseException e )
645             {
646                 LdapInvalidAttributeValueException iave = new LdapInvalidAttributeValueException(
647                     ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err( I18n.ERR_428,
648                         value.getString() ) );
649                 iave.initCause( e );
650                 throw iave;
651             }
652 
653             nameForms[pos++] = nameForm;
654         }
655 
656         return nameForms;
657     }
658 }