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 }