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  
21  package org.apache.directory.ldap.client.api;
22  
23  
24  import java.io.IOException;
25  import java.text.ParseException;
26  import java.util.ArrayList;
27  import java.util.List;
28  import java.util.Set;
29  
30  import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
31  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
32  import org.apache.directory.api.ldap.model.entry.Attribute;
33  import org.apache.directory.api.ldap.model.entry.DefaultEntry;
34  import org.apache.directory.api.ldap.model.entry.Entry;
35  import org.apache.directory.api.ldap.model.entry.Value;
36  import org.apache.directory.api.ldap.model.exception.LdapException;
37  import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
38  import org.apache.directory.api.ldap.model.name.Dn;
39  import org.apache.directory.api.ldap.model.schema.AttributeType;
40  import org.apache.directory.api.ldap.model.schema.AttributesFactory;
41  import org.apache.directory.api.ldap.model.schema.DitContentRule;
42  import org.apache.directory.api.ldap.model.schema.DitStructureRule;
43  import org.apache.directory.api.ldap.model.schema.LdapSyntax;
44  import org.apache.directory.api.ldap.model.schema.MatchingRule;
45  import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
46  import org.apache.directory.api.ldap.model.schema.NameForm;
47  import org.apache.directory.api.ldap.model.schema.ObjectClass;
48  import org.apache.directory.api.ldap.model.schema.SchemaObject;
49  import org.apache.directory.api.ldap.model.schema.SchemaObjectWrapper;
50  import org.apache.directory.api.ldap.model.schema.parsers.AttributeTypeDescriptionSchemaParser;
51  import org.apache.directory.api.ldap.model.schema.parsers.DitContentRuleDescriptionSchemaParser;
52  import org.apache.directory.api.ldap.model.schema.parsers.DitStructureRuleDescriptionSchemaParser;
53  import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription;
54  import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescriptionSchemaParser;
55  import org.apache.directory.api.ldap.model.schema.parsers.LdapSyntaxDescriptionSchemaParser;
56  import org.apache.directory.api.ldap.model.schema.parsers.MatchingRuleDescriptionSchemaParser;
57  import org.apache.directory.api.ldap.model.schema.parsers.MatchingRuleUseDescriptionSchemaParser;
58  import org.apache.directory.api.ldap.model.schema.parsers.NameFormDescriptionSchemaParser;
59  import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription;
60  import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescriptionSchemaParser;
61  import org.apache.directory.api.ldap.model.schema.parsers.ObjectClassDescriptionSchemaParser;
62  import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription;
63  import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescriptionSchemaParser;
64  import org.apache.directory.api.ldap.model.schema.registries.AbstractSchemaLoader;
65  import org.apache.directory.api.ldap.model.schema.registries.DefaultSchema;
66  import org.apache.directory.api.ldap.model.schema.registries.Schema;
67  import org.apache.directory.api.util.Base64;
68  import org.apache.directory.api.util.Strings;
69  import org.apache.directory.ldap.client.api.exception.InvalidConnectionException;
70  import org.slf4j.Logger;
71  import org.slf4j.LoggerFactory;
72  
73  
74  /**
75   * A schema loader which uses LdapConnection to load schema from a ApacheDS serveur
76   *
77   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
78   */
79  public class DefaultSchemaLoader extends AbstractSchemaLoader
80  {
81      private static final String DEFAULT_APACHEDS_VENDOR_NAME = "Apache Software Foundation";
82  
83      /** the logger */
84      private static final Logger LOG = LoggerFactory.getLogger( DefaultSchemaLoader.class );
85  
86      /** the connection to the ldap server */
87      private LdapConnection connection;
88  
89      /** the subschemaSubentry DN */
90      private Dn subschemaSubentryDn;
91  
92      /** The SubschemaSubentry descriptions parsers */
93      private static final AttributeTypeDescriptionSchemaParser AT_DESCR_SCHEMA_PARSER = new AttributeTypeDescriptionSchemaParser();
94      private static final DitStructureRuleDescriptionSchemaParser DSR_DESCR_SCHEMA_PARSER = new DitStructureRuleDescriptionSchemaParser();
95      private static final DitContentRuleDescriptionSchemaParser DCR_DESCR_SCHEMA_PARSER = new DitContentRuleDescriptionSchemaParser();
96      private static final MatchingRuleDescriptionSchemaParser MR_DESCR_SCHEMA_PARSER = new MatchingRuleDescriptionSchemaParser();
97      private static final MatchingRuleUseDescriptionSchemaParser MRU_DESCR_SCHEMA_PARSER = new MatchingRuleUseDescriptionSchemaParser();
98      private static final NameFormDescriptionSchemaParser NF_DESCR_SCHEMA_PARSER = new NameFormDescriptionSchemaParser();
99      private static final ObjectClassDescriptionSchemaParser OC_DESCR_SCHEMA_PARSER = new ObjectClassDescriptionSchemaParser();
100     private static final LdapSyntaxDescriptionSchemaParser LS_DESCR_SCHEMA_PARSER = new LdapSyntaxDescriptionSchemaParser();
101 
102     private static final LdapComparatorDescriptionSchemaParser C_DESCR_SCHEMA_PARSER = new LdapComparatorDescriptionSchemaParser();
103     private static final NormalizerDescriptionSchemaParser N_DESCR_SCHEMA_PARSER = new NormalizerDescriptionSchemaParser();
104     private static final SyntaxCheckerDescriptionSchemaParser SC_DESCR_SCHEMA_PARSER = new SyntaxCheckerDescriptionSchemaParser();
105 
106 
107     /**
108      * Creates a new instance of DefaultSchemaLoader.
109      *
110      * @param connection the LDAP connection
111      * @throws LdapException if the connection is not authenticated or if there are any problems
112      *                   while loading the schema entries
113      */
114     public DefaultSchemaLoader( LdapConnection connection ) throws LdapException
115     {
116         this( connection, false );
117     }
118 
119 
120     /**
121      * Creates a new instance of NetworkSchemaLoader.
122      *
123      * @param connection the LDAP connection
124      * @param subschemaSubentryDn The SubschemaSubentry
125      * @throws LdapException if the connection is not authenticated or if there are any problems
126      *                   while loading the schema entries
127      */
128     public DefaultSchemaLoader( LdapConnection connection, Dn subschemaSubentryDn ) throws LdapException
129     {
130         if ( !connection.isAuthenticated() )
131         {
132             throw new IllegalArgumentException( "connection is not authenticated" );
133         }
134 
135         this.connection = connection;
136         this.subschemaSubentryDn = subschemaSubentryDn;
137 
138         loadSchemas();
139     }
140 
141 
142     /**
143      * Creates a new instance of DefaultSchemaLoader.
144      *
145      * @param connection the LDAP connection
146      * @param relaxed initial setting for the relaxed mode
147      * @throws LdapException if the connection is not authenticated or if there are any problems
148      *                   while loading the schema entries
149      */
150     public DefaultSchemaLoader( LdapConnection connection, boolean relaxed ) throws LdapException
151     {
152         if ( connection == null )
153         {
154             throw new InvalidConnectionException( "Cannot connect on the server, the connection is null" );
155         }
156 
157         this.connection = connection;
158         setRelaxed( relaxed );
159         setQuirksMode( relaxed );
160 
161         // Flagging if the connection was already connected
162         boolean wasConnected = connection.isConnected();
163 
164         try
165         {
166             // Connecting (if needed)
167             if ( !wasConnected )
168             {
169                 connection.connect();
170             }
171 
172             // Getting the subschemaSubentry DN from the rootDSE
173             Entry rootDse = connection.lookup( Dn.ROOT_DSE, SchemaConstants.SUBSCHEMA_SUBENTRY_AT,
174                 SchemaConstants.VENDOR_NAME_AT );
175 
176             if ( rootDse != null )
177             {
178                 // Checking if this is an ApacheDS server
179                 if ( isApacheDs( rootDse ) )
180                 {
181                     // Getting the subSchemaSubEntry attribute
182                     Attribute subschemaSubentryAttribute = rootDse.get( SchemaConstants.SUBSCHEMA_SUBENTRY_AT );
183 
184                     if ( ( subschemaSubentryAttribute != null ) && ( subschemaSubentryAttribute.size() > 0 ) )
185                     {
186                         subschemaSubentryDn = new Dn( connection.getSchemaManager(),
187                             subschemaSubentryAttribute.getString() );
188 
189                         loadSchemas();
190                     }
191                 }
192                 else
193                 {
194                     try
195                     {
196                         // No matter what, first try to search the schema from the rootDSE
197                         // Getting the subSchemaSubEntry attribute
198                         Attribute subschemaSubentryAttribute = rootDse.get( SchemaConstants.SUBSCHEMA_SUBENTRY_AT );
199 
200                         if ( ( subschemaSubentryAttribute != null ) && ( subschemaSubentryAttribute.size() > 0 ) )
201                         {
202                             subschemaSubentryDn = new Dn( connection.getSchemaManager(),
203                                 subschemaSubentryAttribute.getString() );
204 
205                             loadSchemas();
206                         }
207                     }
208                     catch ( LdapException le )
209                     {
210                         // TODO : if we can't read the schema from the rootDSE, just try to read the 
211                         // schema from cn=schema
212                         throw le;
213                     }
214                 }
215             }
216         }
217         finally
218         {
219             // Checking if the connection needs to be closed
220             if ( ( !wasConnected ) && ( connection.isConnected() ) )
221             {
222                 try
223                 {
224                     connection.close();
225                 }
226                 catch ( IOException e )
227                 {
228                     throw new LdapException( e );
229                 }
230             }
231         }
232     }
233 
234 
235     /**
236      * Indicates if the given Root DSE corresponds to an ApacheDS server.
237      *
238      * @param rootDse the Root DSE
239      * @return <code>true</code> if this is an ApacheDS server,
240      *         <code>false</code> if not.
241      * @throws LdapInvalidAttributeValueException
242      */
243     private boolean isApacheDs( Entry rootDse ) throws LdapInvalidAttributeValueException
244     {
245         if ( rootDse != null )
246         {
247             Attribute vendorNameAttribute = rootDse.get( SchemaConstants.VENDOR_NAME_AT );
248 
249             if ( ( vendorNameAttribute != null ) && vendorNameAttribute.size() == 1 )
250             {
251                 return DEFAULT_APACHEDS_VENDOR_NAME.equalsIgnoreCase( vendorNameAttribute.getString() );
252             }
253         }
254 
255         return false;
256     }
257 
258 
259     /**
260      * Load all the schemas.
261      * 
262      * @param subschemaSubentryDn
263      * @throws LdapException
264      */
265     private void loadSchemas() throws LdapException
266     {
267         LOG.debug( "initializing schemas" );
268 
269         // Load all the elements from the SubschemaSubentry
270         Entry subschemaSubentry = connection.lookup( subschemaSubentryDn,
271             SchemaConstants.ATTRIBUTE_TYPES_AT,
272             SchemaConstants.COMPARATORS_AT,
273             SchemaConstants.DIT_CONTENT_RULES_AT,
274             SchemaConstants.DIT_STRUCTURE_RULES_AT,
275             SchemaConstants.LDAP_SYNTAXES_AT,
276             SchemaConstants.MATCHING_RULES_AT,
277             SchemaConstants.MATCHING_RULE_USE_AT,
278             SchemaConstants.NAME_FORMS_AT,
279             SchemaConstants.NORMALIZERS_AT,
280             SchemaConstants.OBJECT_CLASSES_AT,
281             SchemaConstants.SYNTAX_CHECKERS_AT
282             );
283 
284         // Load all the AT
285         Attribute attributeTypes = subschemaSubentry.get( SchemaConstants.ATTRIBUTE_TYPES_AT );
286         loadAttributeTypes( attributeTypes );
287 
288         // Load all the C
289         Attribute comparators = subschemaSubentry.get( SchemaConstants.COMPARATORS_AT );
290         loadComparators( comparators );
291 
292         // Load all the DCR
293         Attribute ditContentRules = subschemaSubentry.get( SchemaConstants.DIT_CONTENT_RULES_AT );
294         loadDitContentRules( ditContentRules );
295 
296         // Load all the DSR
297         Attribute ditStructureRules = subschemaSubentry.get( SchemaConstants.DIT_STRUCTURE_RULES_AT );
298         loadDitStructureRules( ditStructureRules );
299 
300         // Load all the LS
301         Attribute ldapSytaxes = subschemaSubentry.get( SchemaConstants.LDAP_SYNTAXES_AT );
302         loadLdapSyntaxes( ldapSytaxes );
303 
304         // Load all the MR
305         Attribute matchingRules = subschemaSubentry.get( SchemaConstants.MATCHING_RULES_AT );
306         loadMatchingRules( matchingRules );
307 
308         // Load all the MRU
309         Attribute matchingRuleUse = subschemaSubentry.get( SchemaConstants.MATCHING_RULE_USE_AT );
310         loadMatchingRuleUses( matchingRuleUse );
311 
312         // Load all the N
313         Attribute normalizers = subschemaSubentry.get( SchemaConstants.NORMALIZERS_AT );
314         loadNormalizers( normalizers );
315 
316         // Load all the NF
317         Attribute nameForms = subschemaSubentry.get( SchemaConstants.NAME_FORMS_AT );
318         loadNameForms( nameForms );
319 
320         // Load all the OC
321         Attribute objectClasses = subschemaSubentry.get( SchemaConstants.OBJECT_CLASSES_AT );
322         loadObjectClasses( objectClasses );
323 
324         // Load all the SC
325         Attribute syntaxCheckers = subschemaSubentry.get( SchemaConstants.SYNTAX_CHECKERS_AT );
326         loadSyntaxCheckers( syntaxCheckers );
327     }
328 
329 
330     private void loadAttributeTypes( Attribute attributeTypes ) throws LdapException
331     {
332         if ( attributeTypes == null )
333         {
334             return;
335         }
336 
337         for ( Value<?> value : attributeTypes )
338         {
339             String desc = value.getString();
340 
341             try
342             {
343                 AttributeType attributeType = AT_DESCR_SCHEMA_PARSER.parseAttributeTypeDescription( desc );
344 
345                 updateSchemas( attributeType );
346             }
347             catch ( ParseException pe )
348             {
349                 throw new LdapException( pe );
350             }
351         }
352     }
353 
354 
355     private void loadComparators( Attribute comparators ) throws LdapException
356     {
357         if ( comparators == null )
358         {
359             return;
360         }
361 
362         for ( Value<?> value : comparators )
363         {
364             String desc = value.getString();
365 
366             try
367             {
368                 LdapComparatorDescription comparator = C_DESCR_SCHEMA_PARSER.parseComparatorDescription( desc );
369 
370                 updateSchemas( comparator );
371             }
372             catch ( ParseException pe )
373             {
374                 throw new LdapException( pe );
375             }
376         }
377     }
378 
379 
380     private void loadDitContentRules( Attribute ditContentRules ) throws LdapException
381     {
382         if ( ditContentRules == null )
383         {
384             return;
385         }
386 
387         for ( Value<?> value : ditContentRules )
388         {
389             String desc = value.getString();
390 
391             try
392             {
393                 DitContentRule ditContentRule = DCR_DESCR_SCHEMA_PARSER.parseDITContentRuleDescription( desc );
394 
395                 updateSchemas( ditContentRule );
396             }
397             catch ( ParseException pe )
398             {
399                 throw new LdapException( pe );
400             }
401         }
402     }
403 
404 
405     private void loadDitStructureRules( Attribute ditStructureRules ) throws LdapException
406     {
407         if ( ditStructureRules == null )
408         {
409             return;
410         }
411 
412         for ( Value<?> value : ditStructureRules )
413         {
414             String desc = value.getString();
415 
416             try
417             {
418                 DitStructureRule ditStructureRule = DSR_DESCR_SCHEMA_PARSER.parseDITStructureRuleDescription( desc );
419 
420                 updateSchemas( ditStructureRule );
421             }
422             catch ( ParseException pe )
423             {
424                 throw new LdapException( pe );
425             }
426         }
427     }
428 
429 
430     private void loadLdapSyntaxes( Attribute ldapSyntaxes ) throws LdapException
431     {
432         if ( ldapSyntaxes == null )
433         {
434             return;
435         }
436 
437         for ( Value<?> value : ldapSyntaxes )
438         {
439             String desc = value.getString();
440 
441             try
442             {
443                 LdapSyntax ldapSyntax = LS_DESCR_SCHEMA_PARSER.parseLdapSyntaxDescription( desc );
444 
445                 updateSchemas( ldapSyntax );
446             }
447             catch ( ParseException pe )
448             {
449                 throw new LdapException( pe );
450             }
451         }
452     }
453 
454 
455     private void loadMatchingRules( Attribute matchingRules ) throws LdapException
456     {
457         if ( matchingRules == null )
458         {
459             return;
460         }
461 
462         for ( Value<?> value : matchingRules )
463         {
464             String desc = value.getString();
465 
466             try
467             {
468                 MatchingRule matchingRule = MR_DESCR_SCHEMA_PARSER.parseMatchingRuleDescription( desc );
469 
470                 updateSchemas( matchingRule );
471             }
472             catch ( ParseException pe )
473             {
474                 throw new LdapException( pe );
475             }
476         }
477     }
478 
479 
480     private void loadMatchingRuleUses( Attribute matchingRuleUses ) throws LdapException
481     {
482         if ( matchingRuleUses == null )
483         {
484             return;
485         }
486 
487         for ( Value<?> value : matchingRuleUses )
488         {
489             String desc = value.getString();
490 
491             try
492             {
493                 MatchingRuleUse matchingRuleUse = MRU_DESCR_SCHEMA_PARSER.parseMatchingRuleUseDescription( desc );
494 
495                 updateSchemas( matchingRuleUse );
496             }
497             catch ( ParseException pe )
498             {
499                 throw new LdapException( pe );
500             }
501         }
502     }
503 
504 
505     private void loadNameForms( Attribute nameForms ) throws LdapException
506     {
507         if ( nameForms == null )
508         {
509             return;
510         }
511 
512         for ( Value<?> value : nameForms )
513         {
514             String desc = value.getString();
515 
516             try
517             {
518                 NameForm nameForm = NF_DESCR_SCHEMA_PARSER.parseNameFormDescription( desc );
519 
520                 updateSchemas( nameForm );
521             }
522             catch ( ParseException pe )
523             {
524                 throw new LdapException( pe );
525             }
526         }
527     }
528 
529 
530     private void loadNormalizers( Attribute normalizers ) throws LdapException
531     {
532         if ( normalizers == null )
533         {
534             return;
535         }
536 
537         for ( Value<?> value : normalizers )
538         {
539             String desc = value.getString();
540 
541             try
542             {
543                 NormalizerDescription normalizer = N_DESCR_SCHEMA_PARSER.parseNormalizerDescription( desc );
544 
545                 updateSchemas( normalizer );
546             }
547             catch ( ParseException pe )
548             {
549                 throw new LdapException( pe );
550             }
551         }
552     }
553 
554 
555     private void loadObjectClasses( Attribute objectClasses ) throws LdapException
556     {
557         if ( objectClasses == null )
558         {
559             return;
560         }
561 
562         for ( Value<?> value : objectClasses )
563         {
564             String desc = value.getString();
565 
566             try
567             {
568                 ObjectClass objectClass = OC_DESCR_SCHEMA_PARSER.parseObjectClassDescription( desc );
569 
570                 updateSchemas( objectClass );
571             }
572             catch ( ParseException pe )
573             {
574                 throw new LdapException( pe );
575             }
576         }
577     }
578 
579 
580     private void loadSyntaxCheckers( Attribute syntaxCheckers ) throws LdapException
581     {
582         if ( syntaxCheckers == null )
583         {
584             return;
585         }
586 
587         for ( Value<?> value : syntaxCheckers )
588         {
589             String desc = value.getString();
590 
591             try
592             {
593                 SyntaxCheckerDescription syntaxChecker = SC_DESCR_SCHEMA_PARSER.parseSyntaxCheckerDescription( desc );
594 
595                 updateSchemas( syntaxChecker );
596             }
597             catch ( ParseException pe )
598             {
599                 throw new LdapException( pe );
600             }
601         }
602     }
603 
604 
605     private void updateSchemas( SchemaObject schemaObject )
606     {
607         String schemaName = schemaObject.getSchemaName();
608         Schema schema;
609 
610         if ( Strings.isEmpty( schemaName ) || Strings.equals( "null", schemaName ) )
611         {
612             schemaName = "default";
613             schema = schemaMap.get( schemaName );
614         }
615         else
616         {
617             schema = schemaMap.get( schemaName );
618         }
619 
620         if ( schema == null )
621         {
622             schema = new DefaultSchema( this, schemaName );
623 
624             schemaMap.put( schemaName, schema );
625         }
626 
627         schema.getContent().add( new SchemaObjectWrapper( schemaObject ) );
628 
629     }
630 
631 
632     /**
633      * {@inheritDoc}
634      */
635     @Override
636     public List<Entry> loadAttributeTypes( Schema... schemas ) throws LdapException, IOException
637     {
638         List<Entry> attributeTypeEntries = new ArrayList<>();
639 
640         if ( schemas == null )
641         {
642             return attributeTypeEntries;
643         }
644 
645         AttributesFactory factory = new AttributesFactory();
646 
647         for ( Schema schema : schemas )
648         {
649             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
650 
651             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
652             {
653                 SchemaObject schemaObject = schemaObjectWrapper.get();
654 
655                 if ( schemaObject instanceof AttributeType )
656                 {
657                     AttributeType attributeType = ( AttributeType ) schemaObject;
658 
659                     Entry attributeTypeEntry = factory.convert( attributeType, schema, null );
660 
661                     attributeTypeEntries.add( attributeTypeEntry );
662                 }
663             }
664         }
665 
666         return attributeTypeEntries;
667     }
668 
669 
670     /**
671      * {@inheritDoc}
672      */
673     @Override
674     public List<Entry> loadComparators( Schema... schemas ) throws LdapException, IOException
675     {
676         List<Entry> comparatorEntries = new ArrayList<>();
677 
678         if ( schemas == null )
679         {
680             return comparatorEntries;
681         }
682 
683         for ( Schema schema : schemas )
684         {
685             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
686 
687             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
688             {
689                 SchemaObject schemaObject = schemaObjectWrapper.get();
690 
691                 if ( schemaObject instanceof LdapComparatorDescription )
692                 {
693                     LdapComparatorDescription ldapComparatorDescription = ( LdapComparatorDescription ) schemaObject;
694                     Entry lcEntry = getEntry( ldapComparatorDescription );
695 
696                     comparatorEntries.add( lcEntry );
697                 }
698             }
699         }
700 
701         return comparatorEntries;
702     }
703 
704 
705     /**
706      * {@inheritDoc}
707      */
708     @Override
709     public List<Entry> loadDitContentRules( Schema... schemas ) throws LdapException, IOException
710     {
711         List<Entry> ditContentRuleEntries = new ArrayList<>();
712 
713         if ( schemas == null )
714         {
715             return ditContentRuleEntries;
716         }
717 
718         AttributesFactory factory = new AttributesFactory();
719 
720         for ( Schema schema : schemas )
721         {
722             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
723 
724             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
725             {
726                 SchemaObject schemaObject = schemaObjectWrapper.get();
727 
728                 if ( schemaObject instanceof DitContentRule )
729                 {
730                     DitContentRule ditContentRule = ( DitContentRule ) schemaObject;
731 
732                     Entry ditContentRuleEntry = factory.convert( ditContentRule, schema, null );
733 
734                     ditContentRuleEntries.add( ditContentRuleEntry );
735                 }
736             }
737         }
738 
739         return ditContentRuleEntries;
740     }
741 
742 
743     /**
744      * {@inheritDoc}
745      */
746     @Override
747     public List<Entry> loadDitStructureRules( Schema... schemas ) throws LdapException, IOException
748     {
749         List<Entry> ditStructureRuleEntries = new ArrayList<>();
750 
751         if ( schemas == null )
752         {
753             return ditStructureRuleEntries;
754         }
755 
756         AttributesFactory factory = new AttributesFactory();
757 
758         for ( Schema schema : schemas )
759         {
760             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
761 
762             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
763             {
764                 SchemaObject schemaObject = schemaObjectWrapper.get();
765 
766                 if ( schemaObject instanceof DitStructureRule )
767                 {
768                     DitStructureRule ditStructureRule = ( DitStructureRule ) schemaObject;
769 
770                     Entry ditStructureRuleEntry = factory.convert( ditStructureRule, schema, null );
771 
772                     ditStructureRuleEntries.add( ditStructureRuleEntry );
773                 }
774             }
775         }
776 
777         return ditStructureRuleEntries;
778     }
779 
780 
781     /**
782      * {@inheritDoc}
783      */
784     @Override
785     public List<Entry> loadMatchingRuleUses( Schema... schemas ) throws LdapException, IOException
786     {
787         List<Entry> matchingRuleUseEntries = new ArrayList<>();
788 
789         if ( schemas == null )
790         {
791             return matchingRuleUseEntries;
792         }
793 
794         AttributesFactory factory = new AttributesFactory();
795 
796         for ( Schema schema : schemas )
797         {
798             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
799 
800             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
801             {
802                 SchemaObject schemaObject = schemaObjectWrapper.get();
803 
804                 if ( schemaObject instanceof MatchingRuleUse )
805                 {
806                     MatchingRuleUse matchingRuleUse = ( MatchingRuleUse ) schemaObject;
807 
808                     Entry matchingRuleUseEntry = factory.convert( matchingRuleUse, schema, null );
809 
810                     matchingRuleUseEntries.add( matchingRuleUseEntry );
811                 }
812             }
813         }
814 
815         return matchingRuleUseEntries;
816     }
817 
818 
819     /**
820      * {@inheritDoc}
821      */
822     @Override
823     public List<Entry> loadMatchingRules( Schema... schemas ) throws LdapException, IOException
824     {
825         List<Entry> matchingRuleEntries = new ArrayList<>();
826 
827         if ( schemas == null )
828         {
829             return matchingRuleEntries;
830         }
831 
832         AttributesFactory factory = new AttributesFactory();
833 
834         for ( Schema schema : schemas )
835         {
836             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
837 
838             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
839             {
840                 SchemaObject schemaObject = schemaObjectWrapper.get();
841 
842                 if ( schemaObject instanceof MatchingRule )
843                 {
844                     MatchingRule matchingRule = ( MatchingRule ) schemaObject;
845 
846                     Entry matchingRuleEntry = factory.convert( matchingRule, schema, null );
847 
848                     matchingRuleEntries.add( matchingRuleEntry );
849                 }
850             }
851         }
852 
853         return matchingRuleEntries;
854     }
855 
856 
857     /**
858      * {@inheritDoc}
859      */
860     @Override
861     public List<Entry> loadNameForms( Schema... schemas ) throws LdapException, IOException
862     {
863         List<Entry> nameFormEntries = new ArrayList<>();
864 
865         if ( schemas == null )
866         {
867             return nameFormEntries;
868         }
869 
870         AttributesFactory factory = new AttributesFactory();
871 
872         for ( Schema schema : schemas )
873         {
874             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
875 
876             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
877             {
878                 SchemaObject schemaObject = schemaObjectWrapper.get();
879 
880                 if ( schemaObject instanceof NameForm )
881                 {
882                     NameForm nameForm = ( NameForm ) schemaObject;
883 
884                     Entry nameFormEntry = factory.convert( nameForm, schema, null );
885 
886                     nameFormEntries.add( nameFormEntry );
887                 }
888             }
889         }
890 
891         return nameFormEntries;
892     }
893 
894 
895     /**
896      * {@inheritDoc}
897      */
898     @Override
899     public List<Entry> loadNormalizers( Schema... schemas ) throws LdapException, IOException
900     {
901         List<Entry> normalizerEntries = new ArrayList<>();
902 
903         if ( schemas == null )
904         {
905             return normalizerEntries;
906         }
907 
908         for ( Schema schema : schemas )
909         {
910             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
911 
912             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
913             {
914                 SchemaObject schemaObject = schemaObjectWrapper.get();
915 
916                 if ( schemaObject instanceof NormalizerDescription )
917                 {
918                     NormalizerDescription normalizerDescription = ( NormalizerDescription ) schemaObject;
919                     Entry normalizerEntry = getEntry( normalizerDescription );
920 
921                     normalizerEntries.add( normalizerEntry );
922                 }
923             }
924         }
925 
926         return normalizerEntries;
927     }
928 
929 
930     /**
931      * {@inheritDoc}
932      */
933     @Override
934     public List<Entry> loadObjectClasses( Schema... schemas ) throws LdapException, IOException
935     {
936         List<Entry> objectClassEntries = new ArrayList<>();
937 
938         if ( schemas == null )
939         {
940             return objectClassEntries;
941         }
942 
943         AttributesFactory factory = new AttributesFactory();
944 
945         for ( Schema schema : schemas )
946         {
947             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
948 
949             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
950             {
951                 SchemaObject schemaObject = schemaObjectWrapper.get();
952 
953                 if ( schemaObject instanceof ObjectClass )
954                 {
955                     ObjectClass objectClass = ( ObjectClass ) schemaObject;
956 
957                     Entry objectClassEntry = factory.convert( objectClass, schema, null );
958 
959                     objectClassEntries.add( objectClassEntry );
960                 }
961             }
962         }
963 
964         return objectClassEntries;
965     }
966 
967 
968     /**
969      * {@inheritDoc}
970      */
971     @Override
972     public List<Entry> loadSyntaxCheckers( Schema... schemas ) throws LdapException, IOException
973     {
974         List<Entry> syntaxCheckerEntries = new ArrayList<>();
975 
976         if ( schemas == null )
977         {
978             return syntaxCheckerEntries;
979         }
980 
981         for ( Schema schema : schemas )
982         {
983             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
984 
985             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
986             {
987                 SchemaObject schemaObject = schemaObjectWrapper.get();
988 
989                 if ( schemaObject instanceof SyntaxCheckerDescription )
990                 {
991                     SyntaxCheckerDescription syntaxCheckerDescription = ( SyntaxCheckerDescription ) schemaObject;
992                     Entry syntaxCheckerEntry = getEntry( syntaxCheckerDescription );
993 
994                     syntaxCheckerEntries.add( syntaxCheckerEntry );
995                 }
996             }
997         }
998 
999         return syntaxCheckerEntries;
1000     }
1001 
1002 
1003     /**
1004      * {@inheritDoc}
1005      */
1006     @Override
1007     public List<Entry> loadSyntaxes( Schema... schemas ) throws LdapException, IOException
1008     {
1009         List<Entry> syntaxEntries = new ArrayList<>();
1010 
1011         if ( schemas == null )
1012         {
1013             return syntaxEntries;
1014         }
1015 
1016         AttributesFactory factory = new AttributesFactory();
1017 
1018         for ( Schema schema : schemas )
1019         {
1020             Set<SchemaObjectWrapper> schemaObjectWrappers = schema.getContent();
1021 
1022             for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjectWrappers )
1023             {
1024                 SchemaObject schemaObject = schemaObjectWrapper.get();
1025 
1026                 if ( schemaObject instanceof LdapSyntax )
1027                 {
1028                     LdapSyntax ldapSyntax = ( LdapSyntax ) schemaObject;
1029 
1030                     Entry ldapSyntaxEntry = factory.convert( ldapSyntax, schema, null );
1031 
1032                     syntaxEntries.add( ldapSyntaxEntry );
1033                 }
1034             }
1035         }
1036 
1037         return syntaxEntries;
1038     }
1039 
1040 
1041     private Entry getEntry( LdapComparatorDescription comparatorDescription )
1042     {
1043         Entry entry = new DefaultEntry();
1044 
1045         entry.put( SchemaConstants.OBJECT_CLASS_AT,
1046             SchemaConstants.TOP_OC,
1047             MetaSchemaConstants.META_TOP_OC,
1048             MetaSchemaConstants.META_COMPARATOR_OC );
1049 
1050         entry.put( MetaSchemaConstants.M_OID_AT, comparatorDescription.getOid() );
1051         entry.put( MetaSchemaConstants.M_FQCN_AT, comparatorDescription.getFqcn() );
1052 
1053         if ( comparatorDescription.getBytecode() != null )
1054         {
1055             entry.put( MetaSchemaConstants.M_BYTECODE_AT,
1056                 Base64.decode( comparatorDescription.getBytecode().toCharArray() ) );
1057         }
1058 
1059         if ( comparatorDescription.getDescription() != null )
1060         {
1061             entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, comparatorDescription.getDescription() );
1062         }
1063 
1064         return entry;
1065     }
1066 
1067 
1068     private Entry getEntry( SyntaxCheckerDescription syntaxCheckerDescription )
1069     {
1070         Entry entry = new DefaultEntry();
1071 
1072         entry.put( SchemaConstants.OBJECT_CLASS_AT,
1073             SchemaConstants.TOP_OC,
1074             MetaSchemaConstants.META_TOP_OC,
1075             MetaSchemaConstants.META_SYNTAX_CHECKER_OC );
1076 
1077         entry.put( MetaSchemaConstants.M_OID_AT, syntaxCheckerDescription.getOid() );
1078         entry.put( MetaSchemaConstants.M_FQCN_AT, syntaxCheckerDescription.getFqcn() );
1079 
1080         if ( syntaxCheckerDescription.getBytecode() != null )
1081         {
1082             entry.put( MetaSchemaConstants.M_BYTECODE_AT,
1083                 Base64.decode( syntaxCheckerDescription.getBytecode().toCharArray() ) );
1084         }
1085 
1086         if ( syntaxCheckerDescription.getDescription() != null )
1087         {
1088             entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, syntaxCheckerDescription.getDescription() );
1089         }
1090 
1091         return entry;
1092     }
1093 
1094 
1095     private Entry getEntry( NormalizerDescription normalizerDescription )
1096     {
1097         Entry entry = new DefaultEntry();
1098 
1099         entry.put( SchemaConstants.OBJECT_CLASS_AT,
1100             SchemaConstants.TOP_OC,
1101             MetaSchemaConstants.META_TOP_OC,
1102             MetaSchemaConstants.META_NORMALIZER_OC );
1103 
1104         entry.put( MetaSchemaConstants.M_OID_AT, normalizerDescription.getOid() );
1105         entry.put( MetaSchemaConstants.M_FQCN_AT, normalizerDescription.getFqcn() );
1106 
1107         if ( normalizerDescription.getBytecode() != null )
1108         {
1109             entry.put( MetaSchemaConstants.M_BYTECODE_AT,
1110                 Base64.decode( normalizerDescription.getBytecode().toCharArray() ) );
1111         }
1112 
1113         if ( normalizerDescription.getDescription() != null )
1114         {
1115             entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, normalizerDescription.getDescription() );
1116         }
1117 
1118         return entry;
1119     }
1120 
1121 
1122     /**
1123      * Sets the quirks mode for all the internal parsers.
1124      *
1125      * If enabled the parser accepts non-numeric OIDs and some
1126      * special characters in descriptions.
1127      *
1128      * @param enabled the new quirks mode
1129      */
1130     public void setQuirksMode( boolean enabled )
1131     {
1132         AT_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1133         C_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1134         DCR_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1135         DSR_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1136         LS_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1137         MR_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1138         MRU_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1139         N_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1140         NF_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1141         OC_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1142         SC_DESCR_SCHEMA_PARSER.setQuirksMode( enabled );
1143     }
1144 }