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
021package org.apache.directory.ldap.client.api;
022
023
024import java.io.IOException;
025import java.util.ArrayList;
026import java.util.List;
027
028import org.apache.directory.shared.ldap.model.cursor.EntryCursor;
029import org.apache.directory.shared.ldap.model.entry.Entry;
030import org.apache.directory.shared.ldap.model.exception.LdapException;
031import org.apache.directory.shared.ldap.model.message.SearchScope;
032import org.apache.directory.shared.ldap.model.name.Dn;
033import org.apache.directory.shared.ldap.model.schema.registries.AbstractSchemaLoader;
034import org.apache.directory.shared.ldap.model.schema.registries.Schema;
035import org.slf4j.Logger;
036import org.slf4j.LoggerFactory;
037
038
039/**
040 * A schema loader which uses LdapConnection to load schema.
041 *
042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
043 */
044public class NetworkSchemaLoader extends AbstractSchemaLoader
045{
046    /** the connection to the ldap server */
047    private LdapConnection connection;
048
049    /** the schema base Dn */
050    private static final String SCHEMA_BASE = "ou=schema";
051
052    /** the search filter */
053    private static final String FILTER = "(objectClass=*)";
054
055    /** the logger */
056    private static final Logger LOG = LoggerFactory.getLogger( NetworkSchemaLoader.class );
057
058
059    /**
060     * Creates a new instance of NetworkSchemaLoader.
061     *
062     * @param connection the LDAP connection
063     * @throws Exception if the connection is not authenticated or if there are any problems
064     *                   while loading the schema entries
065     */
066    public NetworkSchemaLoader( LdapConnection connection ) throws Exception
067    {
068        if ( !connection.isAuthenticated() )
069        {
070            throw new IllegalArgumentException( "connection is not authenticated" );
071        }
072
073        this.connection = connection;
074        initializeSchemas();
075    }
076
077
078    private void initializeSchemas() throws Exception
079    {
080        List<Entry> schemaEntries = searchSchemaObjects( SCHEMA_BASE, "(objectClass=metaSchema)" );
081
082        LOG.debug( "initializing schemas {}", schemaEntries );
083        for ( Entry entry : schemaEntries )
084        {
085            Schema schema = getSchema( entry );
086            schemaMap.put( schema.getSchemaName(), schema );
087        }
088    }
089
090
091    /**
092     * searches with ONE LEVEL scope under the given Dn and retrieves all the schema objects
093     * 
094     * @param baseDn the Dn of the schema entry under which the schema objects are present
095     *               e.x ou=attributeTypes,cn=apache,ou=schema
096     * @param filter optional search filter, if null the default fileter {@link #FILTER} is used
097     * @return a list of entries of the schema objects 
098     * @throws LdapException
099     */
100    private List<Entry> searchSchemaObjects( String baseDn, String filter ) throws LdapException
101    {
102        try
103        {
104            LOG.debug( "searching under the dn {} for schema objects", baseDn );
105
106            List<Entry> entries = new ArrayList<Entry>();
107
108            if ( filter == null )
109            {
110                filter = FILTER;
111            }
112
113            EntryCursor cursor = connection.search( new Dn( baseDn ), filter, SearchScope.ONELEVEL, "*", "+" );
114
115            while ( cursor.next() )
116            {
117                Entry entry = cursor.get();
118                entries.add( entry );
119            }
120
121            cursor.close();
122
123            return entries;
124        }
125        catch ( LdapException e )
126        {
127            throw e;
128        }
129        catch ( Exception e )
130        {
131            throw new LdapException( e );
132        }
133    }
134
135
136    /**
137     * @see #searchSchemaObjects(String, String)
138     */
139    private List<Entry> searchSchemaObjects( String baseDn ) throws LdapException
140    {
141        return searchSchemaObjects( baseDn, FILTER );
142    }
143
144
145    /**
146     * {@inheritDoc}
147     */
148    public List<Entry> loadAttributeTypes( Schema... schemas ) throws LdapException, IOException
149    {
150        List<Entry> atEntries = new ArrayList<Entry>();
151
152        for ( Schema s : schemas )
153        {
154            List<Entry> entries = searchSchemaObjects( "ou=attributeTypes,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
155            atEntries.addAll( entries );
156        }
157
158        return atEntries;
159    }
160
161
162    /**
163     * {@inheritDoc}
164     */
165    public List<Entry> loadComparators( Schema... schemas ) throws LdapException, IOException
166    {
167        List<Entry> comparatorsEntries = new ArrayList<Entry>();
168
169        for ( Schema s : schemas )
170        {
171            List<Entry> entries = searchSchemaObjects( "ou=comparators,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
172            comparatorsEntries.addAll( entries );
173        }
174
175        return comparatorsEntries;
176    }
177
178
179    /**
180     * {@inheritDoc}
181     */
182    public List<Entry> loadDitContentRules( Schema... schemas ) throws LdapException, IOException
183    {
184        List<Entry> ditContentRulesEntries = new ArrayList<Entry>();
185
186        for ( Schema s : schemas )
187        {
188            List<Entry> entries = searchSchemaObjects( "ou=ditContentRules,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
189            ditContentRulesEntries.addAll( entries );
190        }
191
192        return ditContentRulesEntries;
193    }
194
195
196    /**
197     * {@inheritDoc}
198     */
199    public List<Entry> loadDitStructureRules( Schema... schemas ) throws LdapException, IOException
200    {
201        List<Entry> ditStructureRulesEntries = new ArrayList<Entry>();
202
203        for ( Schema s : schemas )
204        {
205            List<Entry> entries = searchSchemaObjects( "ou=ditStructureRules,cn=" + s.getSchemaName() + ","
206                + SCHEMA_BASE );
207            ditStructureRulesEntries.addAll( entries );
208        }
209
210        return ditStructureRulesEntries;
211    }
212
213
214    /**
215     * {@inheritDoc}
216     */
217    public List<Entry> loadMatchingRuleUses( Schema... schemas ) throws LdapException, IOException
218    {
219        List<Entry> matchingRuleUsesEntries = new ArrayList<Entry>();
220
221        for ( Schema s : schemas )
222        {
223            List<Entry> entries = searchSchemaObjects( "ou=matchingRuleUse,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
224            matchingRuleUsesEntries.addAll( entries );
225        }
226
227        return matchingRuleUsesEntries;
228    }
229
230
231    /**
232     * {@inheritDoc}
233     */
234    public List<Entry> loadMatchingRules( Schema... schemas ) throws LdapException, IOException
235    {
236        List<Entry> matchingRulesEntries = new ArrayList<Entry>();
237
238        for ( Schema s : schemas )
239        {
240            List<Entry> entries = searchSchemaObjects( "ou=matchingRules,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
241            matchingRulesEntries.addAll( entries );
242        }
243
244        return matchingRulesEntries;
245    }
246
247
248    /**
249     * {@inheritDoc}
250     */
251    public List<Entry> loadNameForms( Schema... schemas ) throws LdapException, IOException
252    {
253        List<Entry> nameFormsEntries = new ArrayList<Entry>();
254
255        for ( Schema s : schemas )
256        {
257            List<Entry> entries = searchSchemaObjects( "ou=nameForms,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
258            nameFormsEntries.addAll( entries );
259        }
260
261        return nameFormsEntries;
262    }
263
264
265    /**
266     * {@inheritDoc}
267     */
268    public List<Entry> loadNormalizers( Schema... schemas ) throws LdapException, IOException
269    {
270        List<Entry> normalizersEntries = new ArrayList<Entry>();
271
272        for ( Schema s : schemas )
273        {
274            List<Entry> entries = searchSchemaObjects( "ou=normalizers,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
275            normalizersEntries.addAll( entries );
276        }
277
278        return normalizersEntries;
279    }
280
281
282    /**
283     * {@inheritDoc}
284     */
285    public List<Entry> loadObjectClasses( Schema... schemas ) throws LdapException, IOException
286    {
287        List<Entry> objectClassesEntries = new ArrayList<Entry>();
288
289        for ( Schema s : schemas )
290        {
291            List<Entry> entries = searchSchemaObjects( "ou=objectClasses,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
292            objectClassesEntries.addAll( entries );
293        }
294
295        return objectClassesEntries;
296    }
297
298
299    /**
300     * {@inheritDoc}
301     */
302    public List<Entry> loadSyntaxCheckers( Schema... schemas ) throws LdapException, IOException
303    {
304        List<Entry> syntaxCheckersEntries = new ArrayList<Entry>();
305
306        for ( Schema s : schemas )
307        {
308            List<Entry> entries = searchSchemaObjects( "ou=syntaxCheckers,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
309            syntaxCheckersEntries.addAll( entries );
310        }
311
312        return syntaxCheckersEntries;
313    }
314
315
316    /**
317     * {@inheritDoc}
318     */
319    public List<Entry> loadSyntaxes( Schema... schemas ) throws LdapException, IOException
320    {
321        List<Entry> syntaxesEntries = new ArrayList<Entry>();
322
323        for ( Schema s : schemas )
324        {
325            List<Entry> entries = searchSchemaObjects( "ou=syntaxes,cn=" + s.getSchemaName() + "," + SCHEMA_BASE );
326            syntaxesEntries.addAll( entries );
327        }
328
329        return syntaxesEntries;
330    }
331
332}