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;
021
022
023import java.util.List;
024import java.util.Map;
025
026import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
027import org.apache.directory.api.ldap.model.constants.SchemaConstants;
028import org.apache.directory.api.ldap.model.entry.Attribute;
029import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
030import org.apache.directory.api.ldap.model.entry.DefaultEntry;
031import org.apache.directory.api.ldap.model.entry.Entry;
032import org.apache.directory.api.ldap.model.exception.LdapException;
033import org.apache.directory.api.ldap.model.schema.registries.Schema;
034import org.apache.directory.api.util.DateUtils;
035
036
037/**
038 * A factory that generates an entry using the meta schema for schema
039 * elements.
040 *
041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042 */
043public class AttributesFactory
044{
045    public Entry getAttributes( SchemaObject obj, Schema schema, SchemaManager schemaManager ) throws LdapException
046    {
047        if ( obj instanceof LdapSyntax )
048        {
049            return convert( ( LdapSyntax ) obj, schema, schemaManager );
050        }
051        else if ( obj instanceof MatchingRule )
052        {
053            return convert( ( MatchingRule ) obj, schema, schemaManager );
054        }
055        else if ( obj instanceof AttributeType )
056        {
057            return convert( ( AttributeType ) obj, schema, schemaManager );
058        }
059        else if ( obj instanceof ObjectClass )
060        {
061            return convert( ( ObjectClass ) obj, schema, schemaManager );
062        }
063        else if ( obj instanceof MatchingRuleUse )
064        {
065            return convert( ( MatchingRuleUse ) obj, schema, schemaManager );
066        }
067        else if ( obj instanceof DitStructureRule )
068        {
069            return convert( ( DitStructureRule ) obj, schema, schemaManager );
070        }
071        else if ( obj instanceof DitContentRule )
072        {
073            return convert( ( DitContentRule ) obj, schema, schemaManager );
074        }
075        else if ( obj instanceof NameForm )
076        {
077            return convert( ( NameForm ) obj, schema, schemaManager );
078        }
079
080        throw new IllegalArgumentException( "nknown SchemaObject type: " + obj.getClass() );
081    }
082
083
084    /**
085     * Convert a Schema to Entry
086     * 
087     * @param schema The Schema to convert
088     * @param schemaManager The SchemaManager
089     * @return An Entry containing the converted Schema
090     * @throws LdapException If the conversion failed
091     */
092    public Entry convert( Schema schema, SchemaManager schemaManager ) throws LdapException
093    {
094        Entry entry = new DefaultEntry( schemaManager );
095
096        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_SCHEMA_OC );
097        entry.put( SchemaConstants.CN_AT, schema.getSchemaName() );
098        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
099        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
100
101        if ( schema.isDisabled() )
102        {
103            entry.put( MetaSchemaConstants.M_DISABLED_AT, "TRUE" );
104        }
105
106        String[] dependencies = schema.getDependencies();
107
108        if ( dependencies != null && dependencies.length > 0 )
109        {
110            Attribute attr = new DefaultAttribute(
111                schemaManager.getAttributeType( MetaSchemaConstants.M_DEPENDENCIES_AT ) );
112
113            for ( String dependency : dependencies )
114            {
115                attr.add( dependency );
116            }
117
118            entry.put( attr );
119        }
120
121        return entry;
122    }
123
124
125    public Entry convert( SyntaxChecker syntaxChecker, Schema schema, SchemaManager schemaManager )
126    {
127        Entry entry = new DefaultEntry( schemaManager );
128
129        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_SYNTAX_CHECKER_OC );
130        entry.put( MetaSchemaConstants.M_OID_AT, syntaxChecker.getOid() );
131        entry.put( MetaSchemaConstants.M_FQCN_AT, syntaxChecker.getClass().getName() );
132        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
133        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
134
135        return entry;
136    }
137
138
139    public Entry convert( LdapSyntax syntax, Schema schema, SchemaManager schemaManager ) throws LdapException
140    {
141        Entry entry = new DefaultEntry( schemaManager );
142
143        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_SYNTAX_OC );
144        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
145        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
146        injectCommon( syntax, entry, schemaManager );
147
148        return entry;
149    }
150
151
152    public Entry convert( String oid, Normalizer normalizer, Schema schema, SchemaManager schemaManager )
153    {
154        Entry entry = new DefaultEntry( schemaManager );
155
156        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_NORMALIZER_OC );
157        entry.put( MetaSchemaConstants.M_OID_AT, oid );
158        entry.put( MetaSchemaConstants.M_FQCN_AT, normalizer.getClass().getName() );
159        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
160        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
161        return entry;
162    }
163
164
165    public Entry convert( String oid, LdapComparator<? super Object> comparator, Schema schema,
166        SchemaManager schemaManager )
167    {
168        Entry entry = new DefaultEntry( schemaManager );
169
170        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_COMPARATOR_OC );
171        entry.put( MetaSchemaConstants.M_OID_AT, oid );
172        entry.put( MetaSchemaConstants.M_FQCN_AT, comparator.getClass().getName() );
173        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
174        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
175        return entry;
176    }
177
178
179    /**
180     * 
181     * @param matchingRule
182     * @return Attributes
183     * @throws LdapException
184     */
185    public Entry convert( MatchingRule matchingRule, Schema schema, SchemaManager schemaManager )
186        throws LdapException
187    {
188        Entry entry = new DefaultEntry( schemaManager );
189
190        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_MATCHING_RULE_OC );
191        entry.put( MetaSchemaConstants.M_SYNTAX_AT, matchingRule.getSyntaxOid() );
192        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
193        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
194        injectCommon( matchingRule, entry, schemaManager );
195        return entry;
196    }
197
198
199    public Entry convert( MatchingRuleUse matchingRuleUse, Schema schema, SchemaManager schemaManager )
200    {
201        Entry entry = new DefaultEntry( schemaManager );
202
203        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, "" );
204        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
205        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
206        return entry;
207    }
208
209
210    public Entry convert( DitStructureRule ditStructureRule, Schema schema, SchemaManager schemaManager )
211    {
212        Entry entry = new DefaultEntry( schemaManager );
213
214        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, "" );
215        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
216        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
217        return entry;
218    }
219
220
221    public Entry convert( DitContentRule dITContentRule, Schema schema, SchemaManager schemaManager )
222    {
223        Entry entry = new DefaultEntry( schemaManager );
224
225        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, "" );
226        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
227        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
228        return entry;
229    }
230
231
232    public Entry convert( NameForm nameForm, Schema schema, SchemaManager schemaManager )
233    {
234        Entry entry = new DefaultEntry( schemaManager );
235
236        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, "" );
237        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
238        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
239        return entry;
240    }
241
242
243    /**
244     * <pre>
245     *    objectclass ( 1.3.6.1.4.1.18060.0.4.0.3.3
246     *       NAME 'metaAttributeType'
247     *       DESC 'meta definition of the AttributeType object'
248     *       SUP metaTop
249     *       STRUCTURAL
250     *       MUST ( m-name $ m-syntax )
251     *       MAY ( m-supAttributeType $ m-obsolete $ m-equality $ m-ordering $
252     *             m-substr $ m-singleValue $ m-collective $ m-noUserModification $
253     *             m-usage $ m-extensionAttributeType )
254     *    )
255     * </pre>
256     * 
257     * @param attributeType
258     * @return Attributes
259     * @throws LdapException
260     */
261    public Entry convert( AttributeType attributeType, Schema schema, SchemaManager schemaManager )
262        throws LdapException
263    {
264        Entry entry = new DefaultEntry( schemaManager );
265
266        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC );
267        entry.put( MetaSchemaConstants.M_COLLECTIVE_AT, getBoolean( attributeType.isCollective() ) );
268        entry.put( MetaSchemaConstants.M_NO_USER_MODIFICATION_AT, getBoolean( !attributeType.isUserModifiable() ) );
269        entry.put( MetaSchemaConstants.M_SINGLE_VALUE_AT, getBoolean( attributeType.isSingleValued() ) );
270        entry.put( MetaSchemaConstants.M_USAGE_AT, attributeType.getUsage().toString() );
271        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
272        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
273
274        injectCommon( attributeType, entry, schemaManager );
275
276        String superiorOid = attributeType.getSuperiorOid();
277
278        if ( superiorOid != null )
279        {
280            entry.put( MetaSchemaConstants.M_SUP_ATTRIBUTE_TYPE_AT, superiorOid );
281        }
282
283        if ( attributeType.getEqualityOid() != null )
284        {
285            entry.put( MetaSchemaConstants.M_EQUALITY_AT, attributeType.getEqualityOid() );
286        }
287
288        if ( attributeType.getSubstringOid() != null )
289        {
290            entry.put( MetaSchemaConstants.M_SUBSTR_AT, attributeType.getSubstringOid() );
291        }
292
293        if ( attributeType.getOrderingOid() != null )
294        {
295            entry.put( MetaSchemaConstants.M_ORDERING_AT, attributeType.getOrderingOid() );
296        }
297
298        if ( attributeType.getSyntaxOid() != null )
299        {
300            entry.put( MetaSchemaConstants.M_SYNTAX_AT, attributeType.getSyntaxOid() );
301        }
302
303        return entry;
304    }
305
306
307    /**
308     * Creates the attributes of an entry representing an objectClass.
309     * 
310     * <pre>
311     *  objectclass ( 1.3.6.1.4.1.18060.0.4.0.3.2
312     *      NAME 'metaObjectClass'
313     *      DESC 'meta definition of the objectclass object'
314     *      SUP metaTop
315     *      STRUCTURAL
316     *      MUST m-oid
317     *      MAY ( m-name $ m-obsolete $ m-supObjectClass $ m-typeObjectClass $ m-must $
318     *            m-may $ m-extensionObjectClass )
319     *  )
320     * </pre>
321     * 
322     * @param objectClass the objectClass to produce a meta schema entry for
323     * @return the attributes of the metaSchema entry representing the objectClass
324     * @throws LdapException if there are any problems
325     */
326    public Entry convert( ObjectClass objectClass, Schema schema, SchemaManager schemaManager )
327        throws LdapException
328    {
329        Entry entry = new DefaultEntry( schemaManager );
330
331        entry.put( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC, MetaSchemaConstants.META_OBJECT_CLASS_OC );
332        entry.put( MetaSchemaConstants.M_TYPE_OBJECT_CLASS_AT, objectClass.getType().toString() );
333        entry.put( SchemaConstants.CREATORS_NAME_AT, schema.getOwner() );
334        entry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
335
336        injectCommon( objectClass, entry, schemaManager );
337        Attribute attr = null;
338
339        // handle the superior objectClasses
340        if ( objectClass.getSuperiorOids() != null && objectClass.getSuperiorOids().size() != 0 )
341        {
342            if ( schemaManager != null )
343            {
344                attr = new DefaultAttribute(
345                    schemaManager.getAttributeType( MetaSchemaConstants.M_SUP_OBJECT_CLASS_AT ) );
346            }
347            else
348            {
349                attr = new DefaultAttribute( MetaSchemaConstants.M_SUP_OBJECT_CLASS_AT );
350            }
351
352            for ( String superior : objectClass.getSuperiorOids() )
353            {
354                attr.add( superior );
355            }
356
357            entry.put( attr );
358        }
359
360        // add the must list
361        if ( objectClass.getMustAttributeTypeOids() != null && objectClass.getMustAttributeTypeOids().size() != 0 )
362        {
363            if ( schemaManager != null )
364            {
365                attr = new DefaultAttribute( schemaManager.getAttributeType( MetaSchemaConstants.M_MUST_AT ) );
366            }
367            else
368            {
369                attr = new DefaultAttribute( MetaSchemaConstants.M_MUST_AT );
370            }
371
372            for ( String mustOid : objectClass.getMustAttributeTypeOids() )
373            {
374                attr.add( mustOid );
375            }
376
377            entry.put( attr );
378        }
379
380        // add the may list
381        if ( objectClass.getMayAttributeTypeOids() != null && objectClass.getMayAttributeTypeOids().size() != 0 )
382        {
383            if ( schemaManager != null )
384            {
385                attr = new DefaultAttribute( schemaManager.getAttributeType( MetaSchemaConstants.M_MAY_AT ) );
386            }
387            else
388            {
389                attr = new DefaultAttribute( MetaSchemaConstants.M_MAY_AT );
390            }
391
392            for ( String mayOid : objectClass.getMayAttributeTypeOids() )
393            {
394                attr.add( mayOid );
395            }
396
397            entry.put( attr );
398        }
399
400        return entry;
401    }
402
403
404    private final void injectCommon( SchemaObject object, Entry entry, SchemaManager schemaManager )
405        throws LdapException
406    {
407        injectNames( object.getNames(), entry, schemaManager );
408        entry.put( MetaSchemaConstants.M_OBSOLETE_AT, getBoolean( object.isObsolete() ) );
409        entry.put( MetaSchemaConstants.M_OID_AT, object.getOid() );
410
411        if ( object.getDescription() != null )
412        {
413            entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, object.getDescription() );
414        }
415
416        // The extensions
417        Map<String, List<String>> extensions = object.getExtensions();
418
419        if ( extensions != null )
420        {
421            for ( Map.Entry<String, List<String>> mapEntry : extensions.entrySet() )
422            {
423                String key = mapEntry.getKey();
424                List<String> values = mapEntry.getValue();
425
426                for ( String value : values )
427                {
428                    entry.add( key, value );
429                }
430            }
431        }
432    }
433
434
435    private final void injectNames( List<String> names, Entry entry, SchemaManager schemaManager ) throws LdapException
436    {
437        if ( ( names == null ) || ( names.size() == 0 ) )
438        {
439            return;
440        }
441
442        Attribute attr = null;
443
444        if ( schemaManager != null )
445        {
446            attr = new DefaultAttribute( schemaManager.getAttributeType( MetaSchemaConstants.M_NAME_AT ) );
447        }
448        else
449        {
450            attr = new DefaultAttribute( MetaSchemaConstants.M_NAME_AT );
451        }
452
453        for ( String name : names )
454        {
455            attr.add( name );
456        }
457
458        entry.put( attr );
459    }
460
461
462    private final String getBoolean( boolean value )
463    {
464        if ( value )
465        {
466            return "TRUE";
467        }
468        else
469        {
470            return "FALSE";
471        }
472    }
473}