View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.directory.server.xdbm;
20  
21  
22  import java.io.IOException;
23  
24  import org.apache.directory.api.ldap.model.constants.Loggers;
25  import org.apache.directory.api.ldap.model.cursor.CursorException;
26  import org.apache.directory.api.ldap.model.cursor.InvalidCursorPositionException;
27  import org.apache.directory.api.ldap.model.exception.LdapException;
28  import org.apache.directory.server.core.api.partition.PartitionTxn;
29  import org.apache.directory.server.i18n.I18n;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  
34  /**
35   * A Cursor over a single element.
36   *
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   */
39  public class SingletonIndexCursor<V> extends AbstractIndexCursor<V>
40  {
41      /** A dedicated log for cursors */
42      private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() );
43  
44      /** Speedup for logs */
45      private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled();
46  
47      private boolean beforeFirst = true;
48      private boolean afterLast;
49      private boolean onSingleton;
50      private final IndexEntry<V, String> singleton;
51  
52  
53      public SingletonIndexCursor( PartitionTxn partitionTxn, IndexEntry<V, String> singleton )
54      {
55          if ( IS_DEBUG )
56          {
57              LOG_CURSOR.debug( "Creating SingletonIndexCursor {}", this );
58          }
59  
60          this.singleton = singleton;
61          this.partitionTxn = partitionTxn;
62      }
63  
64  
65      /**
66       * {@inheritDoc}
67       */
68      protected String getUnsupportedMessage()
69      {
70          return UNSUPPORTED_MSG;
71      }
72  
73  
74      /**
75       * {@inheritDoc}
76       */
77      @Override
78      public boolean available()
79      {
80          return onSingleton;
81      }
82  
83  
84      /**
85       * {@inheritDoc}
86       */
87      @Override
88      public void beforeFirst() throws LdapException, CursorException
89      {
90          checkNotClosed();
91          beforeFirst = true;
92          afterLast = false;
93          onSingleton = false;
94      }
95  
96  
97      /**
98       * {@inheritDoc}
99       */
100     @Override
101     public void afterLast() throws LdapException, CursorException
102     {
103         checkNotClosed();
104         beforeFirst = false;
105         afterLast = true;
106         onSingleton = false;
107     }
108 
109 
110     /**
111      * {@inheritDoc}
112      */
113     @Override
114     public boolean first() throws LdapException, CursorException
115     {
116         checkNotClosed();
117         beforeFirst = false;
118         onSingleton = true;
119         afterLast = false;
120         return true;
121     }
122 
123 
124     /**
125      * {@inheritDoc}
126      */
127     @Override
128     public boolean last() throws LdapException, CursorException
129     {
130         checkNotClosed();
131         beforeFirst = false;
132         onSingleton = true;
133         afterLast = false;
134         return true;
135     }
136 
137 
138     /**
139      * {@inheritDoc}
140      */
141     @Override
142     public boolean isFirst()
143     {
144         return onSingleton;
145     }
146 
147 
148     /**
149      * {@inheritDoc}
150      */
151     @Override
152     public boolean isLast()
153     {
154         return onSingleton;
155     }
156 
157 
158     /**
159      * {@inheritDoc}
160      */
161     @Override
162     public boolean isAfterLast()
163     {
164         return afterLast;
165     }
166 
167 
168     /**
169      * {@inheritDoc}
170      */
171     @Override
172     public boolean isBeforeFirst()
173     {
174         return beforeFirst;
175     }
176 
177 
178     /**
179      * {@inheritDoc}
180      */
181     @Override
182     public boolean previous() throws LdapException, CursorException
183     {
184         checkNotClosed();
185         if ( beforeFirst )
186         {
187             return false;
188         }
189 
190         if ( afterLast )
191         {
192             beforeFirst = false;
193             onSingleton = true;
194             afterLast = false;
195             return true;
196         }
197 
198         // must be on the singleton
199         beforeFirst = true;
200         onSingleton = false;
201         afterLast = false;
202         return false;
203     }
204 
205 
206     /**
207      * {@inheritDoc}
208      */
209     @Override
210     public boolean next() throws LdapException, CursorException
211     {
212         checkNotClosed();
213         
214         if ( beforeFirst )
215         {
216             beforeFirst = false;
217             onSingleton = true;
218             afterLast = false;
219             return true;
220         }
221 
222         if ( afterLast )
223         {
224             return false;
225         }
226 
227         // must be on the singleton
228         beforeFirst = false;
229         onSingleton = false;
230         afterLast = true;
231         return false;
232     }
233 
234 
235     /**
236      * {@inheritDoc}
237      */
238     public IndexEntry<V, String> get() throws CursorException
239     {
240         checkNotClosed();
241 
242         if ( onSingleton )
243         {
244             return singleton;
245         }
246 
247         if ( beforeFirst )
248         {
249             throw new InvalidCursorPositionException( I18n.err( I18n.ERR_705 ) );
250         }
251         else
252         {
253             throw new InvalidCursorPositionException( I18n.err( I18n.ERR_706 ) );
254         }
255     }
256 
257 
258     /**
259      * {@inheritDoc}
260      */
261     @Override
262     public void close() throws IOException
263     {
264         if ( IS_DEBUG )
265         {
266             LOG_CURSOR.debug( "Closing SingletonIndexCursor {}", this );
267         }
268 
269         super.close();
270     }
271 
272 
273     /**
274      * {@inheritDoc}
275      */
276     @Override
277     public void close( Exception cause ) throws IOException
278     {
279         if ( IS_DEBUG )
280         {
281             LOG_CURSOR.debug( "Closing SingletonIndexCursor {}", this );
282         }
283 
284         super.close( cause );
285     }
286 }