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 */
019package org.apache.directory.shared.ldap.model.cursor;
020
021
022/**
023 * A Cursor for bidirectional traversal over elements in a dataSet. Cursors
024 * unlike Iterators or Enumerations may advance to an element by calling
025 * next() or previous() which returns true or false if the request succeeds
026 * with a viable element at the new position.  Operations for relative
027 * positioning in larger increments are provided.  If the cursor can not
028 * advance, then the Cursor is either positioned before the first element or
029 * after the last element in which case the user of the Cursor must stop
030 * advancing in the respective direction.  If an advance succeeds a get()
031 * operation retrieves the current object at the Cursors position.
032 *
033 * Although this interface presumes Cursors can advance bidirectionally,
034 * implementations may restrict this by throwing
035 * UnsupportedOperationExceptions.
036 *
037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
038 * @param <E> The type of element on which this cursor will iterate
039 */
040public interface Cursor<E> extends Iterable<E>
041{
042    /**
043     * Determines whether or not a call to get() will succeed.
044     *
045     * @return true if a call to the get() method will succeed, false otherwise
046     */
047    boolean available();
048
049
050    /**
051     * Prepares this Cursor, so a subsequent call to Cursor#next() with a
052     * true return value, will have positioned the Cursor on a dataSet 
053     * element equal to or less than the element argument but not greater.  
054     * A call to Cursor#previous() with a true return value will position 
055     * the Cursor on a dataSet element less than the argument.  If 
056     * Cursor#next() returns false then the Cursor is past the last element 
057     * and so all values in the dataSet are less than the argument.  If 
058     * Cursor#previous() returns false then the Cursor is positioned before 
059     * the first element and all elements in the dataSet are greater than 
060     * the argument.
061     *
062     * @param element the element to be positioned before
063     * @throws Exception with problems accessing the underlying btree
064     */
065    void before( E element ) throws Exception;
066
067
068    /**
069     * Prepares this Cursor, so a subsequent call to Cursor#previous() with a
070     * true return value, will have positioned the Cursor on a dataSet element
071     * equal to or less than the element argument but not greater. A call to
072     * Cursor#next() with a true return value will position the Cursor on a
073     * dataSet element greater than the argument.  If Cursor#next() returns
074     * false then the Cursor is past the last element and so all values in the
075     * dataSet are less than or equal to the argument.  If Cursor#previous()
076     * returns false then the Cursor is positioned before the first element
077     * and all elements in the dataSet are greater than the argument.
078     *
079     * @param element the element to be positioned after
080     * @throws Exception if there are problems positioning this cursor or if
081     * this Cursor is closed
082     */
083    void after( E element ) throws Exception;
084
085
086    /**
087     * Positions this Cursor before the first element.
088     *
089     * @throws Exception if there are problems positioning this cursor or if
090     * this Cursor is closed
091     */
092    void beforeFirst() throws Exception;
093
094
095    /**
096     * Positions this Cursor after the last element.
097     *
098     * @throws Exception if there are problems positioning this Cursor or if
099     * this Cursor is closed
100     */
101    void afterLast() throws Exception;
102
103
104    /**
105     * Positions this Cursor at the first element.
106     *
107     * @return true if the position has been successfully changed to the first
108     * element, false otherwise
109     * @throws Exception if there are problems positioning this Cursor or if
110     * this Cursor is closed
111     */
112    boolean first() throws Exception;
113
114
115    /**
116     * Is this Cursor positioned at the first element.
117     *
118     * @return true if this cursor is positioned at the first element, 
119     * false otherwise
120     * @throws Exception if there are problems querying the position of this Cursor
121     * or if this Cursor is closed
122     */
123    boolean isFirst() throws Exception;
124
125
126    /**
127     * Is this Cursor positioned before the first element.
128     *
129     * @return true if this cursor is positioned before the first element, 
130     * false otherwise
131     * @throws Exception if there are problems querying the position of this Cursor
132     * or if this Cursor is closed
133     */
134    boolean isBeforeFirst() throws Exception;
135
136
137    /**
138     * Positions this Cursor at the last element.
139     *
140     * @return true if the position has been successfully changed to the last
141     * element, false otherwise
142     * @throws Exception if there are problems positioning this Cursor or if
143     * this Cursor is closed
144     */
145    boolean last() throws Exception;
146
147
148    /**
149     * Is this Cursor positioned at the last element.
150     *
151     * @return true if this cursor is positioned at the last element, 
152     * false otherwise
153     * @throws Exception if there are problems querying the position of this Cursor
154     * or if this Cursor is closed
155     */
156    boolean isLast() throws Exception;
157
158
159    /**
160     * Is this Cursor positioned after the last element.
161     *
162     * @return true if this cursor is positioned after the last element, 
163     * false otherwise
164     * @throws Exception if there are problems querying the position of this Cursor
165     * or if this Cursor is closed
166     */
167    boolean isAfterLast() throws Exception;
168
169
170    /**
171     * Checks if this Cursor is closed.  Calls to this operation should not
172     * fail with exceptions if and only if the cursor is in the closed state.
173     *
174     * @return true if this Cursor is closed, false otherwise
175     * @throws Exception if there are problems determining the cursor's closed state
176     */
177    boolean isClosed() throws Exception;
178
179
180    /**
181     * Advances this Cursor to the previous position.  If called before
182     * explicitly positioning this Cursor, the position is presumed to be
183     * after the last element and this method moves the cursor back to the
184     * last element.
185     *
186     * @return true if the advance succeeded, false otherwise
187     * @throws Exception if there are problems advancing to the next position
188     */
189    boolean previous() throws Exception;
190
191
192    /**
193     * Advances this Cursor to the next position.  If called before
194     * explicitly positioning this Cursor, the position is presumed to be
195     * before the first element and this method moves the cursor forward to
196     * the first element.
197     *
198     * @return true if the advance succeeded, false otherwise
199     * @throws Exception if there are problems advancing to this Cursor to
200     * the next position, or if this Cursor is closed
201     */
202    boolean next() throws Exception;
203
204
205    /**
206     * Gets the object at the current position.  Cursor implementations may
207     * choose to reuse element objects by re-populating them on advances
208     * instead of creating new objects on each advance.
209     *
210     * @return the object at the current position
211     * @throws Exception if the object at this Cursor's current position
212     * cannot be retrieved, or if this Cursor is closed
213     */
214    E get() throws Exception;
215
216
217    /**
218     * Closes this Cursor and frees any resources it my have allocated.
219     * Repeated calls to this method after this Cursor has already been
220     * called should not fail with exceptions.
221     *
222     * @throws Exception if for some reason this Cursor could not be closed
223     */
224    void close() throws Exception;
225
226
227    /**
228     * Closes this Cursor and frees any resources it my have allocated.
229     * Repeated calls to this method after this Cursor has already been
230     * called should not fail with exceptions.  The reason argument is 
231     * the Exception instance thrown instead of the standard 
232     * CursorClosedException.
233     *
234     * @param reason exception thrown when this Cursor is accessed after close
235     * @throws Exception if for some reason this Cursor could not be closed
236     */
237    void close( Exception reason ) throws Exception;
238
239
240    /**
241     * Sets a non-null closure monitor to associate with this Cursor.
242     *
243     * @param monitor the monitor to use for detecting Cursor close events
244     */
245    void setClosureMonitor( ClosureMonitor monitor );
246}