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  
25  import org.apache.directory.api.ldap.model.constants.Loggers;
26  import org.apache.directory.api.ldap.model.cursor.AbstractCursor;
27  import org.apache.directory.api.ldap.model.cursor.ClosureMonitor;
28  import org.apache.directory.api.ldap.model.cursor.Cursor;
29  import org.apache.directory.api.ldap.model.cursor.CursorException;
30  import org.apache.directory.api.ldap.model.entry.Entry;
31  import org.apache.directory.api.ldap.model.exception.LdapException;
32  import org.apache.directory.api.ldap.model.filter.ExprNode;
33  import org.apache.directory.server.core.api.partition.PartitionTxn;
34  import org.apache.directory.server.xdbm.IndexEntry;
35  import org.apache.directory.server.xdbm.search.Evaluator;
36  import org.apache.directory.server.xdbm.search.PartitionSearchResult;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  
41  /**
42   * Adapts index cursors to return just Entry objects.
43   *
44   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
45   */
46  public class EntryCursorAdaptor extends AbstractCursor<Entry>
47  {
48      /** A dedicated log for cursors */
49      private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() );
50  
51      /** Speedup for logs */
52      private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled();
53      
54      /** The transaction in use */
55      private PartitionTxn partitionTxn;
56  
57      private final Cursor<IndexEntry<String, String>> indexCursor;
58      private final Evaluator<? extends ExprNode> evaluator;
59  
60  
61      public EntryCursorAdaptor( PartitionTxn partitionTxn, AbstractBTreePartition db, PartitionSearchResult searchResult )
62      {
63          if ( IS_DEBUG )
64          {
65              LOG_CURSOR.debug( "Creating EntryCursorAdaptor {}", this );
66          }
67  
68          indexCursor = searchResult.getResultSet();
69          evaluator = searchResult.getEvaluator();
70          this.partitionTxn = partitionTxn;
71      }
72  
73  
74      /**
75       * {@inheritDoc}
76       */
77      public void after( Entry element ) throws LdapException, CursorException
78      {
79          throw new UnsupportedOperationException();
80      }
81  
82  
83      /**
84       * {@inheritDoc}
85       */
86      public void afterLast() throws LdapException, CursorException
87      {
88          this.indexCursor.afterLast();
89      }
90  
91  
92      /**
93       * {@inheritDoc}
94       */
95      public boolean available()
96      {
97          return indexCursor.available();
98      }
99  
100 
101     /**
102      * {@inheritDoc}
103      */
104     public void before( Entry element ) throws LdapException, CursorException
105     {
106         throw new UnsupportedOperationException();
107     }
108 
109 
110     /**
111      * {@inheritDoc}
112      */
113     public void beforeFirst() throws LdapException, CursorException
114     {
115         indexCursor.beforeFirst();
116     }
117 
118 
119     /**
120      * {@inheritDoc}
121      */
122     @Override
123     public final void setClosureMonitor( ClosureMonitor monitor )
124     {
125         indexCursor.setClosureMonitor( monitor );
126     }
127 
128 
129     /**
130      * {@inheritDoc}}
131      */
132     @Override
133     public void close() throws IOException
134     {
135         if ( IS_DEBUG )
136         {
137             LOG_CURSOR.debug( "Closing EntryCursorAdaptor {}", this );
138         }
139 
140         indexCursor.close();
141     }
142 
143 
144     /**
145      * {@inheritDoc}
146      */
147     @Override
148     public void close( Exception cause ) throws IOException
149     {
150         if ( IS_DEBUG )
151         {
152             LOG_CURSOR.debug( "Closing EntryCursorAdaptor {}", this );
153         }
154 
155         indexCursor.close( cause );
156     }
157 
158 
159     /**
160      * {@inheritDoc}
161      */
162     public boolean first() throws LdapException, CursorException
163     {
164         return indexCursor.first();
165     }
166 
167 
168     /**
169      * {@inheritDoc}
170      */
171     public Entry get() throws CursorException
172     {
173         IndexEntry<String, String> indexEntry = indexCursor.get();
174 
175         try
176         {
177             if ( evaluator.evaluate( partitionTxn, indexEntry ) )
178             {
179                 Entry entry = indexEntry.getEntry();
180                 indexEntry.setEntry( null );
181 
182                 return entry;
183             }
184             else
185             {
186                 indexEntry.setEntry( null );
187             }
188 
189             return null;
190         }
191         catch ( Exception e )
192         {
193             throw new CursorException( e.getMessage(), e );
194         }
195     }
196 
197 
198     /**
199      * {@inheritDoc}
200      */
201     @Override
202     public boolean isClosed()
203     {
204         return indexCursor.isClosed();
205     }
206 
207 
208     /**
209      * {@inheritDoc}
210      */
211     public boolean last() throws LdapException, CursorException
212     {
213         return indexCursor.last();
214     }
215 
216 
217     /**
218      * {@inheritDoc}
219      */
220     public boolean next() throws LdapException, CursorException
221     {
222         return indexCursor.next();
223     }
224 
225 
226     /**
227      * {@inheritDoc}
228      */
229     public boolean previous() throws LdapException, CursorException
230     {
231         return indexCursor.previous();
232     }
233 
234 
235     /**
236      * @see Object#toString()
237      */
238     @Override
239     public String toString( String tabs )
240     {
241         StringBuilder sb = new StringBuilder();
242 
243         sb.append( tabs ).append( "EntryCursorAdaptor\n" );
244 
245         if ( indexCursor != null )
246         {
247             sb.append( tabs ).append( "    " ).append( "IndexCursor : \n" );
248             sb.append( indexCursor.toString( tabs + "        " ) );
249         }
250 
251         if ( evaluator != null )
252         {
253             sb.append( tabs ).append( "    " ).append( "Evaluator : \n" );
254             sb.append( evaluator.toString( tabs + "        " ) );
255         }
256 
257         return sb.toString();
258     }
259 
260 
261     /**
262      * @see Object#toString()
263      */
264     public String toString()
265     {
266         return toString( "" );
267     }
268 }