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 }