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; 020 021 022 import java.util.Arrays; 023 import java.util.List; 024 025 import org.apache.directory.server.i18n.I18n; 026 import org.apache.directory.server.xdbm.Tuple; 027 import org.apache.directory.shared.ldap.NotImplementedException; 028 import org.apache.directory.shared.ldap.cursor.AbstractCursor; 029 import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException; 030 031 032 /** 033 * A Cursor which returns the values of a single key as Tuples. 034 * 035 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 036 * @version $Rev$, $Date$ 037 */ 038 public class ValueArrayCursor<K, V> extends AbstractCursor<Tuple<K, V>> 039 { 040 private static final int BEFORE_FIRST = -1; 041 042 private final K key; 043 private final List<V> values; 044 private final Tuple<K, V> tuple = new Tuple<K, V>(); 045 046 private int pos = BEFORE_FIRST; 047 048 049 public ValueArrayCursor( final K key, final V[] values ) 050 { 051 this.key = key; 052 this.tuple.setKey( key ); 053 this.values = Arrays.asList( values ); 054 } 055 056 057 public ValueArrayCursor( final K key, final List<V> values ) 058 { 059 this.key = key; 060 this.tuple.setKey( key ); 061 this.values = values; 062 } 063 064 065 public boolean available() 066 { 067 return inRangeOnValue(); 068 } 069 070 071 public void before( Tuple<K, V> element ) throws Exception 072 { 073 throw new NotImplementedException(); 074 } 075 076 077 public void after( Tuple<K, V> element ) throws Exception 078 { 079 throw new NotImplementedException(); 080 } 081 082 083 public void beforeFirst() throws Exception 084 { 085 checkNotClosed( "beforeFirst()" ); 086 pos = BEFORE_FIRST; 087 } 088 089 090 public void afterLast() throws Exception 091 { 092 checkNotClosed( "afterLast()" ); 093 pos = values.size(); 094 } 095 096 097 public boolean absolute( int absolutePosition ) throws Exception 098 { 099 checkNotClosed( "absolute()" ); 100 if ( absolutePosition >= values.size() ) 101 { 102 pos = values.size(); 103 return false; 104 } 105 106 if ( absolutePosition < 0 ) 107 { 108 pos = BEFORE_FIRST; 109 return false; 110 } 111 112 pos = absolutePosition; 113 return true; 114 } 115 116 117 public boolean first() throws Exception 118 { 119 checkNotClosed( "first()" ); 120 pos = 0; 121 return true; 122 } 123 124 125 public boolean last() throws Exception 126 { 127 checkNotClosed( "last()" ); 128 pos = values.size() - 1; 129 return true; 130 } 131 132 133 public boolean isFirst() throws Exception 134 { 135 checkNotClosed( "isFirst()" ); 136 return pos == 0; 137 } 138 139 140 public boolean isLast() throws Exception 141 { 142 checkNotClosed( "isLast()" ); 143 return pos == values.size() - 1; 144 } 145 146 147 public boolean isAfterLast() throws Exception 148 { 149 checkNotClosed( "isAfterLast()" ); 150 return pos == values.size(); 151 } 152 153 154 public boolean isBeforeFirst() throws Exception 155 { 156 checkNotClosed( "isBeforeFirst()" ); 157 return pos == BEFORE_FIRST; 158 } 159 160 161 public boolean previous() throws Exception 162 { 163 checkNotClosed( "previous()" ); 164 if ( pos <= BEFORE_FIRST ) 165 { 166 return false; 167 } 168 169 pos--; 170 return inRangeOnValue(); 171 } 172 173 174 private boolean inRangeOnValue() 175 { 176 return pos > BEFORE_FIRST && pos < values.size(); 177 } 178 179 180 public boolean next() throws Exception 181 { 182 checkNotClosed( "next()" ); 183 if ( pos >= values.size() ) 184 { 185 return false; 186 } 187 188 pos++; 189 return inRangeOnValue(); 190 } 191 192 193 public Tuple<K, V> get() throws Exception 194 { 195 checkNotClosed( "get()" ); 196 if ( inRangeOnValue() ) 197 { 198 return tuple.setBoth( key, values.get( pos ) ); 199 } 200 201 throw new InvalidCursorPositionException( I18n.err( I18n.ERR_701, pos, ( values.size() - 1 ) ) ); 202 } 203 204 205 public boolean isElementReused() 206 { 207 return true; 208 } 209 }