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    package org.apache.directory.server.core.partition.avl;
021    
022    
023    import java.util.HashSet;
024    import java.util.List;
025    import java.util.Set;
026    
027    import org.apache.directory.server.constants.ApacheSchemaConstants;
028    import org.apache.directory.server.core.entry.ServerEntry;
029    import org.apache.directory.server.xdbm.Index;
030    import org.apache.directory.server.xdbm.AbstractXdbmPartition;
031    import org.apache.directory.server.xdbm.search.impl.CursorBuilder;
032    import org.apache.directory.server.xdbm.search.impl.DefaultOptimizer;
033    import org.apache.directory.server.xdbm.search.impl.DefaultSearchEngine;
034    import org.apache.directory.server.xdbm.search.impl.EvaluatorBuilder;
035    import org.apache.directory.server.xdbm.search.impl.NoOpOptimizer;
036    import org.apache.directory.shared.ldap.constants.SchemaConstants;
037    import org.apache.directory.shared.ldap.entry.Modification;
038    
039    
040    /**
041     * An XDBM Partition backed by in memory AVL Trees.
042     *
043     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
044     * @version $Rev$, $Date$
045     */
046    public class AvlPartition extends AbstractXdbmPartition<Long>
047    {
048        private Set<AvlIndex<?, ServerEntry>> indexedAttributes;
049    
050    
051        /**
052         * Creates a store based on AVL Trees.
053         */
054        public AvlPartition()
055        {
056            super( new AvlStore<ServerEntry>() );
057            indexedAttributes = new HashSet<AvlIndex<?, ServerEntry>>();
058        }
059    
060    
061        /**
062         * {@inheritDoc}
063         */
064        public void initialize() throws Exception
065        {
066            setSchemaManager( schemaManager );
067    
068            EvaluatorBuilder<Long> evaluatorBuilder = new EvaluatorBuilder<Long>( store, schemaManager );
069            CursorBuilder<Long> cursorBuilder = new CursorBuilder<Long>( store, evaluatorBuilder );
070    
071            // setup optimizer and registries for parent
072            if ( !optimizerEnabled )
073            {
074                optimizer = new NoOpOptimizer();
075            }
076            else
077            {
078                optimizer = new DefaultOptimizer<ServerEntry, Long>( store );
079            }
080    
081            searchEngine = new DefaultSearchEngine<Long>( store, cursorBuilder, evaluatorBuilder, optimizer );
082    
083            // initialize the store
084            store.setName( getId() );
085            store.setSuffixDn( suffix.getName() );
086    
087            Set<Index<?, ServerEntry, Long>> userIndices = new HashSet<Index<?, ServerEntry, Long>>();
088    
089            for ( AvlIndex<?, ServerEntry> obj : indexedAttributes )
090            {
091                AvlIndex<?, ServerEntry> index;
092    
093                if ( obj instanceof AvlIndex<?, ?> )
094                {
095                    index = ( AvlIndex<?, ServerEntry> ) obj;
096                }
097                else
098                {
099                    index = new AvlIndex<Object, ServerEntry>();
100                    index.setAttributeId( obj.getAttributeId() );
101                }
102    
103                String oid = schemaManager.getAttributeTypeRegistry().getOidByName( index.getAttributeId() );
104    
105                if ( SYS_INDEX_OIDS.contains( schemaManager.getAttributeTypeRegistry()
106                    .getOidByName( index.getAttributeId() ) ) )
107                {
108                    if ( oid.equals( ApacheSchemaConstants.APACHE_ALIAS_AT_OID ) )
109                    {
110                        store.setAliasIndex( ( Index<String, ServerEntry, Long> ) index );
111                    }
112                    else if ( oid.equals( ApacheSchemaConstants.APACHE_EXISTENCE_AT_OID ) )
113                    {
114                        store.setPresenceIndex( ( Index<String, ServerEntry, Long> ) index );
115                    }
116                    else if ( oid.equals( ApacheSchemaConstants.APACHE_ONE_LEVEL_AT_OID ) )
117                    {
118                        store.setOneLevelIndex( ( Index<Long, ServerEntry, Long> ) index );
119                    }
120                    else if ( oid.equals( ApacheSchemaConstants.APACHE_N_DN_AT_OID ) )
121                    {
122                        store.setNdnIndex( ( Index<String, ServerEntry, Long> ) index );
123                    }
124                    else if ( oid.equals( ApacheSchemaConstants.APACHE_ONE_ALIAS_AT_OID ) )
125                    {
126                        store.setOneAliasIndex( ( Index<Long, ServerEntry, Long> ) index );
127                    }
128                    else if ( oid.equals( ApacheSchemaConstants.APACHE_SUB_ALIAS_AT_OID ) )
129                    {
130                        store.setSubAliasIndex( ( Index<Long, ServerEntry, Long> ) index );
131                    }
132                    else if ( oid.equals( ApacheSchemaConstants.APACHE_UP_DN_AT_OID ) )
133                    {
134                        store.setUpdnIndex( ( Index<String, ServerEntry, Long> ) index );
135                    }
136                    else if ( oid.equals( SchemaConstants.OBJECT_CLASS_AT_OID ) )
137                    {
138                        store.addIndex( ( Index<String, ServerEntry, Long> ) index );
139                    }
140                    else
141                    {
142                        throw new IllegalStateException( "Unrecognized system index " + oid );
143                    }
144                }
145                else
146                {
147                    userIndices.add( index );
148                }
149    
150                store.setUserIndices( userIndices );
151            }
152    
153            store.init( schemaManager );
154        }
155    
156    
157        /**
158         * {@inheritDoc}
159         */
160        public final void modify( long entryId, List<Modification> modifications ) throws Exception
161        {
162            ( ( AvlStore<ServerEntry> ) store ).modify( entryId, modifications );
163        }
164    
165    
166        /*
167         * TODO requires review 
168         * 
169         * This getter deviates from the norm. all the partitions
170         * so far written never return a reference to store but I think that in this 
171         * case the presence of this method gives significant ease and advantage to perform
172         * add/delete etc. operations without creating a operation context.
173         */
174        public AvlStore<ServerEntry> getStore()
175        {
176            return ( AvlStore<ServerEntry> ) store;
177        }
178    
179    }