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