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