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.xdbm.Index;
029    import org.apache.directory.server.xdbm.AbstractXdbmPartition;
030    import org.apache.directory.server.xdbm.search.impl.CursorBuilder;
031    import org.apache.directory.server.xdbm.search.impl.DefaultOptimizer;
032    import org.apache.directory.server.xdbm.search.impl.DefaultSearchEngine;
033    import org.apache.directory.server.xdbm.search.impl.EvaluatorBuilder;
034    import org.apache.directory.server.xdbm.search.impl.NoOpOptimizer;
035    import org.apache.directory.shared.ldap.constants.SchemaConstants;
036    import org.apache.directory.shared.ldap.entry.Modification;
037    import org.apache.directory.shared.ldap.entry.ServerEntry;
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        protected void doInit() 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            if ( store.isInitialized() )
084            {
085                return;
086            }
087    
088            // initialize the store
089            store.setName( getId() );
090            suffix.normalize( schemaManager.getNormalizerMapping() );
091            store.setSuffixDn( suffix.getName() );
092    
093            Set<Index<?, ServerEntry, Long>> userIndices = new HashSet<Index<?, ServerEntry, Long>>();
094    
095            for ( AvlIndex<?, ServerEntry> obj : indexedAttributes )
096            {
097                AvlIndex<?, ServerEntry> index;
098    
099                if ( obj instanceof AvlIndex<?, ?> )
100                {
101                    index = ( AvlIndex<?, ServerEntry> ) obj;
102                }
103                else
104                {
105                    index = new AvlIndex<Object, ServerEntry>();
106                    index.setAttributeId( obj.getAttributeId() );
107                }
108    
109                String oid = schemaManager.getAttributeTypeRegistry().getOidByName( index.getAttributeId() );
110    
111                if ( SYS_INDEX_OIDS.contains( schemaManager.getAttributeTypeRegistry()
112                    .getOidByName( index.getAttributeId() ) ) )
113                {
114                    if ( oid.equals( ApacheSchemaConstants.APACHE_ALIAS_AT_OID ) )
115                    {
116                        store.setAliasIndex( ( Index<String, ServerEntry, Long> ) index );
117                    }
118                    else if ( oid.equals( ApacheSchemaConstants.APACHE_EXISTENCE_AT_OID ) )
119                    {
120                        store.setPresenceIndex( ( Index<String, ServerEntry, Long> ) index );
121                    }
122                    else if ( oid.equals( ApacheSchemaConstants.APACHE_ONE_LEVEL_AT_OID ) )
123                    {
124                        store.setOneLevelIndex( ( Index<Long, ServerEntry, Long> ) index );
125                    }
126                    else if ( oid.equals( ApacheSchemaConstants.APACHE_N_DN_AT_OID ) )
127                    {
128                        store.setNdnIndex( ( Index<String, ServerEntry, Long> ) index );
129                    }
130                    else if ( oid.equals( ApacheSchemaConstants.APACHE_ONE_ALIAS_AT_OID ) )
131                    {
132                        store.setOneAliasIndex( ( Index<Long, ServerEntry, Long> ) index );
133                    }
134                    else if ( oid.equals( ApacheSchemaConstants.APACHE_SUB_ALIAS_AT_OID ) )
135                    {
136                        store.setSubAliasIndex( ( Index<Long, ServerEntry, Long> ) index );
137                    }
138                    else if ( oid.equals( ApacheSchemaConstants.APACHE_UP_DN_AT_OID ) )
139                    {
140                        store.setUpdnIndex( ( Index<String, ServerEntry, Long> ) index );
141                    }
142                    else if ( oid.equals( SchemaConstants.OBJECT_CLASS_AT_OID ) )
143                    {
144                        store.addIndex( ( Index<String, ServerEntry, Long> ) index );
145                    }
146                    else
147                    {
148                        throw new IllegalStateException( "Unrecognized system index " + oid );
149                    }
150                }
151                else
152                {
153                    userIndices.add( index );
154                }
155    
156                store.setUserIndices( userIndices );
157            }
158    
159            store.init( schemaManager );
160        }
161    
162    
163        /**
164         * {@inheritDoc}
165         */
166        public final void modify( long entryId, List<Modification> modifications ) throws Exception
167        {
168            ( ( AvlStore<ServerEntry> ) store ).modify( entryId, modifications );
169        }
170    
171    
172        /*
173         * TODO requires review 
174         * 
175         * This getter deviates from the norm. all the partitions
176         * so far written never return a reference to store but I think that in this 
177         * case the presence of this method gives significant ease and advantage to perform
178         * add/delete etc. operations without creating a operation context.
179         */
180        public AvlStore<ServerEntry> getStore()
181        {
182            return ( AvlStore<ServerEntry> ) store;
183        }
184    
185    }