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   */
20  package org.apache.directory.server.core.partition.impl.btree;
21  
22  
23  import java.io.IOException;
24  import java.util.Iterator;
25  
26  import org.apache.directory.api.i18n.I18n;
27  import org.apache.directory.api.ldap.model.constants.Loggers;
28  import org.apache.directory.api.ldap.model.cursor.ClosureMonitor;
29  import org.apache.directory.api.ldap.model.cursor.Cursor;
30  import org.apache.directory.api.ldap.model.cursor.CursorException;
31  import org.apache.directory.api.ldap.model.cursor.CursorIterator;
32  import org.apache.directory.api.ldap.model.cursor.Tuple;
33  import org.apache.directory.api.ldap.model.exception.LdapException;
34  import org.apache.directory.server.core.api.partition.PartitionTxn;
35  import org.apache.directory.server.xdbm.AbstractIndexCursor;
36  import org.apache.directory.server.xdbm.IndexEntry;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  
41  /**
42   * A Cursor which adapts an underlying Tuple based Cursor to one which returns
43   * IndexEntry objects rather than tuples.
44   *
45   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
46   */
47  public class IndexCursorAdaptor<K> extends AbstractIndexCursor<K>
48  {
49      /** A dedicated log for cursors */
50      private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() );
51  
52      /** Speedup for logs */
53      private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled();
54  
55      @SuppressWarnings("unchecked")
56      final Cursor<Tuple> wrappedCursor;
57      final IndexEntry<K, String> forwardEntry;
58  
59  
60      /**
61       * Creates an IndexCursorAdaptor which wraps and adapts a Cursor from a table to
62       * one which returns an IndexEntry.
63       *
64       * @param partitionTxn The transaction to use
65       * @param wrappedCursor the Cursor being adapted
66       * @param forwardIndex true for a cursor over a forward index, false for
67       * one over a reverse index
68       */
69      @SuppressWarnings("unchecked")
70      public IndexCursorAdaptor( PartitionTxn partitionTxn, Cursor<Tuple> wrappedCursor, boolean forwardIndex )
71      {
72          this.wrappedCursor = wrappedCursor;
73  
74          forwardEntry = new IndexEntry<>();
75          this.partitionTxn = partitionTxn;
76  
77          if ( IS_DEBUG )
78          {
79              LOG_CURSOR.debug( "Creating IndexCursorAdaptor {}", this );
80          }
81      }
82  
83  
84      /**
85       * {@inheritDoc}
86       */
87      @Override
88      public boolean available()
89      {
90          return wrappedCursor.available();
91      }
92  
93  
94      /**
95       * {@inheritDoc}
96       */
97      @Override
98      public void before( IndexEntry<K, String> element ) throws LdapException, CursorException
99      {
100         wrappedCursor.before( element.getTuple() );
101     }
102 
103 
104     /**
105      * {@inheritDoc}
106      */
107     @Override
108     public void after( IndexEntry<K, String> element ) throws LdapException, CursorException
109     {
110         wrappedCursor.after( element.getTuple() );
111     }
112 
113 
114     /**
115      * {@inheritDoc}
116      */
117     public void beforeFirst() throws LdapException, CursorException
118     {
119         wrappedCursor.beforeFirst();
120     }
121 
122 
123     /**
124      * {@inheritDoc}
125      */
126     public void afterLast() throws LdapException, CursorException
127     {
128         wrappedCursor.afterLast();
129     }
130 
131 
132     /**
133      * {@inheritDoc}
134      */
135     public boolean first() throws LdapException, CursorException
136     {
137         return wrappedCursor.first();
138     }
139 
140 
141     /**
142      * {@inheritDoc}
143      */
144     public boolean last() throws LdapException, CursorException
145     {
146         return wrappedCursor.last();
147     }
148 
149 
150     /**
151      * {@inheritDoc}
152      */
153     @Override
154     public boolean isClosed()
155     {
156         return wrappedCursor.isClosed();
157     }
158 
159 
160     /**
161      * {@inheritDoc}
162      */
163     @Override
164     public boolean previous() throws LdapException, CursorException
165     {
166         return wrappedCursor.previous();
167     }
168 
169 
170     /**
171      * {@inheritDoc}
172      */
173     @Override
174     public boolean next() throws LdapException, CursorException
175     {
176         return wrappedCursor.next();
177     }
178 
179 
180     /**
181      * {@inheritDoc}
182      */
183     @SuppressWarnings("unchecked")
184     public IndexEntry<K, String> get() throws CursorException
185     {
186         Tuple<K, String> tuple = wrappedCursor.get();
187         forwardEntry.setTuple( tuple );
188 
189         return forwardEntry;
190     }
191 
192 
193     @Override
194     public final void setClosureMonitor( ClosureMonitor monitor )
195     {
196         wrappedCursor.setClosureMonitor( monitor );
197     }
198 
199 
200     /**
201      * {@inheritDoc}
202      */
203     @Override
204     public void close() throws IOException
205     {
206         if ( IS_DEBUG )
207         {
208             LOG_CURSOR.debug( "Closing IndexCursorAdaptor {}", this );
209         }
210 
211         wrappedCursor.close();
212     }
213 
214 
215     /**
216      * {@inheritDoc}
217      */
218     @Override
219     public void close( Exception reason ) throws IOException
220     {
221         if ( IS_DEBUG )
222         {
223             LOG_CURSOR.debug( "Closing IndexCursorAdaptor {}", this );
224         }
225 
226         wrappedCursor.close( reason );
227     }
228 
229 
230     @Override
231     public Iterator<IndexEntry<K, String>> iterator()
232     {
233         return new CursorIterator<>( this );
234     }
235 
236 
237     /**
238      * {@inheritDoc}
239      */
240     @Override
241     public boolean isAfterLast()
242     {
243         throw new UnsupportedOperationException( I18n.err( I18n.ERR_13102_UNSUPPORTED_OPERATION, getClass().getName()
244             .concat( "." ).concat( "isAfterLast()" ) ) );
245     }
246 
247 
248     /**
249      * {@inheritDoc}
250      */
251     @Override
252     public boolean isBeforeFirst()
253     {
254         throw new UnsupportedOperationException( I18n.err( I18n.ERR_13102_UNSUPPORTED_OPERATION, getClass().getName()
255             .concat( "." ).concat( "isBeforeFirst()" ) ) );
256     }
257 
258 
259     /**
260      * {@inheritDoc}
261      */
262     @Override
263     public boolean isFirst()
264     {
265         throw new UnsupportedOperationException( I18n.err( I18n.ERR_13102_UNSUPPORTED_OPERATION, getClass().getName()
266             .concat( "." ).concat( "isFirst()" ) ) );
267     }
268 
269 
270     /**
271      * {@inheritDoc}
272      */
273     @Override
274     public boolean isLast()
275     {
276         throw new UnsupportedOperationException( I18n.err( I18n.ERR_13102_UNSUPPORTED_OPERATION, getClass().getName()
277             .concat( "." ).concat( "isLast()" ) ) );
278     }
279 
280 
281     /**
282      * {@inheritDoc}
283      */
284     protected String getUnsupportedMessage()
285     {
286         return UNSUPPORTED_MSG;
287     }
288 
289 
290     /**
291      * @see Object#toString()
292      */
293     @Override
294     public String toString( String tabs )
295     {
296         StringBuilder sb = new StringBuilder();
297 
298         sb.append( tabs ).append( "IndexCursorAdaptor (" );
299 
300         if ( available() )
301         {
302             sb.append( "available)" );
303         }
304         else
305         {
306             sb.append( "absent)" );
307         }
308 
309         sb.append( " :\n" );
310 
311         sb.append( wrappedCursor.toString( tabs + "    " ) );
312 
313         return sb.toString();
314     }
315 
316 
317     /**
318      * @see Object#toString()
319      */
320     public String toString()
321     {
322         return toString( "" );
323     }
324 }