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