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