001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License.
018     *
019     */
020    package org.apache.directory.shared.ldap.schema.loader.ldif;
021    
022    
023    import java.io.File;
024    import java.io.InputStream;
025    import java.net.URL;
026    import java.util.ArrayList;
027    import java.util.List;
028    import java.util.Map;
029    import java.util.regex.Pattern;
030    
031    import org.apache.directory.shared.i18n.I18n;
032    import org.apache.directory.shared.ldap.constants.SchemaConstants;
033    import org.apache.directory.shared.ldap.entry.Entry;
034    import org.apache.directory.shared.ldap.ldif.LdifEntry;
035    import org.apache.directory.shared.ldap.ldif.LdifReader;
036    import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.ResourceMap;
037    import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.DefaultSchemaLdifExtractor;
038    import org.apache.directory.shared.ldap.schema.registries.AbstractSchemaLoader;
039    import org.apache.directory.shared.ldap.schema.registries.Schema;
040    import org.slf4j.Logger;
041    import org.slf4j.LoggerFactory;
042    
043    
044    /**
045     * Loads schema data from LDIF files containing entries representing schema
046     * objects, using the meta schema format.
047     * 
048     * This class is used only for tests.
049     *
050     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
051     * @version $Revision$
052     */
053    public class JarLdifSchemaLoader extends AbstractSchemaLoader
054    {
055        /** ldif file extension used */
056        private static final String LDIF_EXT = "ldif";
057        
058        /** static class logger */
059        private static final Logger LOG = LoggerFactory.getLogger( JarLdifSchemaLoader.class );
060    
061        /** Speedup for DEBUG mode */
062        private static final boolean IS_DEBUG = LOG.isDebugEnabled();
063    
064        /** a map of all the resources in this jar */
065        private static final Map<String,Boolean> RESOURCE_MAP = ResourceMap.getResources( Pattern.compile( ".*schema/ou=schema.*" ) );
066    
067        
068        /**
069         * Creates a new LDIF based SchemaLoader. The constructor checks to make
070         * sure the supplied base directory exists and contains a schema.ldif file
071         * and if not complains about it.
072         *
073         * @throws Exception if the base directory does not exist or does not
074         * a valid schema.ldif file
075         */
076        public JarLdifSchemaLoader() throws Exception
077        {
078            initializeSchemas();
079        }
080    
081        
082        private final URL getResource( String resource, String msg ) throws Exception
083        {
084            if ( RESOURCE_MAP.get( resource ) )
085            {
086                return DefaultSchemaLdifExtractor.getUniqueResource( resource, msg );
087            }
088            else
089            {
090                return new File( resource ).toURI().toURL();
091            }
092        }
093        
094    
095        /**
096         * Scans for LDIF files just describing the various schema contained in
097         * the schema repository.
098         *
099         * @throws Exception
100         */
101        private void initializeSchemas() throws Exception
102        {
103            if ( IS_DEBUG )
104            {
105                LOG.debug( "Initializing schema" );
106            }
107            
108            for ( String file : RESOURCE_MAP.keySet() )
109            {
110                Pattern pat = Pattern.compile( ".*schema/ou=schema/cn=[a-z0-9-_]*\\." + LDIF_EXT );
111                
112                if ( pat.matcher( file ).matches() )
113                {
114                    URL resource = getResource( file, "schema LDIF file" );
115                    InputStream in = resource.openStream();
116                    
117                    try
118                    {
119                        LdifReader reader = new LdifReader( in );
120                        LdifEntry entry = reader.next();
121                        reader.close();
122                        Schema schema = getSchema( entry.getEntry() );
123                        schemaMap.put( schema.getSchemaName(), schema );
124                        
125                        if ( IS_DEBUG )
126                        {
127                            LOG.debug( "Schema Initialized ... \n{}", schema );
128                        }
129                    }
130                    catch ( Exception e )
131                    {
132                        LOG.error( I18n.err( I18n.ERR_10003, file ), e );
133                        throw e;
134                    }
135                    finally
136                    {
137                        in.close();
138                    }
139                }
140            }
141        }
142    
143    
144        /**
145         * Utility method to get the path for a schema directory.
146         *
147         * @param schema the schema to get the path for
148         * @return the path for the specific schema directory
149         */
150        private final String getSchemaDirectory( Schema schema )
151        {
152            return "schema/ou=schema/cn=" + schema.getSchemaName();
153        }
154        
155        
156        /**
157         * {@inheritDoc}
158         */
159        public List<Entry> loadComparators( Schema... schemas ) throws Exception
160        {
161            List<Entry> comparatorList = new ArrayList<Entry>();
162            
163            if ( schemas == null )
164            {
165                return comparatorList;
166            }
167            
168            for ( Schema schema : schemas )
169            {
170                String comparatorsDirectory = getSchemaDirectory( schema ) 
171                    + "/" + SchemaConstants.COMPARATORS_PATH;
172                
173                for ( String resourcePath : RESOURCE_MAP.keySet() )
174                {
175                    Pattern regex = Pattern.compile( ".*" + comparatorsDirectory + "/m-oid=.*\\." + LDIF_EXT );
176                    
177                    if ( regex.matcher( resourcePath ).matches() )
178                    {
179                        URL resource = getResource( resourcePath, "comparator LDIF file" );
180                        LdifReader reader = new LdifReader( resource.openStream() );
181                        LdifEntry entry = reader.next();
182                        reader.close();
183        
184                        comparatorList.add( entry.getEntry() );
185                    }
186                }
187            }
188            
189            return comparatorList;
190        }
191        
192        
193        /**
194         * {@inheritDoc}
195         */
196        public List<Entry> loadSyntaxCheckers( Schema... schemas ) throws Exception
197        {
198            List<Entry> syntaxCheckerList = new ArrayList<Entry>();
199            
200            if ( schemas == null )
201            {
202                return syntaxCheckerList;
203            }
204            
205            for ( Schema schema : schemas )
206            {
207                String syntaxCheckersDirectory = getSchemaDirectory( schema ) 
208                    +  "/" + SchemaConstants.SYNTAX_CHECKERS_PATH;
209        
210                for ( String resourcePath : RESOURCE_MAP.keySet() )
211                {
212                    Pattern regex = Pattern.compile( ".*" + syntaxCheckersDirectory + "/m-oid=.*\\." + LDIF_EXT );
213                    
214                    if ( regex.matcher( resourcePath ).matches() )
215                    {
216                        URL resource = getResource( resourcePath, "syntaxChecker LDIF file" );
217                        LdifReader reader = new LdifReader( resource.openStream() );
218                        LdifEntry entry = reader.next();
219                        reader.close();
220                        
221                        syntaxCheckerList.add( entry.getEntry() );
222                    }
223                }
224            }
225            
226            return syntaxCheckerList;
227        }
228        
229        
230        /**
231         * {@inheritDoc}
232         */
233        public List<Entry> loadNormalizers( Schema... schemas ) throws Exception
234        {
235            List<Entry> normalizerList = new ArrayList<Entry>();
236            
237            if ( schemas == null )
238            {
239                return normalizerList;
240            }
241            
242            for ( Schema schema : schemas )
243            {
244                String normalizersDirectory = getSchemaDirectory( schema )
245                    + "/" + SchemaConstants.NORMALIZERS_PATH;
246        
247                for ( String resourcePath : RESOURCE_MAP.keySet() )
248                {
249                    Pattern regex = Pattern.compile( ".*" + normalizersDirectory + "/m-oid=.*\\." + LDIF_EXT );
250                    
251                    if ( regex.matcher( resourcePath ).matches() )
252                    {
253                        URL resource = getResource( resourcePath, "normalizer LDIF file" );
254                        LdifReader reader = new LdifReader( resource.openStream() );
255                        LdifEntry entry = reader.next();
256                        reader.close();
257                        
258                        normalizerList.add( entry.getEntry() );
259                    }
260                }
261            }
262            
263            return normalizerList;
264        }
265        
266        
267        /**
268         * {@inheritDoc}
269         */
270        public List<Entry> loadMatchingRules( Schema... schemas ) throws Exception
271        {
272            List<Entry> matchingRuleList = new ArrayList<Entry>();
273            
274            if ( schemas == null )
275            {
276                return matchingRuleList;
277            }
278            
279            for ( Schema schema : schemas )
280            {
281                String matchingRulesDirectory = getSchemaDirectory( schema )
282                    + "/" + SchemaConstants.MATCHING_RULES_PATH;
283                
284                for ( String resourcePath : RESOURCE_MAP.keySet() )
285                {
286                    Pattern regex = Pattern.compile( ".*" + matchingRulesDirectory + "/m-oid=.*\\." + LDIF_EXT );
287                    
288                    if ( regex.matcher( resourcePath ).matches() )
289                    {
290                        URL resource = getResource( resourcePath, "matchingRules LDIF file" );
291                        LdifReader reader = new LdifReader( resource.openStream() );
292                        LdifEntry entry = reader.next();
293                        reader.close();
294        
295                        matchingRuleList.add( entry.getEntry() );
296                    }
297                }
298            }
299            
300            return matchingRuleList;
301        }
302        
303        
304        /**
305         * {@inheritDoc}
306         */
307        public List<Entry> loadSyntaxes( Schema... schemas ) throws Exception
308        {
309            List<Entry> syntaxList = new ArrayList<Entry>();
310            
311            if ( schemas == null )
312            {
313                return syntaxList;
314            }
315            
316            for ( Schema schema : schemas )
317            {
318                String syntaxesDirectory = getSchemaDirectory( schema )
319                    + "/" + SchemaConstants.SYNTAXES_PATH;
320        
321                for ( String resourcePath : RESOURCE_MAP.keySet() )
322                {
323                    Pattern regex = Pattern.compile( ".*" + syntaxesDirectory + "/m-oid=.*\\." + LDIF_EXT );
324                    
325                    if ( regex.matcher( resourcePath ).matches() )
326                    {
327                        URL resource = getResource( resourcePath, "syntax LDIF file" );
328                        LdifReader reader = new LdifReader( resource.openStream() );
329                        LdifEntry entry = reader.next();
330                        reader.close();
331                        
332                        syntaxList.add( entry.getEntry() );
333                    }
334                }
335            }
336            
337            return syntaxList;
338        }
339    
340        
341        /**
342         * {@inheritDoc}
343         */
344        public List<Entry> loadAttributeTypes( Schema... schemas ) throws Exception
345        {
346            List<Entry> attributeTypeList = new ArrayList<Entry>();
347    
348            if ( schemas == null )
349            {
350                return attributeTypeList;
351            }
352            
353            for ( Schema schema : schemas )
354            {
355                    // check that the attributeTypes directory exists for the schema
356                String attributeTypesDirectory = getSchemaDirectory( schema )
357                    + "/" + SchemaConstants.ATTRIBUTES_TYPE_PATH;
358                
359                // get list of attributeType LDIF schema files in attributeTypes
360                for ( String resourcePath : RESOURCE_MAP.keySet() )
361                {
362                    Pattern regex = Pattern.compile( ".*" + attributeTypesDirectory + "/m-oid=.*\\." + LDIF_EXT );
363                    
364                    if ( regex.matcher( resourcePath ).matches() )
365                    {
366                        URL resource = getResource( resourcePath, "attributeType LDIF file" );
367                        LdifReader reader = new LdifReader( resource.openStream() );
368                        LdifEntry entry = reader.next();
369                        reader.close();
370        
371                        attributeTypeList.add( entry.getEntry() );
372                    }
373                }
374            }
375            
376            return attributeTypeList;
377        }
378    
379    
380        /**
381         * {@inheritDoc}
382         */
383        public List<Entry> loadMatchingRuleUses( Schema... schemas ) throws Exception
384        {
385            List<Entry> matchingRuleUseList = new ArrayList<Entry>();
386            
387            if ( schemas == null )
388            {
389                return matchingRuleUseList;
390            }
391            
392            for ( Schema schema : schemas )
393            {
394                String matchingRuleUsesDirectory = getSchemaDirectory( schema )
395                    + "/" + SchemaConstants.MATCHING_RULE_USE_PATH;
396                
397                for ( String resourcePath : RESOURCE_MAP.keySet() )
398                {
399                    Pattern regex = Pattern.compile( ".*" + matchingRuleUsesDirectory + "/m-oid=.*\\." + LDIF_EXT );
400                    
401                    if ( regex.matcher( resourcePath ).matches() )
402                    {
403                        URL resource = getResource( resourcePath, "matchingRuleUse LDIF file" );
404                        LdifReader reader = new LdifReader( resource.openStream() );
405                        LdifEntry entry = reader.next();
406                        reader.close();
407        
408                        matchingRuleUseList.add( entry.getEntry() );
409                    }
410                }
411            }
412            
413            return matchingRuleUseList;
414        }
415    
416    
417        /**
418         * {@inheritDoc}
419         */
420        public List<Entry> loadNameForms( Schema... schemas ) throws Exception
421        {
422            List<Entry> nameFormList = new ArrayList<Entry>();
423            
424            if ( schemas == null )
425            {
426                return nameFormList;
427            }
428            
429            for ( Schema schema : schemas )
430            {
431                String nameFormsDirectory = getSchemaDirectory( schema ) + "/" + SchemaConstants.NAME_FORMS_PATH;
432        
433                for ( String resourcePath : RESOURCE_MAP.keySet() )
434                {
435                    Pattern regex = Pattern.compile( ".*" + nameFormsDirectory + "/m-oid=.*\\." + LDIF_EXT );
436                    
437                    if ( regex.matcher( resourcePath ).matches() )
438                    {
439                        URL resource = getResource( resourcePath, "nameForm LDIF file" );
440                        LdifReader reader = new LdifReader( resource.openStream() );
441                        LdifEntry entry = reader.next();
442                        reader.close();
443        
444                        nameFormList.add( entry.getEntry() );
445                    }
446                }
447            }
448            
449            return nameFormList;
450        }
451    
452    
453        /**
454         * {@inheritDoc}
455         */
456        public List<Entry> loadDitContentRules( Schema... schemas ) throws Exception
457        {
458            List<Entry> ditContentRulesList = new ArrayList<Entry>();
459            
460            if ( schemas == null )
461            {
462                return ditContentRulesList;
463            }
464            
465            for ( Schema schema : schemas )
466            {
467                String ditContentRulesDirectory = getSchemaDirectory( schema ) + "/" + 
468                    SchemaConstants.DIT_CONTENT_RULES_PATH;
469        
470                for ( String resourcePath : RESOURCE_MAP.keySet() )
471                {
472                    Pattern regex = Pattern.compile( ".*" + ditContentRulesDirectory + "/m-oid=.*\\." + LDIF_EXT );
473                    
474                    if ( regex.matcher( resourcePath ).matches() )
475                    {
476                        URL resource = getResource( resourcePath, "ditContentRule LDIF file" );
477                        LdifReader reader = new LdifReader( resource.openStream() );
478                        LdifEntry entry = reader.next();
479                        reader.close();
480                        
481                        ditContentRulesList.add( entry.getEntry() );
482                    }
483                }
484            }
485            
486            return ditContentRulesList;
487        }
488    
489    
490        /**
491         * {@inheritDoc}
492         */
493        public List<Entry> loadDitStructureRules( Schema... schemas ) throws Exception
494        {
495            List<Entry> ditStructureRuleList = new ArrayList<Entry>();
496            
497            if ( schemas == null )
498            {
499                return ditStructureRuleList;
500            }
501            
502            for ( Schema schema : schemas )
503            {
504                String ditStructureRulesDirectory = getSchemaDirectory( schema )
505                    + "/" + SchemaConstants.DIT_STRUCTURE_RULES_PATH;
506        
507                for ( String resourcePath : RESOURCE_MAP.keySet() )
508                {
509                    Pattern regex = Pattern.compile( ".*" + ditStructureRulesDirectory + "/m-oid=.*\\." + LDIF_EXT );
510                    
511                    if ( regex.matcher( resourcePath ).matches() )
512                    {
513                        URL resource = getResource( resourcePath, "ditStructureRule LDIF file" );
514                        LdifReader reader = new LdifReader( resource.openStream() );
515                        LdifEntry entry = reader.next();
516                        reader.close();
517                        
518                        ditStructureRuleList.add( entry.getEntry() );
519                    }
520                }
521            }
522            
523            return ditStructureRuleList;
524        }
525    
526    
527        /**
528         * {@inheritDoc}
529         */
530        public List<Entry> loadObjectClasses( Schema... schemas ) throws Exception
531        {
532            List<Entry> objectClassList = new ArrayList<Entry>();
533            
534            if ( schemas == null )
535            {
536                return objectClassList;
537            }
538            
539            for ( Schema schema : schemas )
540            {
541                    // get objectClasses directory, check if exists, return if not
542                    String objectClassesDirectory = getSchemaDirectory( schema ) + "/" + SchemaConstants.OBJECT_CLASSES_PATH;
543        
544                for ( String resourcePath : RESOURCE_MAP.keySet() )
545                {
546                    Pattern regex = Pattern.compile( ".*" + objectClassesDirectory + "/m-oid=.*\\." + LDIF_EXT );
547                    
548                    if ( regex.matcher( resourcePath ).matches() )
549                    {
550                        URL resource = getResource( resourcePath, "objectClass LDIF file" );
551                        LdifReader reader = new LdifReader( resource.openStream() );
552                        LdifEntry entry = reader.next();
553                        reader.close();
554        
555                        objectClassList.add( entry.getEntry() );
556                    }
557                }
558            }
559            
560            return objectClassList;
561        }
562    }