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.impl.btree;
021    
022    
023    
024    import java.util.Iterator;
025    
026    import org.apache.directory.server.xdbm.ForwardIndexEntry;
027    import org.apache.directory.server.xdbm.IndexCursor;
028    import org.apache.directory.server.xdbm.IndexEntry;
029    import org.apache.directory.server.xdbm.ReverseIndexEntry;
030    import org.apache.directory.server.xdbm.Tuple;
031    import org.apache.directory.server.xdbm.TupleCursor;
032    import org.apache.directory.shared.ldap.cursor.ClosureMonitor;
033    import org.apache.directory.shared.ldap.cursor.Cursor;
034    import org.apache.directory.shared.ldap.cursor.CursorIterator;
035    
036    
037    /**
038     * A Cursor which adapts an underlying Tuple based Cursor to one which returns
039     * IndexEntry objects rather than tuples.
040     *
041     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042     * @version $Rev$
043     */
044    public class IndexCursorAdaptor<K,O> implements IndexCursor<K,O>
045    {
046        @SuppressWarnings("unchecked")
047        final Cursor<Tuple> wrappedCursor;
048        final ForwardIndexEntry<K, O> forwardEntry;
049        final ReverseIndexEntry<K, O> reverseEntry;
050    
051    
052        /**
053         * Creates an IndexCursorAdaptor which wraps and adapts a Cursor from a table to
054         * one which returns an IndexEntry.
055         *
056         * @param wrappedCursor the Cursor being adapted
057         * @param forwardIndex true for a cursor over a forward index, false for
058         * one over a reverse index
059         */
060        @SuppressWarnings("unchecked")
061        public IndexCursorAdaptor( Cursor<Tuple> wrappedCursor, boolean forwardIndex )
062        {
063            this.wrappedCursor = wrappedCursor;
064            if ( forwardIndex )
065            {
066                forwardEntry = new ForwardIndexEntry<K,O>();
067                reverseEntry = null;
068            }
069            else
070            {
071                forwardEntry = null;
072                reverseEntry = new ReverseIndexEntry<K, O>();
073            }
074        }
075    
076    
077        public boolean available()
078        {
079            return wrappedCursor.available();
080        }
081    
082    
083        @SuppressWarnings("unchecked")
084        public void beforeValue( Long id, K key ) throws Exception
085        {
086            if ( wrappedCursor instanceof TupleCursor )
087            {
088                ( ( TupleCursor ) wrappedCursor ).beforeValue( key, id );
089            }
090        }
091    
092    
093        @SuppressWarnings("unchecked")
094        public void afterValue( Long id, K key ) throws Exception
095        {
096            if ( wrappedCursor instanceof TupleCursor )
097            {
098                ( ( TupleCursor ) wrappedCursor ).afterValue( key, id );
099            }
100        }
101    
102    
103        public void before( IndexEntry<K, O> element ) throws Exception
104        {
105            wrappedCursor.before( element.getTuple() );
106        }
107    
108    
109        public void after( IndexEntry<K, O> element ) throws Exception
110        {
111            wrappedCursor.after( element.getTuple() );
112        }
113    
114    
115        public void beforeFirst() throws Exception
116        {
117            wrappedCursor.beforeFirst();
118        }
119    
120    
121        public void afterLast() throws Exception
122        {
123            wrappedCursor.afterLast();
124        }
125    
126    
127        public boolean first() throws Exception
128        {
129            return wrappedCursor.first();
130        }
131    
132    
133        public boolean last() throws Exception
134        {
135            return wrappedCursor.last();
136        }
137    
138    
139        public boolean isClosed() throws Exception
140        {
141            return wrappedCursor.isClosed();
142        }
143    
144    
145        public boolean previous() throws Exception
146        {
147            return wrappedCursor.previous();
148        }
149    
150    
151        public boolean next() throws Exception
152        {
153            return wrappedCursor.next();
154        }
155    
156    
157        @SuppressWarnings("unchecked")
158        public IndexEntry<K, O> get() throws Exception
159        {
160            if ( forwardEntry != null )
161            {
162                Tuple<K,Long> tuple = wrappedCursor.get();
163                forwardEntry.setTuple( tuple, null );
164                return forwardEntry;
165            }
166            else
167            {
168                Tuple<Long,K> tuple = wrappedCursor.get();
169                reverseEntry.setTuple( tuple, null );
170                return reverseEntry;
171            }
172        }
173    
174    
175        public boolean isElementReused()
176        {
177            return true;
178        }
179        
180        
181        public final void setClosureMonitor( ClosureMonitor monitor )
182        {
183            wrappedCursor.setClosureMonitor( monitor );
184        }
185    
186    
187        public void close() throws Exception
188        {
189            wrappedCursor.close();
190        }
191    
192    
193        public void close( Exception reason ) throws Exception
194        {
195            wrappedCursor.close( reason );
196        }
197    
198    
199        public Iterator<IndexEntry<K, O>> iterator()
200        {
201            return new CursorIterator<IndexEntry<K,O>>( this );
202        }
203    }