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