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 package org.apache.directory.server.core.partition.impl.btree.jdbm; 020 021 022 import org.apache.directory.server.xdbm.Tuple; 023 import org.apache.directory.server.xdbm.AbstractTupleCursor; 024 import org.apache.directory.server.core.avltree.ArrayTree; 025 import org.apache.directory.server.core.avltree.ArrayTreeCursor; 026 import org.apache.directory.server.i18n.I18n; 027 import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException; 028 029 030 /** 031 * Cursor over a set of values for the same key which are store in an in 032 * memory ArrayTree. This Cursor is limited to the same key and it's tuples 033 * will always return the same key. 034 * 035 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 036 * @version $Rev$, $Date$ 037 */ 038 public class KeyTupleArrayCursor<K,V> extends AbstractTupleCursor<K,V> 039 { 040 private final ArrayTreeCursor<V> wrapped; 041 private final K key; 042 043 private Tuple<K,V> returnedTuple = new Tuple<K,V>(); 044 private boolean valueAvailable; 045 046 047 /** 048 * Creates a Cursor over the tuples of an ArrayTree. 049 * 050 * @param avlTree the ArrayTree to build a Tuple returning Cursor over 051 * @param key the constant key for which values are returned 052 */ 053 public KeyTupleArrayCursor( ArrayTree<V> arrayTree, K key ) 054 { 055 this.key = key; 056 this.wrapped = new ArrayTreeCursor<V>( arrayTree ); 057 } 058 059 060 private void clearValue() 061 { 062 returnedTuple.setKey( key ); 063 returnedTuple.setValue( null ); 064 valueAvailable = false; 065 } 066 067 068 public boolean available() 069 { 070 return valueAvailable; 071 } 072 073 074 public void beforeKey( K key ) throws Exception 075 { 076 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) ); 077 } 078 079 080 public void afterKey( K key ) throws Exception 081 { 082 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) ); 083 } 084 085 086 public void beforeValue( K key, V value ) throws Exception 087 { 088 checkNotClosed( "beforeValue()" ); 089 if ( key != null && ! key.equals( this.key ) ) 090 { 091 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) ); 092 } 093 094 wrapped.before( value ); 095 clearValue(); 096 } 097 098 099 public void afterValue( K key, V value ) throws Exception 100 { 101 checkNotClosed( "afterValue()" ); 102 if ( key != null && ! key.equals( this.key ) ) 103 { 104 throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) ); 105 } 106 107 wrapped.after( value ); 108 clearValue(); 109 } 110 111 112 /** 113 * Positions this Cursor over the same keys before the value of the 114 * supplied element Tuple. The supplied element Tuple's key is not 115 * considered at all. 116 * 117 * @param element the valueTuple who's value is used to position this Cursor 118 * @throws Exception if there are failures to position the Cursor 119 */ 120 public void before( Tuple<K,V> element ) throws Exception 121 { 122 checkNotClosed( "before()" ); 123 wrapped.before( element.getValue() ); 124 clearValue(); 125 } 126 127 128 public void after( Tuple<K,V> element ) throws Exception 129 { 130 checkNotClosed( "after()" ); 131 wrapped.after( element.getValue() ); 132 clearValue(); 133 } 134 135 136 public void beforeFirst() throws Exception 137 { 138 checkNotClosed( "beforeFirst()" ); 139 wrapped.beforeFirst(); 140 clearValue(); 141 } 142 143 144 public void afterLast() throws Exception 145 { 146 checkNotClosed( "afterLast()" ); 147 wrapped.afterLast(); 148 clearValue(); 149 } 150 151 152 public boolean first() throws Exception 153 { 154 beforeFirst(); 155 return next(); 156 } 157 158 159 public boolean last() throws Exception 160 { 161 afterLast(); 162 return previous(); 163 } 164 165 166 public boolean previous() throws Exception 167 { 168 checkNotClosed( "previous()" ); 169 if ( wrapped.previous() ) 170 { 171 returnedTuple.setKey( key ); 172 returnedTuple.setValue( wrapped.get() ); 173 return valueAvailable = true; 174 } 175 else 176 { 177 clearValue(); 178 return false; 179 } 180 } 181 182 183 public boolean next() throws Exception 184 { 185 checkNotClosed( "next()" ); 186 if ( wrapped.next() ) 187 { 188 returnedTuple.setKey( key ); 189 returnedTuple.setValue( wrapped.get() ); 190 return valueAvailable = true; 191 } 192 else 193 { 194 clearValue(); 195 return false; 196 } 197 } 198 199 200 public Tuple<K,V> get() throws Exception 201 { 202 checkNotClosed( "get()" ); 203 if ( valueAvailable ) 204 { 205 return returnedTuple; 206 } 207 208 throw new InvalidCursorPositionException(); 209 } 210 211 212 public boolean isElementReused() 213 { 214 return true; 215 } 216 }