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.shared.ldap.cursor; 020 021 022 import java.util.Comparator; 023 024 import org.apache.directory.shared.i18n.I18n; 025 026 027 /** 028 * A Cursor over a single element. 029 * 030 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 031 * @version $Rev$, $Date$ 032 */ 033 public class SingletonCursor<E> extends AbstractCursor<E> 034 { 035 /** A flag set to true to a*/ 036 private boolean beforeFirst = true; 037 private boolean afterLast; 038 private boolean onSingleton; 039 040 /** The comparator used for this cursor. */ 041 private final Comparator<E> comparator; 042 043 /** The unique element stored in the cursor */ 044 private final E singleton; 045 046 047 /** 048 * Creates a new instance of SingletonCursor. 049 * 050 * @param singleton The unique element to store into this cursor 051 */ 052 public SingletonCursor( E singleton ) 053 { 054 this( singleton, null ); 055 } 056 057 058 /** 059 * Creates a new instance of SingletonCursor, with its associated 060 * conmparator 061 * 062 * @param singleton The unique element to store into this cursor 063 * @param comparator The associated comparator 064 */ 065 public SingletonCursor( E singleton, Comparator<E> comparator ) 066 { 067 this.singleton = singleton; 068 this.comparator = comparator; 069 } 070 071 072 /** 073 * {@inheritDoc} 074 */ 075 public boolean available() 076 { 077 return onSingleton; 078 } 079 080 081 /** 082 * {@inheritDoc} 083 */ 084 public void before( E element ) throws Exception 085 { 086 checkNotClosed( "before()" ); 087 088 if ( comparator == null ) 089 { 090 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02010 ) ); 091 } 092 093 int comparison = comparator.compare( singleton, element ); 094 095 if ( comparison < 0 ) 096 { 097 first(); 098 } 099 else 100 { 101 beforeFirst(); 102 } 103 } 104 105 106 /** 107 * {@inheritDoc} 108 */ 109 public void after( E element ) throws Exception 110 { 111 checkNotClosed( "after()" ); 112 113 if ( comparator == null ) 114 { 115 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02011 ) ); 116 } 117 118 int comparison = comparator.compare( singleton, element ); 119 120 if ( comparison > 0 ) 121 { 122 first(); 123 } 124 else 125 { 126 afterLast(); 127 } 128 } 129 130 131 /** 132 * {@inheritDoc} 133 */ 134 public void beforeFirst() throws Exception 135 { 136 checkNotClosed( "()" ); 137 beforeFirst = true; 138 afterLast = false; 139 onSingleton = false; 140 } 141 142 143 /** 144 * {@inheritDoc} 145 */ 146 public void afterLast() throws Exception 147 { 148 checkNotClosed( "()" ); 149 beforeFirst = false; 150 afterLast = true; 151 onSingleton = false; 152 } 153 154 155 /** 156 * {@inheritDoc} 157 */ 158 public boolean first() throws Exception 159 { 160 checkNotClosed( "()" ); 161 beforeFirst = false; 162 onSingleton = true; 163 afterLast = false; 164 return true; 165 } 166 167 168 /** 169 * {@inheritDoc} 170 */ 171 public boolean last() throws Exception 172 { 173 checkNotClosed( "()" ); 174 beforeFirst = false; 175 onSingleton = true; 176 afterLast = false; 177 return true; 178 } 179 180 181 /** 182 * {@inheritDoc} 183 */ 184 public boolean isFirst() throws Exception 185 { 186 checkNotClosed( "()" ); 187 return onSingleton; 188 } 189 190 191 /** 192 * {@inheritDoc} 193 */ 194 public boolean isLast() throws Exception 195 { 196 checkNotClosed( "()" ); 197 return onSingleton; 198 } 199 200 201 /** 202 * {@inheritDoc} 203 */ 204 public boolean isAfterLast() throws Exception 205 { 206 checkNotClosed( "()" ); 207 return afterLast; 208 } 209 210 211 /** 212 * {@inheritDoc} 213 */ 214 public boolean isBeforeFirst() throws Exception 215 { 216 checkNotClosed( "()" ); 217 return beforeFirst; 218 } 219 220 221 /** 222 * {@inheritDoc} 223 */ 224 public boolean previous() throws Exception 225 { 226 checkNotClosed( "()" ); 227 228 if ( beforeFirst ) 229 { 230 return false; 231 } 232 233 if ( afterLast ) 234 { 235 beforeFirst = false; 236 onSingleton = true; 237 afterLast = false; 238 return true; 239 } 240 241 // must be on the singleton 242 beforeFirst = true; 243 onSingleton = false; 244 afterLast = false; 245 return false; 246 } 247 248 249 /** 250 * {@inheritDoc} 251 */ 252 public boolean next() throws Exception 253 { 254 checkNotClosed( "()" ); 255 256 if ( beforeFirst ) 257 { 258 beforeFirst = false; 259 onSingleton = true; 260 afterLast = false; 261 return true; 262 } 263 264 if ( afterLast ) 265 { 266 return false; 267 } 268 269 // must be on the singleton 270 beforeFirst = false; 271 onSingleton = false; 272 afterLast = true; 273 return false; 274 } 275 276 277 /** 278 * {@inheritDoc} 279 */ 280 public E get() throws Exception 281 { 282 checkNotClosed( "()" ); 283 284 if ( onSingleton ) 285 { 286 return singleton; 287 } 288 289 if ( beforeFirst ) 290 { 291 throw new InvalidCursorPositionException( I18n.err( I18n.ERR_02012 ) ); 292 } 293 else 294 { 295 throw new InvalidCursorPositionException( I18n.err( I18n.ERR_02013 ) ); 296 } 297 } 298 299 300 /** 301 * {@inheritDoc} 302 */ 303 public boolean isElementReused() 304 { 305 return true; 306 } 307 }