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