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 */ 020package org.apache.directory.server.xdbm.search.cursor; 021 022 023import java.io.IOException; 024 025import org.apache.directory.api.ldap.model.constants.Loggers; 026import org.apache.directory.api.ldap.model.cursor.Cursor; 027import org.apache.directory.api.ldap.model.cursor.CursorException; 028import org.apache.directory.api.ldap.model.exception.LdapException; 029import org.apache.directory.server.core.api.partition.PartitionTxn; 030import org.apache.directory.server.core.partition.impl.btree.IndexCursorAdaptor; 031import org.apache.directory.server.xdbm.AbstractIndexCursor; 032import org.apache.directory.server.xdbm.IndexEntry; 033import org.apache.directory.server.xdbm.Store; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037 038/** 039 * A Cursor over all entries in a partition which returns IndexEntries. 040 * 041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 042 */ 043public class AllEntriesCursor extends AbstractIndexCursor<String> 044{ 045 /** A dedicated log for cursors */ 046 private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() ); 047 048 /** Speedup for logs */ 049 private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled(); 050 051 /** The index entry we use to return entries one by one. */ 052 private IndexEntry<String, String> indexEntry = new IndexEntry<>(); 053 054 /** The cursor on the MsterTable index */ 055 private final Cursor<IndexEntry<String, String>> wrapped; 056 057 058 /** 059 * {@inheritDoc} 060 */ 061 protected String getUnsupportedMessage() 062 { 063 return UNSUPPORTED_MSG; 064 } 065 066 067 /** 068 * Creates a new instance of AllEntriesCursor 069 * 070 * @param partitionTxn The transaction to use 071 * @param store The Store instance 072 * @throws LdapException If we weren't able to create an instance of AllEntriesCursor 073 */ 074 public AllEntriesCursor( PartitionTxn partitionTxn, Store store ) throws LdapException 075 { 076 if ( IS_DEBUG ) 077 { 078 LOG_CURSOR.debug( "Creating AllEntriesCursor {}", this ); 079 } 080 081 this.partitionTxn = partitionTxn; 082 083 // Uses the MasterTable 084 wrapped = new IndexCursorAdaptor( partitionTxn, store.getMasterTable().cursor(), true ); 085 } 086 087 088 /** 089 * {@inheritDoc} 090 */ 091 @Override 092 public void after( IndexEntry<String, String> indexEntry ) throws LdapException, CursorException 093 { 094 checkNotClosed(); 095 } 096 097 098 /** 099 * {@inheritDoc} 100 */ 101 public void afterLast() throws LdapException, CursorException 102 { 103 checkNotClosed(); 104 105 wrapped.afterLast(); 106 } 107 108 109 /** 110 * {@inheritDoc} 111 */ 112 @Override 113 public boolean available() 114 { 115 return wrapped.available(); 116 } 117 118 119 /** 120 * {@inheritDoc} 121 */ 122 @Override 123 public void before( IndexEntry<String, String> indexEntry ) throws LdapException, CursorException 124 { 125 checkNotClosed(); 126 } 127 128 129 /** 130 * {@inheritDoc} 131 */ 132 public void beforeFirst() throws LdapException, CursorException 133 { 134 checkNotClosed(); 135 136 wrapped.beforeFirst(); 137 } 138 139 140 /** 141 * {@inheritDoc} 142 */ 143 public boolean first() throws LdapException, CursorException 144 { 145 checkNotClosed(); 146 147 return wrapped.first(); 148 } 149 150 151 /** 152 * {@inheritDoc} 153 */ 154 public IndexEntry<String, String> get() throws CursorException 155 { 156 checkNotClosed(); 157 158 // Create the returned IndexEntry, copying what we get from the wrapped cursor 159 // As we are using the MasterTable, we have to use the key as the 160 // ID and value 161 IndexEntry<?, String> wrappedEntry = wrapped.get(); 162 indexEntry.setId( ( String ) wrappedEntry.getKey() ); 163 indexEntry.setKey( ( String ) wrappedEntry.getKey() ); 164 indexEntry.setEntry( null ); 165 166 return indexEntry; 167 } 168 169 170 /** 171 * {@inheritDoc} 172 */ 173 public boolean last() throws LdapException, CursorException 174 { 175 checkNotClosed(); 176 177 return wrapped.last(); 178 } 179 180 181 /** 182 * {@inheritDoc} 183 */ 184 @Override 185 public boolean next() throws LdapException, CursorException 186 { 187 checkNotClosed(); 188 189 return wrapped.next(); 190 } 191 192 193 /** 194 * {@inheritDoc} 195 */ 196 @Override 197 public boolean previous() throws LdapException, CursorException 198 { 199 checkNotClosed(); 200 201 return wrapped.previous(); 202 } 203 204 205 /** 206 * {@inheritDoc} 207 */ 208 @Override 209 public void close() throws IOException 210 { 211 if ( IS_DEBUG ) 212 { 213 LOG_CURSOR.debug( "Closing AllEntriesCursor {}", this ); 214 } 215 216 wrapped.close(); 217 } 218 219 220 /** 221 * {@inheritDoc} 222 */ 223 @Override 224 public void close( Exception cause ) throws IOException 225 { 226 if ( IS_DEBUG ) 227 { 228 LOG_CURSOR.debug( "Closing AllEntriesCursor {}", this ); 229 } 230 231 wrapped.close( cause ); 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( "AllEntriesCursor (" ); 244 245 if ( available() ) 246 { 247 sb.append( "available)" ); 248 } 249 else 250 { 251 sb.append( "absent)" ); 252 } 253 254 sb.append( " :\n" ); 255 256 sb.append( wrapped.toString( tabs + " " ) ); 257 258 return sb.toString(); 259 } 260 261 262 /** 263 * @see Object#toString() 264 */ 265 public String toString() 266 { 267 return toString( "" ); 268 } 269}