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