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  package org.apache.directory.api.ldap.schema.loader;
21  
22  
23  import java.io.File;
24  import java.io.FileNotFoundException;
25  import java.io.FilenameFilter;
26  import java.io.IOException;
27  import java.util.ArrayList;
28  import java.util.List;
29  
30  import org.apache.directory.api.i18n.I18n;
31  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
32  import org.apache.directory.api.ldap.model.entry.Entry;
33  import org.apache.directory.api.ldap.model.exception.LdapException;
34  import org.apache.directory.api.ldap.model.ldif.LdifEntry;
35  import org.apache.directory.api.ldap.model.ldif.LdifReader;
36  import org.apache.directory.api.ldap.model.schema.registries.AbstractSchemaLoader;
37  import org.apache.directory.api.ldap.model.schema.registries.Schema;
38  import org.apache.directory.api.util.Strings;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  
43  /**
44   * Loads schema data from LDIF files containing entries representing schema
45   * objects, using the meta schema format.
46   *
47   * This class is used only for tests.
48   * 
49   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
50   */
51  public class LdifSchemaLoader extends AbstractSchemaLoader
52  {
53      /** ldif file extension used */
54      private static final String LDIF_EXT = "ldif";
55  
56      /** ou=schema LDIF file name */
57      private static final String OU_SCHEMA_LDIF = "ou=schema." + LDIF_EXT;
58  
59      /** static class logger */
60      private static final Logger LOG = LoggerFactory.getLogger( LdifSchemaLoader.class );
61  
62      /** directory containing the schema LDIF file for ou=schema */
63      private final File baseDirectory;
64  
65      /** a filter for listing all the LDIF files within a directory */
66      private final FilenameFilter ldifFilter = new FilenameFilter()
67      {
68          @Override
69          public boolean accept( File file, String name )
70          {
71              return name.endsWith( LDIF_EXT );
72          }
73      };
74  
75  
76      /**
77       * Creates a new LDIF based SchemaLoader. The constructor checks to make
78       * sure the supplied base directory exists and contains a schema.ldif file
79       * and if not complains about it.
80       *
81       * @param baseDirectory the schema LDIF base directory
82       * @throws LdapException if the base directory does not exist or does not
83       * a valid schema.ldif file
84       * @throws IOException If we can't load the schema
85       */
86      public LdifSchemaLoader( File baseDirectory ) throws LdapException, IOException
87      {
88          this.baseDirectory = baseDirectory;
89  
90          if ( !baseDirectory.exists() )
91          {
92              String msg = I18n.err( I18n.ERR_16046_BASE_DIR_DOES_NOT_EXIST, baseDirectory.getAbsolutePath() );
93              LOG.error( msg );
94              throw new IllegalArgumentException( msg );
95          }
96  
97          File schemaLdif = new File( baseDirectory, OU_SCHEMA_LDIF );
98  
99          if ( !schemaLdif.exists() )
100         {
101             String msg = I18n.err( I18n.ERR_16010_NO_SHEMA_FILE, schemaLdif.getAbsolutePath() );
102             LOG.error( msg );
103             throw new FileNotFoundException( msg );
104         }
105 
106         if ( LOG.isDebugEnabled() )
107         {
108             LOG.debug( I18n.msg( I18n.MSG_16010_USING_BASE_SCHEMA_DIR, baseDirectory ) );
109         }
110 
111         initializeSchemas();
112     }
113 
114 
115     /**
116      * Scans for LDIF files just describing the various schema contained in
117      * the schema repository.
118      *
119      * @throws LdapException if the schemas can't be initialized
120      * @throws IOException If teh schema can't be read
121      */
122     private void initializeSchemas() throws LdapException, IOException
123     {
124         if ( LOG.isDebugEnabled() )
125         {
126             LOG.debug( I18n.msg( I18n.MSG_16006_INITIALIZING_SCHEMA ) );
127         }
128 
129         File schemaDirectory = new File( baseDirectory, SchemaConstants.OU_SCHEMA );
130         String[] ldifFiles = schemaDirectory.list( ldifFilter );
131 
132         if ( ldifFiles != null )
133         {
134             for ( String ldifFile : ldifFiles )
135             {
136                 File file = new File( schemaDirectory, ldifFile );
137 
138                 try ( LdifReader reader = new LdifReader( file ) )
139                 {
140                     
141                     LdifEntry entry = reader.next();
142                     Schema schema = getSchema( entry.getEntry() );
143 
144                     if ( schema == null )
145                     {
146                         // The entry was not a schema, skip it
147                         continue;
148                     }
149 
150                     schemaMap.put( schema.getSchemaName(), schema );
151 
152                     if ( LOG.isDebugEnabled() )
153                     {
154                         LOG.debug( I18n.msg( I18n.MSG_16007_SCHEMA_INITIALIZED, schema ) );
155                     }
156                 }
157                 catch ( LdapException e )
158                 {
159                     LOG.error( I18n.err( I18n.ERR_16009_LDIF_LOAD_FAIL, ldifFile ), e );
160                     throw e;
161                 }
162             }
163         }
164     }
165 
166 
167     /**
168      * Utility method to get the file for a schema directory.
169      *
170      * @param schema the schema to get the file for
171      * @return the file for the specific schema directory
172      */
173     private File getSchemaDirectory( Schema schema )
174     {
175         return new File( new File( baseDirectory, SchemaConstants.OU_SCHEMA ), "cn="
176             + Strings.lowerCase( schema.getSchemaName() ) );
177     }
178 
179 
180     /**
181      * {@inheritDoc}
182      */
183     @Override
184     public List<Entry> loadComparators( Schema... schemas ) throws LdapException, IOException
185     {
186         List<Entry> comparatorList = new ArrayList<>();
187 
188         if ( schemas == null )
189         {
190             return comparatorList;
191         }
192 
193         for ( Schema schema : schemas )
194         {
195             File comparatorsDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.COMPARATORS_PATH );
196 
197             if ( !comparatorsDirectory.exists() )
198             {
199                 return comparatorList;
200             }
201 
202             File[] comparators = comparatorsDirectory.listFiles( ldifFilter );
203 
204             if ( comparators != null )
205             {
206                 for ( File ldifFile : comparators )
207                 {
208                     try ( LdifReader reader = new LdifReader( ldifFile ) )
209                     {
210                         LdifEntry entry = reader.next();
211                         comparatorList.add( entry.getEntry() );
212                     }
213                 }
214             }
215         }
216 
217         return comparatorList;
218     }
219 
220 
221     /**
222      * {@inheritDoc}
223      */
224     @Override
225     public List<Entry> loadSyntaxCheckers( Schema... schemas ) throws LdapException, IOException
226     {
227         List<Entry> syntaxCheckerList = new ArrayList<>();
228 
229         if ( schemas == null )
230         {
231             return syntaxCheckerList;
232         }
233 
234         for ( Schema schema : schemas )
235         {
236             File syntaxCheckersDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.SYNTAX_CHECKERS_PATH );
237 
238             if ( !syntaxCheckersDirectory.exists() )
239             {
240                 return syntaxCheckerList;
241             }
242 
243             File[] syntaxCheckerFiles = syntaxCheckersDirectory.listFiles( ldifFilter );
244 
245             if ( syntaxCheckerFiles != null )
246             {
247                 for ( File ldifFile : syntaxCheckerFiles )
248                 {
249                     try ( LdifReader reader = new LdifReader( ldifFile ) )
250                     {
251                         LdifEntry entry = reader.next();
252                         syntaxCheckerList.add( entry.getEntry() );
253                     }
254                 }
255             }
256         }
257 
258         return syntaxCheckerList;
259     }
260 
261 
262     /**
263      * {@inheritDoc}
264      */
265     @Override
266     public List<Entry> loadNormalizers( Schema... schemas ) throws LdapException, IOException
267     {
268         List<Entry> normalizerList = new ArrayList<>();
269 
270         if ( schemas == null )
271         {
272             return normalizerList;
273         }
274 
275         for ( Schema schema : schemas )
276         {
277             File normalizersDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.NORMALIZERS_PATH );
278 
279             if ( !normalizersDirectory.exists() )
280             {
281                 return normalizerList;
282             }
283 
284             File[] normalizerFiles = normalizersDirectory.listFiles( ldifFilter );
285 
286             if ( normalizerFiles != null )
287             {
288                 for ( File ldifFile : normalizerFiles )
289                 {
290                     try ( LdifReader reader = new LdifReader( ldifFile ) )
291                     {
292                         LdifEntry entry = reader.next();
293                         normalizerList.add( entry.getEntry() );
294                     }
295                 }
296             }
297         }
298 
299         return normalizerList;
300     }
301 
302 
303     /**
304      * {@inheritDoc}
305      */
306     @Override
307     public List<Entry> loadMatchingRules( Schema... schemas ) throws LdapException, IOException
308     {
309         List<Entry> matchingRuleList = new ArrayList<>();
310 
311         if ( schemas == null )
312         {
313             return matchingRuleList;
314         }
315 
316         for ( Schema schema : schemas )
317         {
318             File matchingRulesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.MATCHING_RULES_PATH );
319 
320             if ( !matchingRulesDirectory.exists() )
321             {
322                 return matchingRuleList;
323             }
324 
325             File[] matchingRuleFiles = matchingRulesDirectory.listFiles( ldifFilter );
326 
327             if ( matchingRuleFiles != null )
328             {
329                 for ( File ldifFile : matchingRuleFiles )
330                 {
331                     try ( LdifReader reader = new LdifReader( ldifFile ) )
332                     {
333                         LdifEntry entry = reader.next();
334                         matchingRuleList.add( entry.getEntry() );
335                     }
336                 }
337             }
338         }
339 
340         return matchingRuleList;
341     }
342 
343 
344     /**
345      * {@inheritDoc}
346      */
347     @Override
348     public List<Entry> loadSyntaxes( Schema... schemas ) throws LdapException, IOException
349     {
350         List<Entry> syntaxList = new ArrayList<>();
351 
352         if ( schemas == null )
353         {
354             return syntaxList;
355         }
356 
357         for ( Schema schema : schemas )
358         {
359             File syntaxesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.SYNTAXES_PATH );
360 
361             if ( !syntaxesDirectory.exists() )
362             {
363                 return syntaxList;
364             }
365 
366             File[] syntaxFiles = syntaxesDirectory.listFiles( ldifFilter );
367 
368             if ( syntaxFiles != null )
369             {
370                 for ( File ldifFile : syntaxFiles )
371                 {
372                     try ( LdifReader reader = new LdifReader( ldifFile ) )
373                     {
374                         LdifEntry entry = reader.next();
375                         syntaxList.add( entry.getEntry() );
376                     }
377                 }
378             }
379         }
380 
381         return syntaxList;
382     }
383 
384 
385     /**
386      * {@inheritDoc}
387      */
388     @Override
389     public List<Entry> loadAttributeTypes( Schema... schemas ) throws LdapException, IOException
390     {
391         List<Entry> attributeTypeList = new ArrayList<>();
392 
393         if ( schemas == null )
394         {
395             return attributeTypeList;
396         }
397 
398         for ( Schema schema : schemas )
399         {
400             // check that the attributeTypes directory exists for the schema
401             File attributeTypesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.ATTRIBUTE_TYPES_PATH );
402 
403             if ( !attributeTypesDirectory.exists() )
404             {
405                 return attributeTypeList;
406             }
407 
408             // get list of attributeType LDIF schema files in attributeTypes
409             File[] attributeTypeFiles = attributeTypesDirectory.listFiles( ldifFilter );
410 
411             if ( attributeTypeFiles != null )
412             {
413                 for ( File ldifFile : attributeTypeFiles )
414                 {
415                     try ( LdifReader reader = new LdifReader( ldifFile ) )
416                     {
417                         LdifEntry entry = reader.next();
418                         attributeTypeList.add( entry.getEntry() );
419                     }
420                 }
421             }
422         }
423 
424         return attributeTypeList;
425     }
426 
427 
428     /**
429      * {@inheritDoc}
430      */
431     @Override
432     public List<Entry> loadMatchingRuleUses( Schema... schemas ) throws LdapException, IOException
433     {
434         List<Entry> matchingRuleUseList = new ArrayList<>();
435 
436         if ( schemas == null )
437         {
438             return matchingRuleUseList;
439         }
440 
441         for ( Schema schema : schemas )
442         {
443             File matchingRuleUsesDirectory = new File( getSchemaDirectory( schema ),
444                 SchemaConstants.MATCHING_RULE_USE_PATH );
445 
446             if ( !matchingRuleUsesDirectory.exists() )
447             {
448                 return matchingRuleUseList;
449             }
450 
451             File[] matchingRuleUseFiles = matchingRuleUsesDirectory.listFiles( ldifFilter );
452 
453             if ( matchingRuleUseFiles != null )
454             {
455                 for ( File ldifFile : matchingRuleUseFiles )
456                 {
457                     try ( LdifReader reader = new LdifReader( ldifFile ) )
458                     {
459                         LdifEntry entry = reader.next();
460                         matchingRuleUseList.add( entry.getEntry() );
461                     }
462                 }
463             }
464         }
465 
466         return matchingRuleUseList;
467     }
468 
469 
470     /**
471      * {@inheritDoc}
472      */
473     @Override
474     public List<Entry> loadNameForms( Schema... schemas ) throws LdapException, IOException
475     {
476         List<Entry> nameFormList = new ArrayList<>();
477 
478         if ( schemas == null )
479         {
480             return nameFormList;
481         }
482 
483         for ( Schema schema : schemas )
484         {
485             File nameFormsDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.NAME_FORMS_PATH );
486 
487             if ( !nameFormsDirectory.exists() )
488             {
489                 return nameFormList;
490             }
491 
492             File[] nameFormFiles = nameFormsDirectory.listFiles( ldifFilter );
493 
494             if ( nameFormFiles != null )
495             {
496                 for ( File ldifFile : nameFormFiles )
497                 {
498                     try ( LdifReader reader = new LdifReader( ldifFile ) )
499                     {
500                         LdifEntry entry = reader.next();
501                         nameFormList.add( entry.getEntry() );
502                     }
503                 }
504             }
505         }
506 
507         return nameFormList;
508     }
509 
510 
511     /**
512      * {@inheritDoc}
513      */
514     @Override
515     public List<Entry> loadDitContentRules( Schema... schemas ) throws LdapException, IOException
516     {
517         List<Entry> ditContentRuleList = new ArrayList<>();
518 
519         if ( schemas == null )
520         {
521             return ditContentRuleList;
522         }
523 
524         for ( Schema schema : schemas )
525         {
526             File ditContentRulesDirectory = new File( getSchemaDirectory( schema ),
527                 SchemaConstants.DIT_CONTENT_RULES_PATH );
528 
529             if ( !ditContentRulesDirectory.exists() )
530             {
531                 return ditContentRuleList;
532             }
533 
534             File[] ditContentRuleFiles = ditContentRulesDirectory.listFiles( ldifFilter );
535 
536             if ( ditContentRuleFiles != null )
537             {
538                 for ( File ldifFile : ditContentRuleFiles )
539                 {
540                     try ( LdifReader reader = new LdifReader( ldifFile ) )
541                     {
542                         LdifEntry entry = reader.next();
543                         ditContentRuleList.add( entry.getEntry() );
544                     }
545                 }
546             }
547         }
548 
549         return ditContentRuleList;
550     }
551 
552 
553     /**
554      * {@inheritDoc}
555      */
556     @Override
557     public List<Entry> loadDitStructureRules( Schema... schemas ) throws LdapException, IOException
558     {
559         List<Entry> ditStructureRuleList = new ArrayList<>();
560 
561         if ( schemas == null )
562         {
563             return ditStructureRuleList;
564         }
565 
566         for ( Schema schema : schemas )
567         {
568             File ditStructureRulesDirectory = new File( getSchemaDirectory( schema ),
569                 SchemaConstants.DIT_STRUCTURE_RULES_PATH );
570 
571             if ( !ditStructureRulesDirectory.exists() )
572             {
573                 return ditStructureRuleList;
574             }
575 
576             File[] ditStructureRuleFiles = ditStructureRulesDirectory.listFiles( ldifFilter );
577 
578             if ( ditStructureRuleFiles != null )
579             {
580                 for ( File ldifFile : ditStructureRuleFiles )
581                 {
582                     try ( LdifReader reader = new LdifReader( ldifFile ) )
583                     {
584                         LdifEntry entry = reader.next();
585                         ditStructureRuleList.add( entry.getEntry() );
586                     }
587                 }
588             }
589         }
590 
591         return ditStructureRuleList;
592     }
593 
594 
595     /**
596      * {@inheritDoc}
597      */
598     @Override
599     public List<Entry> loadObjectClasses( Schema... schemas ) throws LdapException, IOException
600     {
601         List<Entry> objectClassList = new ArrayList<>();
602 
603         if ( schemas == null )
604         {
605             return objectClassList;
606         }
607 
608         for ( Schema schema : schemas )
609         {
610             // get objectClasses directory, check if exists, return if not
611             File objectClassesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.OBJECT_CLASSES_PATH );
612 
613             if ( !objectClassesDirectory.exists() )
614             {
615                 return objectClassList;
616             }
617 
618             // get list of objectClass LDIF files from directory and load
619             File[] objectClassFiles = objectClassesDirectory.listFiles( ldifFilter );
620 
621             if ( objectClassFiles != null )
622             {
623                 for ( File ldifFile : objectClassFiles )
624                 {
625                     try ( LdifReader reader = new LdifReader( ldifFile ) )
626                     {
627                         LdifEntry entry = reader.next();
628                         objectClassList.add( entry.getEntry() );
629                     }
630                 }
631             }
632         }
633 
634         return objectClassList;
635     }
636 }