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 */
020package org.apache.directory.api.ldap.model.schema.registries;
021
022
023import java.io.IOException;
024import java.util.ArrayList;
025import java.util.Collection;
026import java.util.HashSet;
027import java.util.List;
028import java.util.Map;
029import java.util.Set;
030
031import org.apache.directory.api.i18n.I18n;
032import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
033import org.apache.directory.api.ldap.model.constants.SchemaConstants;
034import org.apache.directory.api.ldap.model.entry.Attribute;
035import org.apache.directory.api.ldap.model.entry.Entry;
036import org.apache.directory.api.ldap.model.entry.Value;
037import org.apache.directory.api.ldap.model.exception.LdapException;
038import org.apache.directory.api.ldap.model.schema.SchemaManager;
039import org.apache.directory.api.util.StringConstants;
040import org.apache.directory.api.util.Strings;
041
042
043/**
044 * An abstract class with a utility method and setListener() implemented.
045 *
046 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
047 */
048public abstract class AbstractSchemaLoader implements SchemaLoader
049{
050    /**
051     * A map of all available schema names to schema objects. This map is
052     * populated when this class is created with all the schemas present in
053     * the LDIF based schema repository.
054     */
055    protected final Map<String, Schema> schemaMap = new LowerCaseKeyMap();
056    
057    /** The flag that tells about the SchemaLoader mode : relaxed or strict */
058    private boolean relaxed;
059
060    /**
061     * {@inheritDoc}
062     */
063    @Override
064    public final Collection<Schema> getAllEnabled()
065    {
066        Collection<Schema> enabledSchemas = new ArrayList<>();
067
068        for ( Schema schema : schemaMap.values() )
069        {
070            if ( schema.isEnabled() )
071            {
072                enabledSchemas.add( schema );
073            }
074        }
075
076        return enabledSchemas;
077    }
078
079
080    /**
081     * {@inheritDoc}
082     */
083    @Override
084    public final Collection<Schema> getAllSchemas()
085    {
086        return schemaMap.values();
087    }
088
089
090    /**
091     * {@inheritDoc}
092     */
093    @Override
094    public Schema getSchema( String schemaName )
095    {
096        return schemaMap.get( Strings.toLowerCaseAscii( schemaName ) );
097    }
098
099
100    /**
101     * {@inheritDoc}
102     */
103    @Override
104    public void addSchema( Schema schema )
105    {
106        schemaMap.put( schema.getSchemaName(), schema );
107    }
108
109
110    /**
111     * {@inheritDoc}
112     */
113    @Override
114    public void removeSchema( Schema schema )
115    {
116        schemaMap.remove( Strings.toLowerCaseAscii( schema.getSchemaName() ) );
117    }
118
119
120    /**
121     * Gets the schema.
122     *
123     * @param entry the entry
124     * @return the schema
125     * @throws LdapException the exception
126     */
127    protected Schema getSchema( Entry entry ) throws LdapException
128    {
129        if ( entry == null )
130        {
131            throw new IllegalArgumentException( I18n.err( I18n.ERR_04261 ) );
132        }
133
134        Attribute objectClasses = entry.get( SchemaConstants.OBJECT_CLASS_AT );
135        boolean isSchema = false;
136
137        for ( Value<?> value : objectClasses )
138        {
139            if ( MetaSchemaConstants.META_SCHEMA_OC.equalsIgnoreCase( value.getString() ) )
140            {
141                isSchema = true;
142                break;
143            }
144        }
145
146        if ( !isSchema )
147        {
148            return null;
149        }
150
151        String name;
152        String owner;
153        String[] dependencies = StringConstants.EMPTY_STRINGS;
154        boolean isDisabled = false;
155
156        if ( entry.get( SchemaConstants.CN_AT ) == null )
157        {
158            throw new IllegalArgumentException( I18n.err( I18n.ERR_04262 ) );
159        }
160
161        name = entry.get( SchemaConstants.CN_AT ).getString();
162
163        Attribute creatorsName = entry.get( SchemaConstants.CREATORS_NAME_AT );
164
165        if ( creatorsName == null )
166        {
167            owner = null;
168        }
169        else
170        {
171            owner = creatorsName.getString();
172        }
173
174        if ( entry.get( MetaSchemaConstants.M_DISABLED_AT ) != null )
175        {
176            String value = entry.get( MetaSchemaConstants.M_DISABLED_AT ).getString();
177            value = Strings.upperCase( value );
178            isDisabled = "TRUE".equals( value );
179        }
180
181        if ( entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT ) != null )
182        {
183            Set<String> depsSet = new HashSet<>();
184            Attribute depsAttr = entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT );
185
186            for ( Value<?> value : depsAttr )
187            {
188                depsSet.add( value.getString() );
189            }
190
191            dependencies = depsSet.toArray( StringConstants.EMPTY_STRINGS );
192        }
193
194        return new DefaultSchema( this, name, owner, dependencies, isDisabled );
195    }
196
197
198    private Schema[] buildSchemaArray( String... schemaNames ) throws LdapException
199    {
200        Schema[] schemas = new Schema[schemaNames.length];
201        int pos = 0;
202
203        for ( String schemaName : schemaNames )
204        {
205            schemas[pos++] = getSchema( schemaName );
206        }
207
208        return schemas;
209    }
210
211
212    /**
213     * {@inheritDoc}
214     */
215    @Override
216    public List<Entry> loadAttributeTypes( String... schemaNames ) throws LdapException, IOException
217    {
218        if ( schemaNames == null )
219        {
220            return new ArrayList<>();
221        }
222
223        return loadAttributeTypes( buildSchemaArray( schemaNames ) );
224    }
225
226
227    /**
228     * {@inheritDoc}
229     */
230    @Override
231    public List<Entry> loadComparators( String... schemaNames ) throws LdapException, IOException
232    {
233        if ( schemaNames == null )
234        {
235            return new ArrayList<>();
236        }
237
238        return loadComparators( buildSchemaArray( schemaNames ) );
239    }
240
241
242    /**
243     * {@inheritDoc}
244     */
245    @Override
246    public List<Entry> loadDitContentRules( String... schemaNames ) throws LdapException, IOException
247    {
248        if ( schemaNames == null )
249        {
250            return new ArrayList<>();
251        }
252
253        return loadDitContentRules( buildSchemaArray( schemaNames ) );
254    }
255
256
257    /**
258     * {@inheritDoc}
259     */
260    @Override
261    public List<Entry> loadDitStructureRules( String... schemaNames ) throws LdapException, IOException
262    {
263        if ( schemaNames == null )
264        {
265            return new ArrayList<>();
266        }
267
268        return loadDitStructureRules( buildSchemaArray( schemaNames ) );
269    }
270
271
272    /**
273     * {@inheritDoc}
274     */
275    @Override
276    public List<Entry> loadMatchingRules( String... schemaNames ) throws LdapException, IOException
277    {
278        if ( schemaNames == null )
279        {
280            return new ArrayList<>();
281        }
282
283        return loadMatchingRules( buildSchemaArray( schemaNames ) );
284    }
285
286
287    /**
288     * {@inheritDoc}
289     */
290    @Override
291    public List<Entry> loadMatchingRuleUses( String... schemaNames ) throws LdapException, IOException
292    {
293        if ( schemaNames == null )
294        {
295            return new ArrayList<>();
296        }
297
298        return loadMatchingRuleUses( buildSchemaArray( schemaNames ) );
299    }
300
301
302    /**
303     * {@inheritDoc}
304     */
305    @Override
306    public List<Entry> loadNameForms( String... schemaNames ) throws LdapException, IOException
307    {
308        if ( schemaNames == null )
309        {
310            return new ArrayList<>();
311        }
312
313        return loadNameForms( buildSchemaArray( schemaNames ) );
314    }
315
316
317    /**
318     * {@inheritDoc}
319     */
320    @Override
321    public List<Entry> loadNormalizers( String... schemaNames ) throws LdapException, IOException
322    {
323        if ( schemaNames == null )
324        {
325            return new ArrayList<>();
326        }
327
328        return loadNormalizers( buildSchemaArray( schemaNames ) );
329    }
330
331
332    /**
333     * {@inheritDoc}
334     */
335    @Override
336    public List<Entry> loadObjectClasses( String... schemaNames ) throws LdapException, IOException
337    {
338        if ( schemaNames == null )
339        {
340            return new ArrayList<>();
341        }
342
343        return loadObjectClasses( buildSchemaArray( schemaNames ) );
344    }
345
346
347    /**
348     * {@inheritDoc}
349     */
350    @Override
351    public List<Entry> loadSyntaxes( String... schemaNames ) throws LdapException, IOException
352    {
353        if ( schemaNames == null )
354        {
355            return new ArrayList<>();
356        }
357
358        return loadSyntaxes( buildSchemaArray( schemaNames ) );
359    }
360
361
362    /**
363     * {@inheritDoc}
364     */
365    @Override
366    public List<Entry> loadSyntaxCheckers( String... schemaNames ) throws LdapException, IOException
367    {
368        if ( schemaNames == null )
369        {
370            return new ArrayList<>();
371        }
372
373        return loadSyntaxCheckers( buildSchemaArray( schemaNames ) );
374    }
375
376
377    /**
378     * {@inheritDoc}
379     */
380    @Override
381    public boolean isRelaxed()
382    {
383        return relaxed == SchemaManager.RELAXED;
384    }
385
386
387    /**
388     * {@inheritDoc}
389     */
390    @Override
391    public boolean isStrict()
392    {
393        return relaxed == SchemaManager.STRICT;
394    }
395
396
397    /**
398     * {@inheritDoc}
399     */
400    @Override
401    public void setRelaxed( boolean relaxed )
402    {
403        this.relaxed = relaxed;
404    }
405}